r183609 - Recognition of empty structures and unions is moved to semantic stage
Serge Pavlov
sepavloff at gmail.com
Sat Jun 8 06:29:59 PDT 2013
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;
+};
More information about the cfe-commits
mailing list