[cfe-commits] r66584 - in /cfe/trunk: lib/Sema/SemaDecl.cpp test/Sema/bitfield.c test/Sema/enum.c test/Sema/incomplete-decl.c test/Sema/tentative-decls.c

Douglas Gregor dgregor at apple.com
Tue Mar 10 14:58:27 PDT 2009


Author: dgregor
Date: Tue Mar 10 16:58:27 2009
New Revision: 66584

URL: http://llvm.org/viewvc/llvm-project?rev=66584&view=rev
Log:
Partial fix for PR3310, concerning type-checking for tentative
definitions. We were rejecting tentative definitions of incomplete
(which is bad), and now we don't.

This fix is partial because we don't do the end-of-translation-unit
initialization for tentative definitions that don't ever have any
initializers specified.


Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/Sema/bitfield.c
    cfe/trunk/test/Sema/enum.c
    cfe/trunk/test/Sema/incomplete-decl.c
    cfe/trunk/test/Sema/tentative-decls.c

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=66584&r1=66583&r2=66584&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Mar 10 16:58:27 2009
@@ -1749,6 +1749,13 @@
     }
   }
 
+  if (!InvalidDecl && R->isVoidType() && !NewVD->hasExternalStorage()) {
+    Diag(NewVD->getLocation(), diag::err_typecheck_decl_incomplete_type)
+      << R;
+    InvalidDecl = true;
+  }
+
+
   // If this is a locally-scoped extern C variable, update the map of
   // such variables.
   if (CurContext->isFunctionOrMethod() && NewVD->isExternC(Context) &&
@@ -2342,17 +2349,25 @@
     // storage-class specifier or with the storage-class specifier "static",
     // constitutes a tentative definition. Note: A tentative definition with
     // external linkage is valid (C99 6.2.2p5).
-    if (isTentativeDefinition(IDecl)) {
-      if (T->isIncompleteArrayType()) {
-        // C99 6.9.2 (p2, p5): Implicit initialization causes an incomplete
-        // array to be completed. Don't issue a diagnostic.
-      } else if (!IDecl->isInvalidDecl() &&
-                 RequireCompleteType(IDecl->getLocation(), T,
-                                        diag::err_typecheck_decl_incomplete_type))
+    if (!getLangOptions().CPlusPlus && isTentativeDefinition(IDecl)) {
+      QualType CheckType = T;
+      unsigned DiagID = diag::err_typecheck_decl_incomplete_type;
+
+      const IncompleteArrayType *ArrayT = Context.getAsIncompleteArrayType(T);
+      if (ArrayT) {
+        CheckType = ArrayT->getElementType();
+        DiagID = diag::err_illegal_decl_array_incomplete_type;
+      }
+
+      if (IDecl->isInvalidDecl()) {
+        // Do nothing with invalid declarations
+      } else if ((ArrayT || IDecl->getStorageClass() == VarDecl::Static) &&
+                 RequireCompleteType(IDecl->getLocation(), CheckType, DiagID)) {
         // C99 6.9.2p3: If the declaration of an identifier for an object is
         // a tentative definition and has internal linkage (C99 6.2.2p3), the  
         // declared type shall not be an incomplete type.
         IDecl->setInvalidDecl();
+      }
     }
     if (IDecl->isFileVarDecl())
       CheckForFileScopedRedefinitions(S, IDecl);
@@ -3243,9 +3258,8 @@
   // C++ 9.6p3: A bit-field shall have integral or enumeration type.
   if (!FieldTy->isIntegralType()) {
     // Handle incomplete types with specific error.
-    if (FieldTy->isIncompleteType())
-      return Diag(FieldLoc, diag::err_field_incomplete)
-        << FieldTy << BitWidth->getSourceRange();
+    if (RequireCompleteType(FieldLoc, FieldTy, diag::err_field_incomplete))
+      return true;
     return Diag(FieldLoc, diag::err_not_integral_type_bitfield)
       << FieldName << BitWidth->getSourceRange();
   }

Modified: cfe/trunk/test/Sema/bitfield.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/bitfield.c?rev=66584&r1=66583&r2=66584&view=diff

==============================================================================
--- cfe/trunk/test/Sema/bitfield.c (original)
+++ cfe/trunk/test/Sema/bitfield.c Tue Mar 10 16:58:27 2009
@@ -1,5 +1,5 @@
 // RUN: clang %s -fsyntax-only -verify 
-enum e0;
+enum e0; // expected-note{{forward declaration of 'enum e0'}}
 
 struct a {
   int a : -1; // expected-error{{bit-field 'a' has negative width}}

Modified: cfe/trunk/test/Sema/enum.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/enum.c?rev=66584&r1=66583&r2=66584&view=diff

==============================================================================
--- cfe/trunk/test/Sema/enum.c (original)
+++ cfe/trunk/test/Sema/enum.c Tue Mar 10 16:58:27 2009
@@ -21,13 +21,11 @@
   return sizeof(enum e) ;
 }
 
-enum gccForwardEnumExtension ve; // expected-error {{variable has incomplete type 'enum gccForwardEnumExtension'}} \
-                                 // expected-warning{{ISO C forbids forward references to 'enum' types}} \
-                                 // expected-note{{forward declaration of 'enum gccForwardEnumExtension'}}
+enum gccForwardEnumExtension ve; // expected-warning{{ISO C forbids forward references to 'enum' types}}
 
 int test2(int i)
 {
-  ve + i;
+  ve + i; // expected-error{{invalid operands to binary expression}}
 }
 
 // PR2020

Modified: cfe/trunk/test/Sema/incomplete-decl.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/incomplete-decl.c?rev=66584&r1=66583&r2=66584&view=diff

==============================================================================
--- cfe/trunk/test/Sema/incomplete-decl.c (original)
+++ cfe/trunk/test/Sema/incomplete-decl.c Tue Mar 10 16:58:27 2009
@@ -1,9 +1,9 @@
 // RUN: clang -fsyntax-only -verify %s
 
-struct foo; // expected-note 4 {{forward declaration of 'struct foo'}}
+struct foo; // expected-note 3 {{forward declaration of 'struct foo'}}
 
 void b;  // expected-error {{variable has incomplete type 'void'}}
-struct foo f; // expected-error {{variable has incomplete type 'struct foo'}}
+struct foo f; // // FIXME: error because 'struct foo' is never defined
 
 static void c; // expected-error {{variable has incomplete type 'void'}}
 static struct foo g;  // expected-error {{variable has incomplete type 'struct foo'}}

Modified: cfe/trunk/test/Sema/tentative-decls.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/tentative-decls.c?rev=66584&r1=66583&r2=66584&view=diff

==============================================================================
--- cfe/trunk/test/Sema/tentative-decls.c (original)
+++ cfe/trunk/test/Sema/tentative-decls.c Tue Mar 10 16:58:27 2009
@@ -1,5 +1,12 @@
 // RUN: clang %s -fsyntax-only -verify
 
+// PR3310
+struct a x1; // expected-note 2{{forward declaration of 'struct a'}}
+static struct a x2; // expected-error{{variable has incomplete type 'struct a'}}
+struct a x3[10]; // expected-error{{array has incomplete element type 'struct a'}}
+struct a {int x;};
+struct b x4; // FIXME: error because 'struct b' is never defined
+
 const int a [1] = {1};
 extern const int a[];
 
@@ -43,3 +50,4 @@
   extern double *p;
   extern double *p;
 }
+





More information about the cfe-commits mailing list