Skip to content

Commit 758e67f

Browse files
authored
Merge pull request #85296 from j-hui/revert-template-arg-import
[cxx-interop] Revert changes to template argument import/safety check
2 parents b1c2bc1 + ae93474 commit 758e67f

File tree

6 files changed

+66
-229
lines changed

6 files changed

+66
-229
lines changed

include/swift/ClangImporter/ClangImporterRequests.h

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -624,53 +624,6 @@ class CxxValueSemantics
624624
void simple_display(llvm::raw_ostream &out, CxxValueSemanticsDescriptor desc);
625625
SourceLoc extractNearestSourceLoc(CxxValueSemanticsDescriptor desc);
626626

627-
struct ClangTypeExplicitSafetyDescriptor final {
628-
clang::CanQualType type;
629-
630-
ClangTypeExplicitSafetyDescriptor(clang::CanQualType type) : type(type) {}
631-
ClangTypeExplicitSafetyDescriptor(clang::QualType type)
632-
: type(type->getCanonicalTypeUnqualified()) {}
633-
634-
friend llvm::hash_code
635-
hash_value(const ClangTypeExplicitSafetyDescriptor &desc) {
636-
return llvm::hash_combine(desc.type.getTypePtrOrNull());
637-
}
638-
639-
friend bool operator==(const ClangTypeExplicitSafetyDescriptor &lhs,
640-
const ClangTypeExplicitSafetyDescriptor &rhs) {
641-
return lhs.type == rhs.type;
642-
}
643-
644-
friend bool operator!=(const ClangTypeExplicitSafetyDescriptor &lhs,
645-
const ClangTypeExplicitSafetyDescriptor &rhs) {
646-
return !(lhs == rhs);
647-
}
648-
};
649-
650-
void simple_display(llvm::raw_ostream &out,
651-
ClangTypeExplicitSafetyDescriptor desc);
652-
SourceLoc extractNearestSourceLoc(ClangTypeExplicitSafetyDescriptor desc);
653-
654-
/// Determine the safety of the given Clang declaration.
655-
class ClangTypeExplicitSafety
656-
: public SimpleRequest<ClangTypeExplicitSafety,
657-
ExplicitSafety(ClangTypeExplicitSafetyDescriptor),
658-
RequestFlags::Cached> {
659-
public:
660-
using SimpleRequest::SimpleRequest;
661-
662-
// Source location
663-
SourceLoc getNearestLoc() const { return SourceLoc(); };
664-
bool isCached() const { return true; }
665-
666-
private:
667-
friend SimpleRequest;
668-
669-
// Evaluation.
670-
ExplicitSafety evaluate(Evaluator &evaluator,
671-
ClangTypeExplicitSafetyDescriptor desc) const;
672-
};
673-
674627
struct CxxDeclExplicitSafetyDescriptor final {
675628
const clang::Decl *decl;
676629
bool isClass;

include/swift/ClangImporter/ClangImporterTypeIDZone.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,6 @@ SWIFT_REQUEST(ClangImporter, ClangTypeEscapability,
4848
SWIFT_REQUEST(ClangImporter, CxxValueSemantics,
4949
CxxValueSemanticsKind(CxxValueSemanticsDescriptor), Cached,
5050
NoLocationInfo)
51-
SWIFT_REQUEST(ClangImporter, ClangTypeExplicitSafety,
52-
ExplicitSafety(ClangTypeExplicitSafetyDescriptor), Cached,
53-
NoLocationInfo)
5451
SWIFT_REQUEST(ClangImporter, ClangDeclExplicitSafety,
5552
ExplicitSafety(CxxDeclExplicitSafetyDescriptor), Cached,
5653
NoLocationInfo)

lib/ClangImporter/ClangImporter.cpp

Lines changed: 38 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -8723,56 +8723,6 @@ SourceLoc swift::extractNearestSourceLoc(SafeUseOfCxxDeclDescriptor desc) {
87238723
return SourceLoc();
87248724
}
87258725

8726-
void swift::simple_display(llvm::raw_ostream &out,
8727-
ClangTypeExplicitSafetyDescriptor desc) {
8728-
auto qt = static_cast<clang::QualType>(desc.type);
8729-
out << "Checking if type '" << qt.getAsString() << "' is explicitly safe.\n";
8730-
}
8731-
8732-
SourceLoc swift::extractNearestSourceLoc(ClangTypeExplicitSafetyDescriptor desc) {
8733-
return SourceLoc();
8734-
}
8735-
8736-
ExplicitSafety ClangTypeExplicitSafety::evaluate(
8737-
Evaluator &evaluator, ClangTypeExplicitSafetyDescriptor desc) const {
8738-
auto clangType = static_cast<clang::QualType>(desc.type);
8739-
8740-
// Handle pointers.
8741-
auto pointeeType = clangType->getPointeeType();
8742-
if (!pointeeType.isNull()) {
8743-
// Function pointers are okay.
8744-
if (pointeeType->isFunctionType())
8745-
return ExplicitSafety::Safe;
8746-
8747-
// Pointers to record types are okay if they come in as foreign reference
8748-
// types.
8749-
if (auto *recordDecl = pointeeType->getAsRecordDecl()) {
8750-
if (hasImportAsRefAttr(recordDecl))
8751-
return ExplicitSafety::Safe;
8752-
}
8753-
8754-
// All other pointers are considered unsafe.
8755-
return ExplicitSafety::Unsafe;
8756-
}
8757-
8758-
// Handle records recursively.
8759-
if (auto recordDecl = clangType->getAsTagDecl()) {
8760-
// If we reached this point the types is not imported as a shared reference,
8761-
// so we don't need to check the bases whether they are shared references.
8762-
auto req = ClangDeclExplicitSafety({recordDecl, false});
8763-
if (evaluator.hasActiveRequest(req))
8764-
// Cycles are allowed in templates, e.g.:
8765-
// template <typename> class Foo { ... }; // throws away template arg
8766-
// template <typename T> class Bar : Foo<Bar<T>> { ... };
8767-
// We need to avoid them here.
8768-
return ExplicitSafety::Unspecified;
8769-
return evaluateOrDefault(evaluator, req, ExplicitSafety::Unspecified);
8770-
}
8771-
8772-
// Everything else is safe.
8773-
return ExplicitSafety::Safe;
8774-
}
8775-
87768726
void swift::simple_display(llvm::raw_ostream &out,
87778727
CxxDeclExplicitSafetyDescriptor desc) {
87788728
out << "Checking if '";
@@ -8844,13 +8794,43 @@ CustomRefCountingOperationResult CustomRefCountingOperation::evaluate(
88448794

88458795
/// Check whether the given Clang type involves an unsafe type.
88468796
static bool hasUnsafeType(Evaluator &evaluator, clang::QualType clangType) {
8847-
auto req = ClangTypeExplicitSafety({clangType});
8848-
if (evaluator.hasActiveRequest(req))
8849-
// If there is a cycle in a type, assume ExplicitSafety is Unspecified,
8850-
// i.e., not unsafe:
8851-
return false;
8852-
return evaluateOrDefault(evaluator, req, ExplicitSafety::Unspecified) ==
8853-
ExplicitSafety::Unsafe;
8797+
// Handle pointers.
8798+
auto pointeeType = clangType->getPointeeType();
8799+
if (!pointeeType.isNull()) {
8800+
// Function pointers are okay.
8801+
if (pointeeType->isFunctionType())
8802+
return false;
8803+
8804+
// Pointers to record types are okay if they come in as foreign reference
8805+
// types.
8806+
if (auto recordDecl = pointeeType->getAsRecordDecl()) {
8807+
if (hasImportAsRefAttr(recordDecl))
8808+
return false;
8809+
}
8810+
8811+
// All other pointers are considered unsafe.
8812+
return true;
8813+
}
8814+
8815+
// Handle records recursively.
8816+
if (auto recordDecl = clangType->getAsTagDecl()) {
8817+
// If we reached this point the types is not imported as a shared reference,
8818+
// so we don't need to check the bases whether they are shared references.
8819+
auto safety = evaluateOrDefault(
8820+
evaluator, ClangDeclExplicitSafety({recordDecl, false}),
8821+
ExplicitSafety::Unspecified);
8822+
switch (safety) {
8823+
case ExplicitSafety::Unsafe:
8824+
return true;
8825+
8826+
case ExplicitSafety::Safe:
8827+
case ExplicitSafety::Unspecified:
8828+
return false;
8829+
}
8830+
}
8831+
8832+
// Everything else is safe.
8833+
return false;
88548834
}
88558835

88568836
ExplicitSafety
@@ -8888,29 +8868,6 @@ ClangDeclExplicitSafety::evaluate(Evaluator &evaluator,
88888868
ClangTypeEscapability({recordDecl->getTypeForDecl(), nullptr}),
88898869
CxxEscapability::Unknown) != CxxEscapability::Unknown)
88908870
return ExplicitSafety::Safe;
8891-
8892-
// A template class is unsafe if any of its type arguments are unsafe.
8893-
// Note that this does not rely on the record being defined.
8894-
if (const auto *ctsd =
8895-
dyn_cast<clang::ClassTemplateSpecializationDecl>(recordDecl)) {
8896-
for (auto arg : ctsd->getTemplateArgs().asArray()) {
8897-
switch (arg.getKind()) {
8898-
case clang::TemplateArgument::Type:
8899-
if (hasUnsafeType(evaluator, arg.getAsType()))
8900-
return ExplicitSafety::Unsafe;
8901-
break;
8902-
case clang::TemplateArgument::Pack:
8903-
for (auto pkArg : arg.getPackAsArray()) {
8904-
if (pkArg.getKind() == clang::TemplateArgument::Type &&
8905-
hasUnsafeType(evaluator, pkArg.getAsType()))
8906-
return ExplicitSafety::Unsafe;
8907-
}
8908-
break;
8909-
default:
8910-
continue;
8911-
}
8912-
}
8913-
}
89148871

89158872
// If we don't have a definition, leave it unspecified.
89168873
recordDecl = recordDecl->getDefinition();
@@ -8924,7 +8881,7 @@ ClangDeclExplicitSafety::evaluate(Evaluator &evaluator,
89248881
return ExplicitSafety::Unsafe;
89258882
}
89268883
}
8927-
8884+
89288885
// Check the fields.
89298886
for (auto field : recordDecl->fields()) {
89308887
if (hasUnsafeType(evaluator, field->getType()))

lib/ClangImporter/ImportDecl.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@
6969
#include "clang/AST/RecordLayout.h"
7070
#include "clang/AST/RecursiveASTVisitor.h"
7171
#include "clang/AST/StmtVisitor.h"
72-
#include "clang/AST/TemplateBase.h"
7372
#include "clang/AST/Type.h"
7473
#include "clang/Basic/Specifiers.h"
7574
#include "clang/Basic/TargetInfo.h"
@@ -2302,6 +2301,34 @@ namespace {
23022301
}
23032302
}
23042303

2304+
// We have to do this after populating ImportedDecls to avoid importing
2305+
// the same decl multiple times. Also after we imported the bases.
2306+
if (const auto *ctsd =
2307+
dyn_cast<clang::ClassTemplateSpecializationDecl>(decl)) {
2308+
for (auto arg : ctsd->getTemplateArgs().asArray()) {
2309+
llvm::SmallVector<clang::TemplateArgument, 1> nonPackArgs;
2310+
if (arg.getKind() == clang::TemplateArgument::Pack) {
2311+
auto pack = arg.getPackAsArray();
2312+
nonPackArgs.assign(pack.begin(), pack.end());
2313+
} else {
2314+
nonPackArgs.push_back(arg);
2315+
}
2316+
for (auto realArg : nonPackArgs) {
2317+
if (realArg.getKind() != clang::TemplateArgument::Type)
2318+
continue;
2319+
auto SwiftType = Impl.importTypeIgnoreIUO(
2320+
realArg.getAsType(), ImportTypeKind::Abstract,
2321+
[](Diagnostic &&diag) {}, false, Bridgeability::None,
2322+
ImportTypeAttrs());
2323+
if (SwiftType && SwiftType->isUnsafe()) {
2324+
auto attr = new (Impl.SwiftContext) UnsafeAttr(/*implicit=*/true);
2325+
result->getAttrs().add(attr);
2326+
break;
2327+
}
2328+
}
2329+
}
2330+
}
2331+
23052332
bool isNonEscapable = false;
23062333
if (evaluateOrDefault(
23072334
Impl.SwiftContext.evaluator,

test/Interop/Cxx/class/safe-interop-mode.swift

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -83,27 +83,6 @@ struct OwnedData {
8383
void takeSharedObject(SharedObject *) const;
8484
};
8585

86-
// A class template that throws away its type argument.
87-
//
88-
// If this template is instantiated with an unsafe type, it should be considered
89-
// unsafe even if that type is never used.
90-
template <typename> struct TTake {};
91-
92-
using TTakeInt = TTake<int>;
93-
using TTakePtr = TTake<int *>;
94-
using TTakeSafeTuple = TTake<SafeTuple>;
95-
using TTakeUnsafeTuple = TTake<UnsafeTuple>;
96-
97-
// An escapability or explicit safety annotation means a type is considered safe
98-
// even if it would otherwise be considered unsafe.
99-
template <typename> struct SWIFT_ESCAPABLE TEscape {};
100-
template <typename> struct __attribute__((swift_attr("safe"))) TSafe { void *ptr; };
101-
102-
using TEscapePtr = TEscape<int *>;
103-
using TEscapeUnsafeTuple = TEscape<UnsafeTuple>;
104-
using TSafePtr = TSafe<int *>;
105-
using TSafeTuple = TSafe<UnsafeTuple>;
106-
10786
struct HoldsShared {
10887
SharedObject* obj;
10988

@@ -205,26 +184,3 @@ func useSharedReference(frt: DerivedFromSharedObject, h: HoldsShared) {
205184
let _ = frt
206185
let _ = h.getObj()
207186
}
208-
209-
func useTTakeInt(x: TTakeInt) {
210-
_ = x
211-
}
212-
213-
func useTTakePtr(x: TTakePtr) {
214-
// expected-warning@+1{{expression uses unsafe constructs but is not marked with 'unsafe'}}
215-
_ = x // expected-note{{reference to parameter 'x' involves unsafe type}}
216-
}
217-
218-
func useTTakeSafeTuple(x: TTakeSafeTuple) {
219-
_ = x
220-
}
221-
222-
func useTTakeUnsafeTuple(x: TTakeUnsafeTuple) {
223-
// expected-warning@+1{{expression uses unsafe constructs but is not marked with 'unsafe'}}
224-
_ = x // expected-note{{reference to parameter 'x' involves unsafe type}}
225-
}
226-
227-
func useTEscapePtr(x: TEscapePtr) { _ = x }
228-
func useTEscapeUnsafeTuple(x: TEscapeUnsafeTuple) { _ = x }
229-
func useTSafePtr(x: TSafePtr) { _ = x }
230-
func useTSafeTuple(x: TSafeTuple) { _ = x }

test/Interop/Cxx/templates/sfinae-template-type-arguments.swift

Lines changed: 0 additions & 53 deletions
This file was deleted.

0 commit comments

Comments
 (0)