Skip to content

Commit 609fe2c

Browse files
authored
[ObjC] Fix offsets following [[no_unique_address]] for @encode() (#71321)
Commit 46ca880 made `@encode` skip fields that are made zero-sized by `[[no_unique_address]]`. When iterating the fields, the index which is passed to `getFieldOffset` failed to be incremented for those due to the use of an early `continue`, so subsequent fields reported an incorrect offset. This caused an assertion to be triggered in `getObjCEncodingForStructureImpl`. Fixes #71250
1 parent 1ad920f commit 609fe2c

File tree

2 files changed

+15
-3
lines changed

2 files changed

+15
-3
lines changed

clang/lib/AST/ASTContext.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8541,14 +8541,12 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
85418541
}
85428542
}
85438543

8544-
unsigned i = 0;
85458544
for (FieldDecl *Field : RDecl->fields()) {
85468545
if (!Field->isZeroLengthBitField(*this) && Field->isZeroSize(*this))
85478546
continue;
8548-
uint64_t offs = layout.getFieldOffset(i);
8547+
uint64_t offs = layout.getFieldOffset(Field->getFieldIndex());
85498548
FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),
85508549
std::make_pair(offs, Field));
8551-
++i;
85528550
}
85538551

85548552
if (CXXRec && includeVBases) {

clang/test/CodeGenObjCXX/encode.mm

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,3 +339,17 @@ @implementation N
339339
const char *inner0 = @encode(Outer0<int>::Inner0 *);
340340
const char *inner1 = @encode(Outer0<int>::Inner1<float> *);
341341
}
342+
343+
#if __cplusplus >= 202002L
344+
namespace GH71250 {
345+
struct Empty {};
346+
struct S {
347+
[[no_unique_address]] Empty a;
348+
long b;
349+
long c;
350+
};
351+
352+
// CHECKCXX20: @_ZN7GH712501sE = constant [7 x i8] c"{S=qq}\00", align 1
353+
extern const char s[] = @encode(S);
354+
}
355+
#endif

0 commit comments

Comments
 (0)