[cfe-commits] r76451 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/Sema/incomplete-decl.c test/Sema/tentative-decls.c

Douglas Gregor dgregor at apple.com
Mon Jul 20 11:47:00 PDT 2009


Author: dgregor
Date: Mon Jul 20 13:46:59 2009
New Revision: 76451

URL: http://llvm.org/viewvc/llvm-project?rev=76451&view=rev
Log:
Improve GCC compatibility by allowing static tentative definitions of
incomplete type (with a warning), from Enea Zaffanella!

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/Sema/incomplete-decl.c
    cfe/trunk/test/Sema/tentative-decls.c

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=76451&r1=76450&r2=76451&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Jul 20 13:46:59 2009
@@ -1206,6 +1206,8 @@
   "arithmetic on pointer to void type">;
 def err_typecheck_decl_incomplete_type : Error<
   "variable has incomplete type %0">;
+def ext_typecheck_decl_incomplete_type : ExtWarn<
+  "tentative definition of variable with internal linkage has incomplete non-array type %0">;
 def err_tentative_def_incomplete_type : Error<
   "tentative definition has type %0 that is never completed">;
 def err_tentative_def_incomplete_type_arr : Error<

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Jul 20 13:46:59 2009
@@ -2899,29 +2899,32 @@
                               diag::err_typecheck_decl_incomplete_type))
         IDecl->setInvalidDecl();
     }
-    // File scope. C99 6.9.2p2: A declaration of an identifier for and 
+    // File scope. C99 6.9.2p2: A declaration of an identifier for an
     // object that has file scope without an initializer, and without a
     // 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 (IDecl->isTentativeDefinition(Context)) {
-      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->isTentativeDefinition(Context) && !IDecl->isInvalidDecl()) {
+      if (const IncompleteArrayType *ArrayT
+          = Context.getAsIncompleteArrayType(T)) {
+        if (RequireCompleteType(IDecl->getLocation(),
+                                ArrayT->getElementType(),
+                                diag::err_illegal_decl_array_incomplete_type))
+          IDecl->setInvalidDecl();
       }
-      
-      if (IDecl->isInvalidDecl()) {
-        // Do nothing with invalid declarations
-      } else if ((ArrayT || IDecl->getStorageClass() == VarDecl::Static) &&
-                 RequireCompleteType(IDecl->getLocation(), CheckType, DiagID)) {
+      else if (IDecl->getStorageClass() == VarDecl::Static) {
         // 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  
+        // a tentative definition and has internal linkage (C99 6.2.2p3), the
         // declared type shall not be an incomplete type.
-        IDecl->setInvalidDecl();
+        // NOTE: code such as the following
+        //     static struct s;
+        //     struct s { int a; };
+        // is accepted by gcc. Hence here we issue a warning instead of
+        // an error and we do not invalidate the static declaration.
+        // NOTE: to avoid multiple warnings, only check the first declaration.
+        if (IDecl->getPreviousDeclaration() == 0)
+          RequireCompleteType(IDecl->getLocation(), T,
+                              diag::ext_typecheck_decl_incomplete_type);
       }
     }
   }

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

==============================================================================
--- cfe/trunk/test/Sema/incomplete-decl.c (original)
+++ cfe/trunk/test/Sema/incomplete-decl.c Mon Jul 20 13:46:59 2009
@@ -1,12 +1,13 @@
 // RUN: clang-cc -fsyntax-only -verify %s
 
-struct foo; // expected-note 4 {{forward declaration of 'struct foo'}}
+struct foo; // expected-note 5 {{forward declaration of 'struct foo'}}
 
 void b;  // expected-error {{variable has incomplete type 'void'}}
 struct foo f; // expected-error{{tentative definition has type 'struct foo' that is never completed}}
 
 static void c; // expected-error {{variable has incomplete type 'void'}}
-static struct foo g;  // expected-error {{variable has incomplete type 'struct foo'}}
+static struct foo g;  // expected-warning {{tentative definition of variable with internal linkage has incomplete non-array type 'struct foo'}} \
+    expected-error{{tentative definition has type 'struct foo' that is never completed}}
 
 extern void d;
 extern struct foo e;

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

==============================================================================
--- cfe/trunk/test/Sema/tentative-decls.c (original)
+++ cfe/trunk/test/Sema/tentative-decls.c Mon Jul 20 13:46:59 2009
@@ -2,7 +2,7 @@
 
 // PR3310
 struct a x1; // expected-note 2{{forward declaration of 'struct a'}}
-static struct a x2; // expected-error{{variable has incomplete type 'struct a'}}
+static struct a x2; // expected-warning{{tentative definition of variable with internal linkage has incomplete non-array type 'struct a'}}
 struct a x3[10]; // expected-error{{array has incomplete element type 'struct a'}}
 struct a {int x;};
 static struct a x2_okay;





More information about the cfe-commits mailing list