]> granicus.if.org Git - clang/commitdiff
Fix PR6618.
authorRafael Espindola <rafael.espindola@gmail.com>
Sun, 21 Mar 2010 22:56:43 +0000 (22:56 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Sun, 21 Mar 2010 22:56:43 +0000 (22:56 +0000)
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
lib/Sema/SemaType.cpp
test/Sema/nested-redef.c
test/SemaCXX/PR6618.cpp [new file with mode: 0644]
test/SemaObjC/ivar-sem-check-1.m

index e11e161ffde2c99d17b7ba66205400c8941cbce0..f5f2f9475868d069cbb4e66256fd661caf40aa71 100644 (file)
@@ -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.
index a79853afdc6b789839b329a017d577f1f84164bd..80e1a0511150e6f2a0632b3452250be3a506a521 100644 (file)
@@ -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<RecordType>())
+    Tag = Record;
+  else if (const EnumType *Enum = T->getAs<EnumType>())
+    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<RecordType>())
-    Tag = Record;
-  else if (const EnumType *Enum = T->getAs<EnumType>())
-    Tag = Enum;
-
+  // type, produce a note.
   if (Tag && !Tag->getDecl()->isInvalidDecl())
     Diag(Tag->getDecl()->getLocation(),
          Tag->isBeingDefined() ? diag::note_type_being_defined
index 6a19921f47fa532e259033e1fa8af2404b8b52d5..bbc485936770478dded4bc77d513f398e18a76f1 100644 (file)
@@ -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 (file)
index 0000000..10d4dc8
--- /dev/null
@@ -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)
+  };
+}
index 099a7a669a91f05d1f4262c545b6dbeb26f0e6cc..de038f5487b5f552e1a6d078c69fc6a033c40598 100644 (file)
@@ -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}}