Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions clang/lib/Sema/SemaInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
30 changes: 30 additions & 0 deletions clang/test/Sema/warn-default-const-init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Loading