Author: sepavloff Date: Sat Jun 8 08:29:58 2013 New Revision: 183609 URL: http://llvm.org/viewvc/llvm-project?rev=183609&view=rev Log: Recognition of empty structures and unions is moved to semantic stage
Differential Revision: http://llvm-reviews.chandlerc.com/D586 Added: cfe/trunk/test/Sema/empty1.c cfe/trunk/test/Sema/empty2.c Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Parse/ParseDecl.cpp cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/test/Parser/declarators.c cfe/trunk/test/Sema/array-init.c Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=183609&r1=183608&r2=183609&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Sat Jun 8 08:29:58 2013 @@ -57,10 +57,6 @@ def ext_integer_complex : Extension< "complex integer types are a GNU extension">, InGroup<GNU>; def ext_thread_before : Extension<"'__thread' before '%0'">; -def ext_empty_struct_union : Extension< - "empty %select{struct|union}0 is a GNU extension">, InGroup<GNU>; -def warn_empty_struct_union_compat : Warning<"empty %select{struct|union}0 " - "has size 0 in C, size 1 in C++">, InGroup<CXXCompat>, DefaultIgnore; def error_empty_enum : Error<"use of empty enum">; def err_invalid_sign_spec : Error<"'%0' cannot be signed or unsigned">; def err_invalid_short_spec : Error<"'short %0' is invalid">; Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=183609&r1=183608&r2=183609&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sat Jun 8 08:29:58 2013 @@ -5464,6 +5464,15 @@ def err_expected_ident_or_lparen : Error def err_typecheck_cond_incompatible_operands_null : Error< "non-pointer operand type %0 incompatible with %select{NULL|nullptr}1">; +def ext_empty_struct_union : Extension< + "empty %select{struct|union}0 is a GNU extension">, InGroup<GNU>; +def ext_no_named_members_in_struct_union : Extension< + "%select{struct|union}0 without named members is a GNU extension">, InGroup<GNU>; +def warn_empty_struct_union_compat : Warning<"empty %select{struct|union}0 " + "has size 0 in C, size 1 in C++">, InGroup<CXXCompat>, DefaultIgnore; +def warn_zero_size_struct_union_compat : Warning<"%select{struct|union}0 " + "with only bit-fields of width 0 has size 0 in C, size 1 in C++">, + InGroup<CXXCompat>, DefaultIgnore; } // End of general sema category. // inline asm. Modified: cfe/trunk/lib/Parse/ParseDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=183609&r1=183608&r2=183609&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseDecl.cpp (original) +++ cfe/trunk/lib/Parse/ParseDecl.cpp Sat Jun 8 08:29:58 2013 @@ -3216,12 +3216,6 @@ void Parser::ParseStructUnionBody(Source ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope); Actions.ActOnTagStartDefinition(getCurScope(), TagDecl); - // Empty structs are an extension in C (C99 6.7.2.1p7). - if (Tok.is(tok::r_brace)) { - Diag(Tok, diag::ext_empty_struct_union) << (TagType == TST_union); - Diag(Tok, diag::warn_empty_struct_union_compat) << (TagType == TST_union); - } - SmallVector<Decl *, 32> FieldDecls; // While we still have something to read, read the declarations in the struct. Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=183609&r1=183608&r2=183609&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat Jun 8 08:29:58 2013 @@ -11235,6 +11235,41 @@ void Sema::ActOnFields(Scope* S, if (Record->hasAttrs()) CheckAlignasUnderalignment(Record); + + // Check if the structure/union declaration is a language extension. + if (!getLangOpts().CPlusPlus) { + bool ZeroSize = true; + bool UnnamedOnly = true; + unsigned UnnamedCnt = 0; + for (RecordDecl::field_iterator I = Record->field_begin(), + E = Record->field_end(); UnnamedOnly && I != E; ++I) { + if (I->isUnnamedBitfield()) { + UnnamedCnt++; + if (I->getBitWidthValue(Context) > 0) + ZeroSize = false; + } else { + UnnamedOnly = ZeroSize = false; + } + } + + // Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in + // C++. + if (ZeroSize) { + if (UnnamedCnt == 0) + Diag(RecLoc, diag::warn_empty_struct_union_compat) << Record->isUnion(); + else + Diag(RecLoc, diag::warn_zero_size_struct_union_compat) << Record->isUnion(); + } + + // Structs without named members are extension in C (C99 6.7.2.1p7), but + // are accepted by GCC. + if (UnnamedOnly) { + if (UnnamedCnt == 0) + Diag(RecLoc, diag::ext_empty_struct_union) << Record->isUnion(); + else + Diag(RecLoc, diag::ext_no_named_members_in_struct_union) << Record->isUnion(); + } + } } else { ObjCIvarDecl **ClsFields = reinterpret_cast<ObjCIvarDecl**>(RecFields.data()); Modified: cfe/trunk/test/Parser/declarators.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/declarators.c?rev=183609&r1=183608&r2=183609&view=diff ============================================================================== --- cfe/trunk/test/Parser/declarators.c (original) +++ cfe/trunk/test/Parser/declarators.c Sat Jun 8 08:29:58 2013 @@ -108,7 +108,8 @@ void test18() { } enum E1 { e1 }: // expected-error {{expected ';'}} -struct EnumBitfield { +struct EnumBitfield { // expected-warning {{struct without named members is a GNU extension}} enum E2 { e2 } : 4; // ok struct S { int n; }: // expected-error {{expected ';'}} + }; Modified: cfe/trunk/test/Sema/array-init.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/array-init.c?rev=183609&r1=183608&r2=183609&view=diff ============================================================================== --- cfe/trunk/test/Sema/array-init.c (original) +++ cfe/trunk/test/Sema/array-init.c Sat Jun 8 08:29:58 2013 @@ -226,7 +226,8 @@ void emptyInit() {struct {} x[] = {6};} // expected-error{{initializer for aggregate with no elements}} void noNamedInit() { - struct {int:5;} x[] = {6}; //expected-error{{initializer for aggregate with no elements}} + struct {int:5;} x[] = {6}; //expected-error{{initializer for aggregate with no elements}} \ +// expected-warning {{struct without named members is a GNU extension}} } struct {int a; int:5;} noNamedImplicit[] = {1,2,3}; int noNamedImplicitCheck[sizeof(noNamedImplicit) == 3 * sizeof(*noNamedImplicit) ? 1 : -1]; Added: cfe/trunk/test/Sema/empty1.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/empty1.c?rev=183609&view=auto ============================================================================== --- cfe/trunk/test/Sema/empty1.c (added) +++ cfe/trunk/test/Sema/empty1.c Sat Jun 8 08:29:58 2013 @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify -Wc++-compat + +struct emp_1 { // expected-warning {{empty struct has size 0 in C, size 1 in C++}} +}; + +union emp_2 { // expected-warning {{empty union has size 0 in C, size 1 in C++}} +}; + +struct emp_3 { // expected-warning {{struct with only bit-fields of width 0 has size 0 in C, size 1 in C++}} + int : 0; +}; + +union emp_4 { // expected-warning {{union with only bit-fields of width 0 has size 0 in C, size 1 in C++}} + int : 0; +}; + +struct emp_5 { // expected-warning {{struct with only bit-fields of width 0 has size 0 in C, size 1 in C++}} + int : 0; + int : 0; +}; + +union emp_6 { // expected-warning {{union with only bit-fields of width 0 has size 0 in C, size 1 in C++}} + int : 0; + int : 0; +}; Added: cfe/trunk/test/Sema/empty2.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/empty2.c?rev=183609&view=auto ============================================================================== --- cfe/trunk/test/Sema/empty2.c (added) +++ cfe/trunk/test/Sema/empty2.c Sat Jun 8 08:29:58 2013 @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic + +struct emp_1 { // expected-warning {{empty struct is a GNU extension}} +}; + +union emp_2 { // expected-warning {{empty union is a GNU extension}} +}; + +struct emp_3 { // expected-warning {{struct without named members is a GNU extension}} + int : 0; +}; + +union emp_4 { // expected-warning {{union without named members is a GNU extension}} + int : 0; +}; + +struct emp_5 { // expected-warning {{struct without named members is a GNU extension}} + int : 0; + int : 0; +}; + +union emp_6 { // expected-warning {{union without named members is a GNU extension}} + int : 0; + int : 0; +}; + +struct nonamed_1 { // expected-warning {{struct without named members is a GNU extension}} + int : 4; +}; + +union nonamed_2 { // expected-warning {{union without named members is a GNU extension}} + int : 4; +}; + +struct nonamed_3 { // expected-warning {{struct without named members is a GNU extension}} + int : 4; + unsigned int : 4; +}; + +union nonamed_4 { // expected-warning {{union without named members is a GNU extension}} + int : 4; + unsigned int : 4; +}; _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
