diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-02-07 05:00:47 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-02-07 05:00:47 +0000 |
commit | a767941651945183cc3665173fd850a6b057c018 (patch) | |
tree | 9fa740ff39679377d3f161a0f55db99ddb4857ee | |
parent | 2beed114ba03a89dad892c70b8df959a7c014dde (diff) | |
download | bcm5719-llvm-a767941651945183cc3665173fd850a6b057c018.tar.gz bcm5719-llvm-a767941651945183cc3665173fd850a6b057c018.zip |
Fix a bug in semantic analysis involving anonymous structs and flexible arrays.
llvm-svn: 149966
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 16 | ||||
-rw-r--r-- | clang/test/Sema/anonymous-struct-union.c | 6 |
2 files changed, 20 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index c44b474e805..ffc7c618727 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -9171,11 +9171,23 @@ void Sema::ActOnFields(Scope* S, if (EnclosingDecl->isInvalidDecl()) return; - // Verify that all the fields are okay. + RecordDecl *Record = dyn_cast<RecordDecl>(EnclosingDecl); + + // Start counting up the number of named members; make sure to include + // members of anonymous structs and unions in the total. unsigned NumNamedMembers = 0; + if (Record) { + for (RecordDecl::decl_iterator i = Record->decls_begin(), + e = Record->decls_end(); i != e; i++) { + if (IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(*i)) + if (IFD->getDeclName()) + ++NumNamedMembers; + } + } + + // Verify that all the fields are okay. SmallVector<FieldDecl*, 32> RecFields; - RecordDecl *Record = dyn_cast<RecordDecl>(EnclosingDecl); bool ARCErrReported = false; for (llvm::ArrayRef<Decl *>::iterator i = Fields.begin(), end = Fields.end(); i != end; ++i) { diff --git a/clang/test/Sema/anonymous-struct-union.c b/clang/test/Sema/anonymous-struct-union.c index d88abc3c3b9..e0822901b0e 100644 --- a/clang/test/Sema/anonymous-struct-union.c +++ b/clang/test/Sema/anonymous-struct-union.c @@ -102,3 +102,9 @@ typedef struct { int x; } a_struct; int tmp = (a_struct) { .x = 0 }; // expected-error {{initializing 'int' with an expression of incompatible type 'a_struct'}} + +// This example comes out of the C11 standard; make sure we don't accidentally reject it. +struct s { + struct { int i; }; + int a[]; +}; |