Skip to content

Commit 4fabc61

Browse files
authored
Merge pull request #84199 from Xazax-hun/no-reflection-anon-types
[cxx-interop] Restrict the uses of anonymous types
2 parents 30fc84c + 1cde254 commit 4fabc61

File tree

5 files changed

+44
-4
lines changed

5 files changed

+44
-4
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4555,6 +4555,10 @@ namespace {
45554555
// FIXME: Temporarily unreachable because of check above.
45564556
markAsVariant(result, *correctSwiftName);
45574557

4558+
if (decl->isAnonymousStructOrUnion())
4559+
Impl.markUnavailable(
4560+
result, "refer to the members of the anonymous type instead");
4561+
45584562
return result;
45594563
}
45604564

lib/IRGen/StructLayout.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -589,10 +589,17 @@ unsigned irgen::getNumFields(const NominalTypeDecl *target) {
589589
}
590590

591591
bool irgen::isExportableField(Field field) {
592-
if (field.getKind() == Field::Kind::Var &&
593-
field.getVarDecl()->getClangDecl() &&
594-
field.getVarDecl()->getFormalAccess() == AccessLevel::Private)
595-
return false;
592+
if (field.getKind() == Field::Kind::Var) {
593+
if (field.getVarDecl()->getClangDecl() &&
594+
field.getVarDecl()->getFormalAccess() == AccessLevel::Private)
595+
return false;
596+
// We should not be able to refer to anonymous types.
597+
if (const auto *vd = dyn_cast_or_null<clang::ValueDecl>(
598+
field.getVarDecl()->getClangDecl()))
599+
if (const auto *rd = vd->getType()->getAsRecordDecl())
600+
if (rd->isAnonymousStructOrUnion())
601+
return false;
602+
}
596603
// All other fields are exportable
597604
return true;
598605
}

test/Interop/Cxx/class/Inputs/simple-structs.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ struct HasPublicFieldsOnly {
1717
HasPublicFieldsOnly(int i1, int i2) : publ1(i1), publ2(i2) {}
1818
};
1919

20+
struct HasAnonymousType {
21+
HasAnonymousType(int a, int b, int c) : a(a), b(b), c(c) {}
22+
23+
struct {
24+
int a, b;
25+
};
26+
int c;
27+
};
28+
2029
struct HasPrivatePublicProtectedFields {
2130
private:
2231
int priv1;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %target-typecheck-verify-swift -I %S/Inputs -swift-version 6 -cxx-interoperability-mode=upcoming-swift
2+
3+
// CHECK: Foobar
4+
5+
import SimpleStructs
6+
7+
let s = HasAnonymousType(1, 2, 3)
8+
let _ = s.__Anonymous_field0 // expected-error {{'__Anonymous_field0' is unavailable: refer to the members of the anonymous type instead}}
9+
// Referring to the members of the anonymous type directly.
10+
let _ = s.a
11+
let _ = s.b
12+
let _ = s.c

test/Interop/Cxx/class/print-simple-structs.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ func printCxxStructNested() {
2424
print(s)
2525
}
2626

27+
func printCxxStructWithAnonType() {
28+
let s = HasAnonymousType(1, 2, 3)
29+
print(s)
30+
}
31+
2732
printCxxStructPrivateFields()
2833
// CHECK: HasPrivateFieldsOnly()
2934

@@ -35,3 +40,6 @@ printCxxStructPrivatePublicProtectedFields()
3540

3641
printCxxStructNested()
3742
// CHECK: Outer(publStruct: {{.*}}.HasPrivatePublicProtectedFields(publ1: 8, publ2: 12))
43+
44+
printCxxStructWithAnonType()
45+
// CHECK: HasAnonymousType(c: 3)

0 commit comments

Comments
 (0)