https://github.com/AaronBallman created https://github.com/llvm/llvm-project/pull/140578
This addresses post-commit review feedback from someone who discovered that we diagnosed code like the following: ``` struct S { int len; const char fam[]; } s; ``` despite it being invalid to initialize the flexible array member. Note, this applies to flexible array members and zero-sized arrays at the end of a structure (an old-style flexible array member), but it does not apply to one-sized arrays at the end of a structure because those do occupy storage that can be initialized. >From 625662da41256345c4609835754c3a61018b54ca Mon Sep 17 00:00:00 2001 From: Aaron Ballman <aa...@aaronballman.com> Date: Mon, 19 May 2025 13:09:03 -0400 Subject: [PATCH] [C] Do not diagnose flexible array members with -Wdefault-const-init-field-unsafe This addresses post-commit review feedback from someone who discovered that we diagnosed code like the following: struct S { int len; const char fam[]; } s; despite it being invalid to initialize the flexible array member. Note, this applies to flexible array members and zero-sized arrays at the end of a structure (an old-style flexible array member), but it does not apply to one-sized arrays at the end of a structure because those do occupy storage that can be initialized. --- clang/lib/Sema/SemaInit.cpp | 8 ++++++ clang/test/Sema/warn-default-const-init.c | 30 +++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 9ee8603ff7811..e17e68966dc00 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -6513,6 +6513,14 @@ static bool canPerformArrayCopy(const InitializedEntity &Entity) { static const FieldDecl *getConstField(const RecordDecl *RD) { assert(!isa<CXXRecordDecl>(RD) && "Only expect to call this in C mode"); for (const FieldDecl *FD : RD->fields()) { + // If the field is a flexible array member, we don't want to consider it + // as a const field because there's no way to initialize the FAM anyway. + if (Decl::isFlexibleArrayMemberLike( + FD->getASTContext(), FD, FD->getType(), + LangOptions::StrictFlexArraysLevelKind::ZeroOrIncomplete, + /*IgnoreTemplateOrMacroSubstitution=*/true)) + continue; + QualType QT = FD->getType(); if (QT.isConstQualified()) return FD; diff --git a/clang/test/Sema/warn-default-const-init.c b/clang/test/Sema/warn-default-const-init.c index e788d72899685..e6ff0aa783e23 100644 --- a/clang/test/Sema/warn-default-const-init.c +++ b/clang/test/Sema/warn-default-const-init.c @@ -85,3 +85,33 @@ void func() { static const int b; // zero-init-var-warning {{default initialization of an object of type 'const int' is incompatible with C++}} \ cxx-error {{default initialization of an object of const type 'const int'}} } + +// Test the behavior of flexible array members. Those cannot be initialized +// when a stack-allocated object of the structure type is created. We handle +// degenerate flexible arrays similarly, but only if the array does not +// actually specify any storage. Note that C++ does not have flexible array +// members at all, which is why the test is disabled there. +#ifndef __cplusplus +struct RealFAM { + int len; + const char fam[]; +}; + +struct FakeFAM { + int len; + const char fam[0]; +}; + +struct NotTreatedAsAFAM { + int len; + const char fam[1]; // unsafe-field-note {{member 'fam' declared 'const' here}} \ + unsafe-field-compat-note {{member 'fam' declared 'const' here}} +}; + +void test_fams() { + struct RealFAM One; + struct FakeFAM Two; + struct NotTreatedAsAFAM Three; // unsafe-field-warning {{default initialization of an object of type 'struct NotTreatedAsAFAM' with const member leaves the object uninitialized}} \ + unsafe-field-compat-warning {{default initialization of an object of type 'struct NotTreatedAsAFAM' with const member leaves the object uninitialized and is incompatible with C++}} +} +#endif // !defined(__cplusplus) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits