Skip to content

Commit 63e4550

Browse files
authored
[clang-reorder-fields] Check for flexible array member (#160262)
A flexible array member must remain the last field in the struct.
1 parent d481e5f commit 63e4550

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,22 @@ getNewFieldsOrder(const RecordDecl *Definition,
164164
return NewFieldsOrder;
165165
}
166166

167+
static bool isOrderValid(const RecordDecl *RD, ArrayRef<unsigned> FieldOrder) {
168+
if (FieldOrder.empty())
169+
return false;
170+
171+
// If there is a flexible array member in the struct, it must remain the last
172+
// field.
173+
if (RD->hasFlexibleArrayMember() &&
174+
FieldOrder.back() != FieldOrder.size() - 1) {
175+
llvm::errs()
176+
<< "Flexible array member must remain the last field in the struct\n";
177+
return false;
178+
}
179+
180+
return true;
181+
}
182+
167183
struct ReorderedStruct {
168184
public:
169185
ReorderedStruct(const RecordDecl *Decl, ArrayRef<unsigned> NewFieldsOrder)
@@ -662,7 +678,7 @@ class ReorderingConsumer : public ASTConsumer {
662678
return;
663679
SmallVector<unsigned, 4> NewFieldsOrder =
664680
getNewFieldsOrder(RD, DesiredFieldsOrder);
665-
if (NewFieldsOrder.empty())
681+
if (!isOrderValid(RD, NewFieldsOrder))
666682
return;
667683
ReorderedStruct RS{RD, NewFieldsOrder};
668684

@@ -699,7 +715,7 @@ class ReorderingConsumer : public ASTConsumer {
699715

700716
std::unique_ptr<ASTConsumer> ReorderFieldsAction::newASTConsumer() {
701717
return std::make_unique<ReorderingConsumer>(RecordName, DesiredFieldsOrder,
702-
Replacements);
718+
Replacements);
703719
}
704720

705721
} // namespace reorder_fields
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: clang-reorder-fields -record-name Foo -fields-order z,y,x %s -- 2>&1 | FileCheck --check-prefix=CHECK-BAD %s
2+
// RUN: clang-reorder-fields -record-name Foo -fields-order y,x,z %s -- | FileCheck --check-prefix=CHECK-GOOD %s
3+
4+
// CHECK-BAD: {{^Flexible array member must remain the last field in the struct}}
5+
6+
struct Foo {
7+
int x; // CHECK-GOOD: {{^ int y;}}
8+
int y; // CHECK-GOOD-NEXT: {{^ int x;}}
9+
int z[]; // CHECK-GOOD-NEXT: {{^ int z\[\];}}
10+
};

0 commit comments

Comments
 (0)