Skip to content

Commit 689c2a5

Browse files
committed
[ClangImporter] Fix (lack of) name importing for ObjC ivars
When #39664 moved the logic for generating anonymous fields' names from ImportDecl to ImportName, it inadvertently replaced a check that the decl was *precisely* `clang::FieldDecl` with a check that it was `FieldDecl` *or a subclass*. This could cause a crash when it tried to call `FieldDecl::getFieldIndex()`, which doesn't work properly on instance variables even though `ObjCIvarDecl` is a subclass of `FieldDecl`. The easiest way to reproduce this is to use a bit field in a class's instance variables, since clang inserts an anonymous instance variable after it for padding. This commit adds a test of a bit field instance variable and fixes the bug. It also adds a PrettyStackTrace frame in the Swift lookup table preparation code, which should make other bugs like this easier to diagnose. Fixes rdar://85173321.
1 parent a24d74b commit 689c2a5

File tree

3 files changed

+15
-1
lines changed

3 files changed

+15
-1
lines changed

lib/ClangImporter/ImportName.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1672,6 +1672,12 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
16721672

16731673
// Spcial case: unnamed/anonymous fields.
16741674
if (auto field = dyn_cast<clang::FieldDecl>(D)) {
1675+
static_assert((clang::Decl::lastField - clang::Decl::firstField) == 2,
1676+
"update logic for new FieldDecl subclasses");
1677+
if (isa<clang::ObjCIvarDecl>(D) || isa<clang::ObjCAtDefsFieldDecl>(D))
1678+
// These are not ordinary fields and are not imported into Swift.
1679+
return result;
1680+
16751681
if (field->isAnonymousStructOrUnion() || field->getDeclName().isEmpty()) {
16761682
// Generate a field name for anonymous fields, this will be used in
16771683
// order to be able to expose the indirect fields injected from there

lib/ClangImporter/SwiftLookupTable.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1860,6 +1860,11 @@ SwiftNameLookupExtension::hashExtension(llvm::hash_code code) const {
18601860
void importer::addEntryToLookupTable(SwiftLookupTable &table,
18611861
clang::NamedDecl *named,
18621862
NameImporter &nameImporter) {
1863+
clang::PrettyStackTraceDecl trace(
1864+
named, named->getLocation(),
1865+
nameImporter.getClangContext().getSourceManager(),
1866+
"while adding SwiftName lookup table entries for clang declaration");
1867+
18631868
// Determine whether this declaration is suppressed in Swift.
18641869
if (shouldSuppressDeclImport(named))
18651870
return;

test/ClangImporter/Inputs/sdk-bridging-header.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
@class NSArray;
44

5-
@interface MyPredicate : NSObject
5+
@interface MyPredicate : NSObject {
6+
int kind : 2; // Should not cause crash in PCH processing (rdar://85173321)
7+
}
8+
69
+ (nonnull MyPredicate *)truePredicate;
710
+ (nonnull MyPredicate *)not;
811
+ (nonnull MyPredicate *)and:(nonnull NSArray *)subpredicates;

0 commit comments

Comments
 (0)