diff options
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 16 | ||||
| -rw-r--r-- | clang/test/Sema/flexible-array-init.c | 9 | 
2 files changed, 20 insertions, 5 deletions
| diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 23721e5d992..e7714521c84 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -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. diff --git a/clang/test/Sema/flexible-array-init.c b/clang/test/Sema/flexible-array-init.c index a0f1acd0715..12f5d4f5d60 100644 --- a/clang/test/Sema/flexible-array-init.c +++ b/clang/test/Sema/flexible-array-init.c @@ -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;  } | 

