diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 932732402c53cbc6fcdfda003a260ce712e55e97..1df1713972af42863d19086d3a58731e0736ec8c 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -73,8 +73,6 @@ def ext_c99_variable_decl_in_for_loop : Extension< "variable declaration in for loop is a C99-specific feature">, InGroup<C99>; def ext_c99_compound_literal : Extension< "compound literals are a C99-specific feature">, InGroup<C99>; -def ext_c99_flexible_array_member : Extension< - "flexible array members are a C99-specific feature">, InGroup<C99>; def ext_enumerator_list_comma_c : Extension< "commas at the end of enumerator lists are a C99-specific " "feature">, InGroup<C99>; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index fea3fe996de351b9981202660fcd899cee6cabc3..ae2d9c9e779df6dcd86f37ed6fd7c8928d11ec9f 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -3935,8 +3935,11 @@ def ext_variable_sized_type_in_struct : ExtWarn< "field %0 with variable sized type %1 not at the end of a struct or class is" " a GNU extension">, InGroup<GNUVariableSizedTypeNotAtEnd>; -def err_flexible_array_empty_struct : Error< - "flexible array %0 not allowed in otherwise empty struct">; +def ext_c99_flexible_array_member : Extension< + "flexible array members are a C99 feature">, InGroup<C99>; +def err_flexible_array_empty_aggregate : Error< + "flexible array member %0 not allowed in otherwise empty " + "%select{struct|interface|union|class|enum}1 is not allowed">; def err_flexible_array_has_nonpod_type : Error< "flexible array member %0 of non-POD element type %1">; def ext_flexible_array_in_struct : Extension< @@ -3951,6 +3954,8 @@ def ext_flexible_array_empty_aggregate_ms : Extension< "flexible array member %0 in otherwise empty " "%select{struct|interface|union|class|enum}1 is a Microsoft extension">, InGroup<Microsoft>; +def err_flexible_array_union : Error< + "flexible array member %0 in a union is not allowed">; def ext_flexible_array_union_ms : Extension< "flexible array member %0 in a union is a Microsoft extension">, InGroup<Microsoft>; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 6c8b36c6cc9e3c86905d57c6d7cd7add96b31b7c..101f4ce8988a315f7237c6f70511882e9645bd1b 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -11822,40 +11822,29 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, // Microsoft and g++ is more permissive regarding flexible array. // It will accept flexible array in union and also // as the sole element of a struct/class. - if (getLangOpts().MicrosoftExt) { - if (Record->isUnion()) - Diag(FD->getLocation(), diag::ext_flexible_array_union_ms) - << FD->getDeclName(); - else if (Fields.size() == 1) - Diag(FD->getLocation(), diag::ext_flexible_array_empty_aggregate_ms) - << FD->getDeclName() << Record->getTagKind(); - else - Diag(FD->getLocation(), diag::ext_c99_flexible_array_member) - << FD->getDeclName() << Record->getTagKind(); - } else if (getLangOpts().CPlusPlus) { - if (Record->isUnion()) - Diag(FD->getLocation(), diag::ext_flexible_array_union_gnu) - << FD->getDeclName(); - else if (Fields.size() == 1) - Diag(FD->getLocation(), diag::ext_flexible_array_empty_aggregate_gnu) - << FD->getDeclName() << Record->getTagKind(); - else - Diag(FD->getLocation(), diag::ext_c99_flexible_array_member) - << FD->getDeclName() << Record->getTagKind(); - } else if (!getLangOpts().C99) { - if (Record->isUnion()) - Diag(FD->getLocation(), diag::ext_flexible_array_union_gnu) - << FD->getDeclName(); - else - Diag(FD->getLocation(), diag::ext_c99_flexible_array_member) - << FD->getDeclName() << Record->getTagKind(); - } else if (NumNamedMembers < 1) { - Diag(FD->getLocation(), diag::err_flexible_array_empty_struct) - << FD->getDeclName(); - FD->setInvalidDecl(); - EnclosingDecl->setInvalidDecl(); - continue; - } + unsigned DiagID = 0; + if (Record->isUnion()) + DiagID = getLangOpts().MicrosoftExt + ? diag::ext_flexible_array_union_ms + : getLangOpts().CPlusPlus + ? diag::ext_flexible_array_union_gnu + : diag::err_flexible_array_union; + else if (Fields.size() == 1) + DiagID = getLangOpts().MicrosoftExt + ? diag::ext_flexible_array_empty_aggregate_ms + : getLangOpts().CPlusPlus + ? diag::ext_flexible_array_empty_aggregate_gnu + : NumNamedMembers < 1 + ? diag::err_flexible_array_empty_aggregate + : 0; + + if (DiagID) + Diag(FD->getLocation(), DiagID) << FD->getDeclName() + << Record->getTagKind(); + if (!getLangOpts().C99) + Diag(FD->getLocation(), diag::ext_c99_flexible_array_member) + << FD->getDeclName() << Record->getTagKind(); + if (!FD->getType()->isDependentType() && !Context.getBaseElementType(FD->getType()).isPODType(Context)) { Diag(FD->getLocation(), diag::err_flexible_array_has_nonpod_type) diff --git a/test/Sema/c89.c b/test/Sema/c89.c index 0c42ec291f04c271aea17fac2fcb163a601560bc..b746d383f3069f339fc8e7dd9e8e2e4bea82774d 100644 --- a/test/Sema/c89.c +++ b/test/Sema/c89.c @@ -90,7 +90,7 @@ void test16() { printg("Hello, world!\n"); /* expected-warning {{implicit declaration of function 'printg'}} */ } -struct x { int x,y[]; }; /* expected-warning {{flexible array members are a C99-specific feature}} */ +struct x { int x,y[]; }; /* expected-warning {{flexible array members are a C99 feature}} */ /* Duplicated type-qualifiers aren't allowed by C90 */ const const int c_i; /* expected-warning {{duplicate 'const' declaration specifier}} */ diff --git a/test/SemaCXX/c99.cpp b/test/SemaCXX/c99.cpp index 3383d595f0ed36318a014c277183b8de5563c9be..7afcdd509f9d18091caac0ea86a2d595590cb5b8 100644 --- a/test/SemaCXX/c99.cpp +++ b/test/SemaCXX/c99.cpp @@ -2,7 +2,7 @@ void f1(int i[static 5]) { // expected-error{{C99}} } -struct Point { int x; int y; int z[]; }; // expected-warning{{flexible array members are a C99-specific feature}} +struct Point { int x; int y; int z[]; }; // expected-warning{{flexible array members are a C99 feature}} Point p1 = { .x = 17, // expected-warning{{designated initializers are a C99 feature}} y: 25 }; // expected-warning{{designated initializers are a C99 feature}} \