diff options
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 25 | ||||
-rw-r--r-- | test/CodeGen/flexible-array-init.c | 8 | ||||
-rw-r--r-- | test/Sema/array-init.c | 4 | ||||
-rw-r--r-- | test/Sema/flexible-array-init.c | 14 |
5 files changed, 38 insertions, 15 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 8b6ef49542..0518094e4c 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -66,6 +66,8 @@ def err_designator_into_flexible_array_member : Error< "designator into flexible array member subobject">; def note_flexible_array_member : Note< "initialized flexible array member %0 is here">; +def ext_flexible_array_init : Extension< + "flexible array initialization is a GNU extension">; // Declarations. def ext_vla : Extension< diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index e0d3b7e545..8a5e2c87d3 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -481,7 +481,8 @@ void InitListChecker::CheckImplicitInitList(InitListExpr *ParentIList, StructuredSubobjectInitIndex, TopLevelObject); unsigned EndIndex = (Index == StartIndex? StartIndex : Index - 1); - + StructuredSubobjectInitList->setType(T); + // Update the structured sub-object initializer so that it's ending // range corresponds with the end of the last initializer it used. if (EndIndex < ParentIList->getNumInits()) { @@ -995,23 +996,35 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList, } if (Field == FieldEnd || !Field->getType()->isIncompleteArrayType() || - Index >= IList->getNumInits() || - !isa<InitListExpr>(IList->getInit(Index))) + Index >= IList->getNumInits()) return; // Handle GNU flexible array initializers. if (!TopLevelObject && - cast<InitListExpr>(IList->getInit(Index))->getNumInits() > 0) { + (!isa<InitListExpr>(IList->getInit(Index)) || + cast<InitListExpr>(IList->getInit(Index))->getNumInits() > 0)) { SemaRef.Diag(IList->getInit(Index)->getSourceRange().getBegin(), diag::err_flexible_array_init_nonempty) << IList->getInit(Index)->getSourceRange().getBegin(); SemaRef.Diag(Field->getLocation(), diag::note_flexible_array_member) << *Field; hadError = true; + ++Index; + return; + } else { + SemaRef.Diag(IList->getInit(Index)->getSourceRange().getBegin(), + diag::ext_flexible_array_init) + << IList->getInit(Index)->getSourceRange().getBegin(); + SemaRef.Diag(Field->getLocation(), diag::note_flexible_array_member) + << *Field; } - CheckSubElementType(IList, Field->getType(), Index, StructuredList, - StructuredIndex); + if (isa<InitListExpr>(IList->getInit(Index))) + CheckSubElementType(IList, Field->getType(), Index, StructuredList, + StructuredIndex); + else + CheckImplicitInitList(IList, Field->getType(), Index, StructuredList, + StructuredIndex); } /// @brief Check the well-formedness of a C99 designated initializer. diff --git a/test/CodeGen/flexible-array-init.c b/test/CodeGen/flexible-array-init.c new file mode 100644 index 0000000000..0e2fcc69d1 --- /dev/null +++ b/test/CodeGen/flexible-array-init.c @@ -0,0 +1,8 @@ +// RUN: clang -triple i386-unknown-unknown -emit-llvm -o - %s | grep 7 | count 1 && +// RUN: clang -triple i386-unknown-unknown -emit-llvm -o - %s | grep 11 | count 1 && +// RUN: clang -triple i386-unknown-unknown -emit-llvm -o - %s | grep 13 | count 1 && +// RUN: clang -triple i386-unknown-unknown -emit-llvm -o - %s | grep 15 | count 1 + +struct { int x; int y[]; } a = { 1, 7, 11 }; + +struct { int x; int y[]; } b = { 1, { 13, 15 } }; diff --git a/test/Sema/array-init.c b/test/Sema/array-init.c index 4ee86181af..0c1bbc0470 100644 --- a/test/Sema/array-init.c +++ b/test/Sema/array-init.c @@ -201,8 +201,8 @@ int bar (void) { return z.z; } struct s3 {void (*a)(void);} t5 = {autoStructTest}; -// Note that clang objc implementation depends on this extension. -struct {int a; int b[];} t6 = {1, {1, 2, 3}}; +struct {int a; int b[];} t6 = {1, {1, 2, 3}}; // expected-warning{{flexible array initialization is a GNU extension}} \ +// expected-note{{initialized flexible array member 'b' is here}} union {char a; int b;} t7[] = {1, 2, 3}; int t8[sizeof t7 == (3*sizeof(int)) ? 1 : -1]; diff --git a/test/Sema/flexible-array-init.c b/test/Sema/flexible-array-init.c index fff5fee2af..2b8f40fa5b 100644 --- a/test/Sema/flexible-array-init.c +++ b/test/Sema/flexible-array-init.c @@ -1,24 +1,24 @@ // RUN: clang -fsyntax-only -pedantic -verify %s struct one { int a; - int values[]; -} x = {5, {1, 2, 3}}; + int values[]; // expected-note 3{{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{{excess elements in struct initializer}} +struct one x2 = { 5, 1, 2, 3 }; // expected-warning{{flexible array initialization is a GNU extension}} void test() { - struct one x3 = {5, {1, 2, 3}}; + struct one x3 = {5, {1, 2, 3}}; // expected-warning{{flexible array initialization is a GNU extension}} } struct foo { int x; - int y[]; // expected-note 4 {{initialized flexible array member 'y' is here}} + int y[]; // expected-note 6 {{initialized flexible array member 'y' is here}} }; struct bar { struct foo z; }; // expected-warning {{'z' may not be nested in a struct due to flexible array member}} -struct foo a = { 1, { 2, 3, 4 } }; // Valid. +struct foo a = { 1, { 2, 3, 4 } }; // expected-warning{{flexible array initialization is a GNU extension}} struct bar b = { { 1, { 2, 3, 4 } } }; // expected-error{{non-empty initialization of flexible array member inside subobject}} -struct bar c = { { 1, { } } }; // Valid. \ +struct bar c = { { 1, { } } }; // // expected-warning{{flexible array initialization is a GNU extension}} \ // expected-warning{{use of GNU empty initializer extension}} \ // expected-warning{{zero size arrays are an extension}} struct foo d[1] = { { 1, { 2, 3, 4 } } }; // expected-warning{{'struct foo' may not be used as an array element due to flexible array member}} \ |