https://github.com/vvuksanovic created https://github.com/llvm/llvm-project/pull/160262
A flexible array member must remain the last field in the struct. >From a7e677c4acc6f92a8ee97893259397835f695dc5 Mon Sep 17 00:00:00 2001 From: Vladimir Vuksanovic <[email protected]> Date: Thu, 11 Sep 2025 11:29:47 +0200 Subject: [PATCH] [clang-reorder-fields] Check for flexible array member A flexible array member must remain the last field in the struct. --- .../ReorderFieldsAction.cpp | 20 +++++++++++++++++-- .../FlexibleArrayMember.c | 10 ++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 clang-tools-extra/test/clang-reorder-fields/FlexibleArrayMember.c diff --git a/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp b/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp index affa276a0c550..5770bf767bc3c 100644 --- a/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp +++ b/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp @@ -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 @@ class ReorderingConsumer : public ASTConsumer { return; SmallVector<unsigned, 4> NewFieldsOrder = getNewFieldsOrder(RD, DesiredFieldsOrder); - if (NewFieldsOrder.empty()) + if (!isOrderValid(RD, NewFieldsOrder)) return; ReorderedStruct RS{RD, NewFieldsOrder}; @@ -699,7 +715,7 @@ class ReorderingConsumer : public ASTConsumer { std::unique_ptr<ASTConsumer> ReorderFieldsAction::newASTConsumer() { return std::make_unique<ReorderingConsumer>(RecordName, DesiredFieldsOrder, - Replacements); + Replacements); } } // namespace reorder_fields diff --git a/clang-tools-extra/test/clang-reorder-fields/FlexibleArrayMember.c b/clang-tools-extra/test/clang-reorder-fields/FlexibleArrayMember.c new file mode 100644 index 0000000000000..ef64350fd08e6 --- /dev/null +++ b/clang-tools-extra/test/clang-reorder-fields/FlexibleArrayMember.c @@ -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\[\];}} +}; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
