[clang-reorder-fields] Check for flexible array member (#160262)

A flexible array member must remain the last field in the struct.
This commit is contained in:
Vladimir Vuksanovic 2025-09-30 00:05:28 +02:00 committed by GitHub
parent d481e5f9b7
commit 63e45504ab
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 28 additions and 2 deletions

View File

@ -164,6 +164,22 @@ getNewFieldsOrder(const RecordDecl *Definition,
return NewFieldsOrder;
}
static bool isOrderValid(const RecordDecl *RD, ArrayRef<unsigned> FieldOrder) {
if (FieldOrder.empty())
return false;
// If there is a flexible array member in the struct, it must remain the last
// field.
if (RD->hasFlexibleArrayMember() &&
FieldOrder.back() != FieldOrder.size() - 1) {
llvm::errs()
<< "Flexible array member must remain the last field in the struct\n";
return false;
}
return true;
}
struct ReorderedStruct {
public:
ReorderedStruct(const RecordDecl *Decl, ArrayRef<unsigned> NewFieldsOrder)
@ -662,7 +678,7 @@ public:
return;
SmallVector<unsigned, 4> NewFieldsOrder =
getNewFieldsOrder(RD, DesiredFieldsOrder);
if (NewFieldsOrder.empty())
if (!isOrderValid(RD, NewFieldsOrder))
return;
ReorderedStruct RS{RD, NewFieldsOrder};
@ -699,7 +715,7 @@ public:
std::unique_ptr<ASTConsumer> ReorderFieldsAction::newASTConsumer() {
return std::make_unique<ReorderingConsumer>(RecordName, DesiredFieldsOrder,
Replacements);
Replacements);
}
} // namespace reorder_fields

View File

@ -0,0 +1,10 @@
// RUN: clang-reorder-fields -record-name Foo -fields-order z,y,x %s -- 2>&1 | FileCheck --check-prefix=CHECK-BAD %s
// RUN: clang-reorder-fields -record-name Foo -fields-order y,x,z %s -- | FileCheck --check-prefix=CHECK-GOOD %s
// CHECK-BAD: {{^Flexible array member must remain the last field in the struct}}
struct Foo {
int x; // CHECK-GOOD: {{^ int y;}}
int y; // CHECK-GOOD-NEXT: {{^ int x;}}
int z[]; // CHECK-GOOD-NEXT: {{^ int z\[\];}}
};