Skip to content

Commit 4be78c2

Browse files
committed
[cxx-interop] Prevent Swift from importing fields marked with [[no_unique_address]]
1 parent 7418b25 commit 4be78c2

File tree

6 files changed

+47
-4
lines changed

6 files changed

+47
-4
lines changed

include/swift/AST/DiagnosticsClangImporter.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,5 +373,8 @@ NOTE(ptr_to_nonescapable,none,
373373
"pointer to non-escapable type %0 cannot be imported",
374374
(const clang::Type*))
375375

376+
WARNING(unsupported_attribute, none, "Swift doesn't support fields marked with %0",
377+
(StringRef))
378+
376379
#define UNDEFINE_DIAGNOSTIC_MACROS
377380
#include "DefineDiagnosticMacros.h"

lib/ClangImporter/ImportDecl.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4383,6 +4383,16 @@ namespace {
43834383
std::optional<ImportedName> correctSwiftName;
43844384
ImportedName importedName;
43854385

4386+
if (decl->hasAttr<clang::NoUniqueAddressAttr>()) {
4387+
// TODO: rdar://148437848 Swift doesn't support fields marked with [[no_unique_address]]
4388+
4389+
Impl.addImportDiagnostic(
4390+
decl,
4391+
Diagnostic(diag::unsupported_attribute, "[[no_unique_address]]"),
4392+
decl->getLocation());
4393+
return nullptr;
4394+
}
4395+
43864396
std::tie(importedName, correctSwiftName) = importFullName(decl);
43874397
if (!importedName) {
43884398
return nullptr;

test/Interop/Cxx/class/Inputs/member-variables.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ struct Empty {
1111
int getNum() const { return 42; }
1212
};
1313

14+
struct HasNoUniqueAddressField {
15+
MyClass simpleField;
16+
[[no_unique_address]] MyClass noUniqueAddressField; // expected-warning {{Swift doesn't support fields marked with [[no_unique_address]]}}
17+
};
18+
1419
struct HasZeroSizedField {
1520
int a;
1621
[[no_unique_address]] Empty b;
Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1-
// RUN: %target-typecheck-verify-swift -I %S/Inputs -enable-experimental-cxx-interop
1+
// RUN: %target-typecheck-verify-swift -I %S/Inputs -enable-experimental-cxx-interop -verify-additional-file %S/Inputs/member-variables.h
22

33
import MemberVariables
4+
import CxxStdlib
45

5-
var s = MyClass()
6-
s.const_member = 42 // expected-error {{cannot assign to property: 'const_member' setter is inaccessible}}
6+
var s1 = MyClass()
7+
s1.const_member = 42 // expected-error {{cannot assign to property: 'const_member' setter is inaccessible}}
8+
9+
// TODO: rdar://148437848 Swift doesn't support fields marked with [[no_unique_address]]
10+
var s2 = HasNoUniqueAddressField()
11+
_ = s2.simpleField.const_member
12+
_ = s2.noUniqueAddressField.const_member // expected-error {{value of type 'HasNoUniqueAddressField' has no member 'noUniqueAddressField'}}

test/Interop/Cxx/class/zero-sized-field.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ FieldsTestSuite.test("Zero sized field") {
2121
expectEqual(s2.c, 7)
2222
expectEqual(s2.c, s2.get_c())
2323
expectEqual(takesZeroSizedInCpp(s2), 5)
24-
expectEqual(s.b.getNum(), 42)
24+
// TODO: rdar://148437848 Swift doesn't support fields marked with [[no_unique_address]]
25+
// expectEqual(s.b.getNum(), 42)
2526
}
2627

2728
runAllTests()
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift %s -o %t/print-std-string.out -Xfrontend -enable-experimental-cxx-interop
3+
// RUN: %target-codesign %t/print-std-string.out
4+
// RUN: %target-run %t/print-std-string.out | %FileCheck %s
5+
6+
// REQUIRES: executable_test
7+
8+
import CxxStdlib
9+
10+
func printString(s: std.string) {
11+
print(s)
12+
let swiftString = String(s)
13+
print(swiftString)
14+
}
15+
16+
printString(s: "Hello")
17+
// CHECK: basic_string<CChar, std.__1.char_traits<CChar>, std.__1.allocator<CChar>>()
18+
// CHECK: Hello

0 commit comments

Comments
 (0)