From 633c0c2fbc1d9272b3f25220ffb8fe4b04ece3db Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Sat, 2 Nov 2013 10:38:05 +0000 Subject: [PATCH] Sema: Cleanup and simplify anonymous union diagnostics The determination of which diagnostics would be issued for certain anonymous unions started to get a little ridiculous. Clean this up by inverting the condition-tree's logic from dialect -> issue to issue -> diagnostic. As part of this cleanup, move ext_c99_flexible_array_member from DiagnosticParseKinds.td to DiagnosticSemaKinds.td because it's driven by Sema, not Parse. Also, the liberty was taken to edit ext_c99_flexible_array_member to match other, similar, diagnostics. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@193919 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticParseKinds.td | 2 - include/clang/Basic/DiagnosticSemaKinds.td | 9 +++- lib/Sema/SemaDecl.cpp | 57 +++++++++------------ test/Sema/c89.c | 2 +- test/SemaCXX/c99.cpp | 2 +- 5 files changed, 32 insertions(+), 40 deletions(-) diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 932732402c..1df1713972 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; def ext_c99_compound_literal : Extension< "compound literals are a C99-specific feature">, InGroup; -def ext_c99_flexible_array_member : Extension< - "flexible array members are a C99-specific feature">, InGroup; def ext_enumerator_list_comma_c : Extension< "commas at the end of enumerator lists are a C99-specific " "feature">, InGroup; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index fea3fe996d..ae2d9c9e77 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; -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; +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; +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; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 6c8b36c6cc..101f4ce898 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 0c42ec291f..b746d383f3 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 3383d595f0..7afcdd509f 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}} \ -- 2.40.0