Skip to content

Commit ff42f2e

Browse files
author
Gabor Horvath
committed
[cxx-interop] Fix a regression making std::string unsafe
Currently, we only get warnings for using unsafe types in expressions but not in the function signature. The tests did not use the std::string object in the function body. As a result, we regressed and std::string was considered unsafe. The reason is that the annotation only mode for calculating escapability of a type did not do what we intended. std::basic_string is conditionally escapable if the template argument is escapable. We considered 'char' to have unknown escapability in annotation only mode. The annotation only mode was introduced to avoid suddenly importing certain types as not escapable when they have pointer fields and break backward compatibility. The solution is to make annotation only mode to still consider char and co as escapable types and only fall back to unknown when the inference otherwise would have deduced non-escapable (for unannotated typed).
1 parent c89cb49 commit ff42f2e

File tree

3 files changed

+11
-4
lines changed

3 files changed

+11
-4
lines changed

Diff for: include/swift/ClangImporter/ClangImporterRequests.h

+3
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,9 @@ enum class CxxEscapability { Escapable, NonEscapable, Unknown };
537537
struct EscapabilityLookupDescriptor final {
538538
const clang::Type *type;
539539
ClangImporter::Implementation *impl;
540+
// Only explicitly ~Escapable annotated types are considered ~Escapable.
541+
// This is for backward compatibility, so we continue to import aggregates
542+
// containing pointers as Escapable types.
540543
bool annotationOnly = true;
541544

542545
friend llvm::hash_code hash_value(const EscapabilityLookupDescriptor &desc) {

Diff for: lib/ClangImporter/ClangImporter.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#include "swift/Strings.h"
5656
#include "swift/Subsystems.h"
5757
#include "clang/AST/ASTContext.h"
58+
#include "clang/AST/Decl.h"
5859
#include "clang/AST/DeclBase.h"
5960
#include "clang/AST/DeclCXX.h"
6061
#include "clang/AST/DeclTemplate.h"
@@ -5348,8 +5349,6 @@ ClangTypeEscapability::evaluate(Evaluator &evaluator,
53485349
return hadUnknown ? CxxEscapability::Unknown : CxxEscapability::Escapable;
53495350
}
53505351
}
5351-
if (desc.annotationOnly)
5352-
return CxxEscapability::Unknown;
53535352
if (desugared->isArrayType()) {
53545353
auto elemTy = cast<clang::ArrayType>(desugared)
53555354
->getElementType()
@@ -5363,7 +5362,8 @@ ClangTypeEscapability::evaluate(Evaluator &evaluator,
53635362
// Base cases
53645363
if (desugared->isAnyPointerType() || desugared->isBlockPointerType() ||
53655364
desugared->isMemberPointerType() || desugared->isReferenceType())
5366-
return CxxEscapability::NonEscapable;
5365+
return desc.annotationOnly ? CxxEscapability::Unknown
5366+
: CxxEscapability::NonEscapable;
53675367
if (desugared->isScalarType())
53685368
return CxxEscapability::Escapable;
53695369
return CxxEscapability::Unknown;
@@ -8508,7 +8508,7 @@ ExplicitSafety ClangDeclExplicitSafety::evaluate(
85088508
// Enums are always safe.
85098509
if (isa<clang::EnumDecl>(decl))
85108510
return ExplicitSafety::Safe;
8511-
8511+
85128512
// If it's not a record, leave it unspecified.
85138513
auto recordDecl = dyn_cast<clang::RecordDecl>(decl);
85148514
if (!recordDecl)

Diff for: test/Interop/Cxx/class/safe-interop-mode.swift

+4
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,11 @@ func useSafeParams(x: Owner, y: View, z: SafeEscapableAggregate, c: MyContainer)
9191
}
9292

9393
func useCfType(x: CFArray) {
94+
_ = x
9495
}
9596

9697
func useString(x: std.string) {
98+
_ = x
9799
}
98100

99101
func useVecOfPtr(x: VecOfPtr) {
@@ -102,9 +104,11 @@ func useVecOfPtr(x: VecOfPtr) {
102104
}
103105

104106
func useVecOfInt(x: VecOfInt) {
107+
_ = x
105108
}
106109

107110
func useSafeTuple(x: SafeTuple) {
111+
_ = x
108112
}
109113

110114
func useUnsafeTuple(x: UnsafeTuple) {

0 commit comments

Comments
 (0)