forked from OSchip/llvm-project
Allow list-initialization of a local variable of class type with a
flexible array member, so long as the flexibility array member is either not initialized or is initialized with an empty initializer list. Fixes <rdar://problem/8540437>. llvm-svn: 116647
This commit is contained in:
parent
ad5f98a9b2
commit
1f81ced14c
|
@ -4395,9 +4395,19 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
|
|||
// global/static definition.
|
||||
if (VDecl->hasLocalStorage())
|
||||
if (const RecordType *RT = VDecl->getType()->getAs<RecordType>())
|
||||
if (RT->getDecl()->hasFlexibleArrayMember() && isa<InitListExpr>(Init)) {
|
||||
Diag(VDecl->getLocation(), diag::err_nonstatic_flexible_variable);
|
||||
VDecl->setInvalidDecl();
|
||||
if (RT->getDecl()->hasFlexibleArrayMember()) {
|
||||
// Check whether the initializer tries to initialize the flexible
|
||||
// array member itself to anything other than an empty initializer list.
|
||||
if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
|
||||
unsigned Index = std::distance(RT->getDecl()->field_begin(),
|
||||
RT->getDecl()->field_end()) - 1;
|
||||
if (Index < ILE->getNumInits() &&
|
||||
!(isa<InitListExpr>(ILE->getInit(Index)) &&
|
||||
cast<InitListExpr>(ILE->getInit(Index))->getNumInits() == 0)) {
|
||||
Diag(VDecl->getLocation(), diag::err_nonstatic_flexible_variable);
|
||||
VDecl->setInvalidDecl();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check any implicit conversions within the expression.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
|
||||
struct one {
|
||||
int a;
|
||||
int values[]; // expected-note 3{{initialized flexible array member 'values' is here}}
|
||||
int values[]; // expected-note 4{{initialized flexible array member 'values' is here}}
|
||||
} x = {5, {1, 2, 3}}; // expected-warning{{flexible array initialization is a GNU extension}}
|
||||
|
||||
struct one x2 = { 5, 1, 2, 3 }; // expected-warning{{flexible array initialization is a GNU extension}}
|
||||
|
@ -10,6 +10,11 @@ void test() {
|
|||
struct one x3 = {5, {1, 2, 3}}; // \
|
||||
// expected-warning{{flexible array initialization is a GNU extension}} \
|
||||
// expected-error {{non-static initialization of a variable with flexible array member}}
|
||||
struct one x3a = { 5 };
|
||||
struct one x3b = { .a = 5 };
|
||||
struct one x3c = { 5, {} }; // expected-warning{{use of GNU empty initializer extension}} \
|
||||
// expected-warning{{flexible array initialization is a GNU extension}} \
|
||||
// expected-warning{{zero size arrays are an extension}}
|
||||
}
|
||||
|
||||
struct foo {
|
||||
|
@ -68,7 +73,7 @@ struct PR8217a {
|
|||
|
||||
void PR8217() {
|
||||
struct PR8217a foo1 = { .i = 0, .v = "foo" }; // expected-error {{non-static initialization of a variable with flexible array member}}
|
||||
struct PR8217a foo2 = { .i = 0 }; // expected-error {{non-static initialization of a variable with flexible array member}}
|
||||
struct PR8217a foo2 = { .i = 0 };
|
||||
struct PR8217a foo3 = { .i = 0, .v = { 'b', 'a', 'r', '\0' } }; // expected-error {{non-static initialization of a variable with flexible array member}}
|
||||
struct PR8217a bar;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue