Skip to content

Commit 712d7db

Browse files
authored
[Clang] Improve testing for the flexible array member (#89462)
Testing for the name of the flexible array member isn't as robust as testing the FieldDecl pointers.
1 parent fc538b0 commit 712d7db

File tree

2 files changed

+20
-15
lines changed

2 files changed

+20
-15
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -822,8 +822,9 @@ CodeGenFunction::evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type,
822822
return ConstantInt::get(ResType, ObjectSize, /*isSigned=*/true);
823823
}
824824

825-
const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberField(
826-
ASTContext &Ctx, const RecordDecl *RD, StringRef Name, uint64_t &Offset) {
825+
const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberFieldAndOffset(
826+
ASTContext &Ctx, const RecordDecl *RD, const FieldDecl *FAMDecl,
827+
uint64_t &Offset) {
827828
const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel =
828829
getLangOpts().getStrictFlexArraysLevel();
829830
uint32_t FieldNo = 0;
@@ -832,7 +833,7 @@ const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberField(
832833
return nullptr;
833834

834835
for (const FieldDecl *FD : RD->fields()) {
835-
if ((Name.empty() || FD->getNameAsString() == Name) &&
836+
if ((!FAMDecl || FD == FAMDecl) &&
836837
Decl::isFlexibleArrayMemberLike(
837838
Ctx, FD, FD->getType(), StrictFlexArraysLevel,
838839
/*IgnoreTemplateOrMacroSubstitution=*/true)) {
@@ -843,8 +844,8 @@ const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberField(
843844

844845
QualType Ty = FD->getType();
845846
if (Ty->isRecordType()) {
846-
if (const FieldDecl *Field = FindFlexibleArrayMemberField(
847-
Ctx, Ty->getAsRecordDecl(), Name, Offset)) {
847+
if (const FieldDecl *Field = FindFlexibleArrayMemberFieldAndOffset(
848+
Ctx, Ty->getAsRecordDecl(), FAMDecl, Offset)) {
848849
const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
849850
Offset += Layout.getFieldOffset(FieldNo);
850851
return Field;
@@ -930,12 +931,14 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type,
930931

931932
// Get the flexible array member Decl.
932933
const RecordDecl *OuterRD = nullptr;
933-
std::string FAMName;
934+
const FieldDecl *FAMDecl = nullptr;
934935
if (const auto *ME = dyn_cast<MemberExpr>(Base)) {
935936
// Check if \p Base is referencing the FAM itself.
936937
const ValueDecl *VD = ME->getMemberDecl();
937938
OuterRD = VD->getDeclContext()->getOuterLexicalRecordContext();
938-
FAMName = VD->getNameAsString();
939+
FAMDecl = dyn_cast<FieldDecl>(VD);
940+
if (!FAMDecl)
941+
return nullptr;
939942
} else if (const auto *DRE = dyn_cast<DeclRefExpr>(Base)) {
940943
// Check if we're pointing to the whole struct.
941944
QualType Ty = DRE->getDecl()->getType();
@@ -974,9 +977,11 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type,
974977
if (!OuterRD)
975978
return nullptr;
976979

980+
// We call FindFlexibleArrayMemberAndOffset even if FAMDecl is non-null to
981+
// get its offset.
977982
uint64_t Offset = 0;
978-
const FieldDecl *FAMDecl =
979-
FindFlexibleArrayMemberField(Ctx, OuterRD, FAMName, Offset);
983+
FAMDecl =
984+
FindFlexibleArrayMemberFieldAndOffset(Ctx, OuterRD, FAMDecl, Offset);
980985
Offset = Ctx.toCharUnitsFromBits(Offset).getQuantity();
981986

982987
if (!FAMDecl || !FAMDecl->getType()->isCountAttributedType())

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3204,12 +3204,12 @@ class CodeGenFunction : public CodeGenTypeCache {
32043204
llvm::Value *Index, QualType IndexType,
32053205
QualType IndexedType, bool Accessed);
32063206

3207-
// Find a struct's flexible array member. It may be embedded inside multiple
3208-
// sub-structs, but must still be the last field.
3209-
const FieldDecl *FindFlexibleArrayMemberField(ASTContext &Ctx,
3210-
const RecordDecl *RD,
3211-
StringRef Name,
3212-
uint64_t &Offset);
3207+
// Find a struct's flexible array member and get its offset. It may be
3208+
// embedded inside multiple sub-structs, but must still be the last field.
3209+
const FieldDecl *
3210+
FindFlexibleArrayMemberFieldAndOffset(ASTContext &Ctx, const RecordDecl *RD,
3211+
const FieldDecl *FAMDecl,
3212+
uint64_t &Offset);
32133213

32143214
/// Find the FieldDecl specified in a FAM's "counted_by" attribute. Returns
32153215
/// \p nullptr if either the attribute or the field doesn't exist.

0 commit comments

Comments
 (0)