From 01620704304f819b82ecef769ec114e541a364d7 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 21 Mar 2010 22:56:43 +0000 Subject: [PATCH] Fix PR6618. If a struct has an invalid field, mark it as invalid. Also avoid producing errors about incomplete types that are invalid. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99150 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDecl.cpp | 4 ++++ lib/Sema/SemaType.cpp | 18 +++++++++++------- test/Sema/nested-redef.c | 3 +-- test/SemaCXX/PR6618.cpp | 13 +++++++++++++ test/SemaObjC/ivar-sem-check-1.m | 3 +-- 5 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 test/SemaCXX/PR6618.cpp diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index e11e161ffd..f5f2f94758 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5261,6 +5261,10 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record, FieldDecl *NewFD = CheckFieldDecl(II, T, TInfo, Record, Loc, Mutable, BitWidth, TSSL, AS, PrevDecl, &D); + + if (NewFD->isInvalidDecl()) + Record->setInvalidDecl(); + if (NewFD->isInvalidDecl() && PrevDecl) { // Don't introduce NewFD into scope; there's already something // with the same name in the same scope. diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index a79853afdc..80e1a05111 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -1942,6 +1942,16 @@ bool Sema::RequireCompleteType(SourceLocation Loc, QualType T, if (diag == 0) return true; + const TagType *Tag = 0; + if (const RecordType *Record = T->getAs()) + Tag = Record; + else if (const EnumType *Enum = T->getAs()) + Tag = Enum; + + // Avoid diagnosing invalid decls as incomplete. + if (Tag && Tag->getDecl()->isInvalidDecl()) + return true; + // We have an incomplete type. Produce a diagnostic. Diag(Loc, PD) << T; @@ -1950,13 +1960,7 @@ bool Sema::RequireCompleteType(SourceLocation Loc, QualType T, Diag(Note.first, Note.second); // If the type was a forward declaration of a class/struct/union - // type, produce - const TagType *Tag = 0; - if (const RecordType *Record = T->getAs()) - Tag = Record; - else if (const EnumType *Enum = T->getAs()) - Tag = Enum; - + // type, produce a note. if (Tag && !Tag->getDecl()->isInvalidDecl()) Diag(Tag->getDecl()->getLocation(), Tag->isBeingDefined() ? diag::note_type_being_defined diff --git a/test/Sema/nested-redef.c b/test/Sema/nested-redef.c index 6a19921f47..bbc4859367 100644 --- a/test/Sema/nested-redef.c +++ b/test/Sema/nested-redef.c @@ -1,7 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s struct X { // expected-note{{previous definition is here}} - struct X { } x; // expected-error{{nested redefinition of 'X'}} \ - // expected-error{{field has incomplete type}} + struct X { } x; // expected-error{{nested redefinition of 'X'}} }; struct Y { }; diff --git a/test/SemaCXX/PR6618.cpp b/test/SemaCXX/PR6618.cpp new file mode 100644 index 0000000000..10d4dc87b0 --- /dev/null +++ b/test/SemaCXX/PR6618.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +class bar; // expected-note {{forward declaration of 'bar'}} +struct zed { + bar g; // expected-error {{field has incomplete type}} +}; +class baz { + zed h; +}; +void f() { + enum { + e = sizeof(baz) + }; +} diff --git a/test/SemaObjC/ivar-sem-check-1.m b/test/SemaObjC/ivar-sem-check-1.m index 099a7a669a..de038f5487 100644 --- a/test/SemaObjC/ivar-sem-check-1.m +++ b/test/SemaObjC/ivar-sem-check-1.m @@ -9,8 +9,7 @@ typedef int FOO(); int arr[]; // expected-error {{field has incomplete type}} struct S IC; // expected-error {{field has incomplete type}} struct T { // expected-note {{previous definition is here}} - struct T {} X; // expected-error {{nested redefinition of 'T'}} \ - // expected-error {{field has incomplete type}} + struct T {} X; // expected-error {{nested redefinition of 'T'}} }YYY; FOO BADFUNC; // expected-error {{field 'BADFUNC' declared as a function}} int kaka; // expected-note {{previous declaration is here}} -- 2.40.0