Skip to content

Commit 3b412ae

Browse files
authored
Merge pull request #79697 from swiftlang/gaborh/do-not-import-nonesc-pointees
[cxx-importer] Do not import pointers to non-escapable types
2 parents 0d8e005 + d0c1677 commit 3b412ae

File tree

5 files changed

+62
-5
lines changed

5 files changed

+62
-5
lines changed

include/swift/AST/DiagnosticEngine.h

+13-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939

4040
namespace clang {
4141
class NamedDecl;
42+
class Type;
4243
}
4344

4445
namespace swift {
@@ -150,7 +151,8 @@ namespace swift {
150151
ActorIsolation,
151152
IsolationSource,
152153
Diagnostic,
153-
ClangDecl
154+
ClangDecl,
155+
ClangType,
154156
};
155157

156158
namespace diag {
@@ -188,6 +190,7 @@ namespace swift {
188190
IsolationSource IsolationSourceVal;
189191
DiagnosticInfo *DiagnosticVal;
190192
const clang::NamedDecl *ClangDecl;
193+
const clang::Type *ClangType;
191194
};
192195

193196
public:
@@ -311,6 +314,9 @@ namespace swift {
311314
DiagnosticArgument(const clang::NamedDecl *ND)
312315
: Kind(DiagnosticArgumentKind::ClangDecl), ClangDecl(ND) {}
313316

317+
DiagnosticArgument(const clang::Type *Ty)
318+
: Kind(DiagnosticArgumentKind::ClangType), ClangType(Ty) {}
319+
314320
/// Initializes a diagnostic argument using the underlying type of the
315321
/// given enum.
316322
template<
@@ -441,6 +447,11 @@ namespace swift {
441447
assert(Kind == DiagnosticArgumentKind::ClangDecl);
442448
return ClangDecl;
443449
}
450+
451+
const clang::Type *getAsClangType() const {
452+
assert(Kind == DiagnosticArgumentKind::ClangType);
453+
return ClangType;
454+
}
444455
};
445456

446457
/// Describes the current behavior to take with a diagnostic.
@@ -1796,6 +1807,7 @@ namespace swift {
17961807
}
17971808

17981809
void printClangDeclName(const clang::NamedDecl *ND, llvm::raw_ostream &os);
1810+
void printClangTypeName(const clang::Type *Ty, llvm::raw_ostream &os);
17991811

18001812
/// Temporary on-stack storage and unescaping for encoded diagnostic
18011813
/// messages.

include/swift/AST/DiagnosticsClangImporter.def

+4
Original file line numberDiff line numberDiff line change
@@ -365,5 +365,9 @@ NOTE(bridged_pointer_type_not_found,none,
365365
"for bridging; module 'Swift' may be broken",
366366
(unsigned))
367367

368+
NOTE(ptr_to_nonescapable,none,
369+
"pointer to non-escapable type %0 cannot be imported",
370+
(const clang::Type*))
371+
368372
#define UNDEFINE_DIAGNOSTIC_MACROS
369373
#include "DefineDiagnosticMacros.h"

lib/AST/DiagnosticEngine.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
#include "swift/Parse/Lexer.h" // bad dependency
4040
#include "clang/AST/ASTContext.h"
4141
#include "clang/AST/Decl.h"
42+
#include "clang/AST/PrettyPrinter.h"
43+
#include "clang/AST/Type.h"
4244
#include "llvm/ADT/SmallString.h"
4345
#include "llvm/ADT/Twine.h"
4446
#include "llvm/Support/CommandLine.h"
@@ -752,6 +754,11 @@ void swift::printClangDeclName(const clang::NamedDecl *ND,
752754
ND->getNameForDiagnostic(os, ND->getASTContext().getPrintingPolicy(), false);
753755
}
754756

757+
void swift::printClangTypeName(const clang::Type *Ty, llvm::raw_ostream &os) {
758+
clang::QualType::print(Ty, clang::Qualifiers(), os,
759+
clang::PrintingPolicy{clang::LangOptions()}, "");
760+
}
761+
755762
/// Format a single diagnostic argument and write it to the given
756763
/// stream.
757764
static void formatDiagnosticArgument(StringRef Modifier,
@@ -1094,6 +1101,13 @@ static void formatDiagnosticArgument(StringRef Modifier,
10941101
printClangDeclName(Arg.getAsClangDecl(), Out);
10951102
Out << FormatOpts.ClosingQuotationMark;
10961103
break;
1104+
1105+
case DiagnosticArgumentKind::ClangType:
1106+
assert(Modifier.empty() && "Improper modifier for ClangDecl argument");
1107+
Out << FormatOpts.OpeningQuotationMark;
1108+
printClangTypeName(Arg.getAsClangType(), Out);
1109+
Out << FormatOpts.ClosingQuotationMark;
1110+
break;
10971111
}
10981112
}
10991113

lib/ClangImporter/ImportType.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,17 @@ namespace {
480480
if (pointeeQualType->isDependentType())
481481
return Type();
482482

483+
// FIXME: remove workaround once Unsafe*Pointer supports
484+
// nonescapable pointees.
485+
if (evaluateOrDefault(
486+
Impl.SwiftContext.evaluator,
487+
ClangTypeEscapability({pointeeQualType.getTypePtr(), nullptr}),
488+
CxxEscapability::Unknown) == CxxEscapability::NonEscapable) {
489+
addImportDiagnostic(Diagnostic(diag::ptr_to_nonescapable,
490+
pointeeQualType.getTypePtr()));
491+
return Type();
492+
}
493+
483494
// All other C pointers to concrete types map to
484495
// UnsafeMutablePointer<T> or OpaquePointer.
485496

test/Interop/Cxx/class/nonescapable-errors.swift

+20-4
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ using OwnerVector = std::vector<Owner>;
9191
ViewVector l1();
9292
OwnerVector l2();
9393

94+
const View* usedToCrash(const View* p) {
95+
return p;
96+
}
97+
9498
//--- test.swift
9599
import Test
96100
import CxxStdlib
@@ -139,11 +143,23 @@ public func noAnnotations() -> View {
139143
// CHECK: nonescapable.h:77:12: error: cannot infer lifetime dependence, no parameters found that are either ~Escapable or Escapable with a borrowing ownership
140144
// CHECK-NO-LIFETIMES: nonescapable.h:77:12: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
141145
l2();
142-
// CHECK-NOT: error
143-
// CHECK-NOT: warning
144146
return View()
145147
// CHECK-NO-LIFETIMES: nonescapable.h:5:5: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
146148
// CHECK-NO-LIFETIMES: nonescapable.h:6:5: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
147-
// CHECK-NO-LIFETIMES-NOT: error
148-
// CHECK-NO-LIFETIMES-NOT: warning
149149
}
150+
151+
public func test3(_ x: inout View) {
152+
usedToCrash(&x)
153+
// CHECK: error: cannot find 'usedToCrash' in scope
154+
// CHECK: note: function 'usedToCrash' unavailable (cannot import)
155+
// CHECK: note: return type unavailable (cannot import)
156+
// CHECK: pointer to non-escapable type 'View' cannot be imported
157+
// CHECK-NO-LIFETIMES: error: cannot find 'usedToCrash' in scope
158+
// CHECK-NO-LIFETIMES: note: function 'usedToCrash' unavailable (cannot import)
159+
// CHECK-NO-LIFETIMES: note: return type unavailable (cannot import)
160+
// CHECK-NO-LIFETIMES: pointer to non-escapable type 'View' cannot be imported
161+
}
162+
// CHECK-NOT: error
163+
// CHECK-NOT: warning
164+
// CHECK-NO-LIFETIMES-NOT: error
165+
// CHECK-NO-LIFETIMES-NOT: warning

0 commit comments

Comments
 (0)