[cfe-commits] r39295 - in /cfe/cfe/trunk: AST/SemaDecl.cpp Sema/SemaDecl.cpp include/clang/Basic/DiagnosticKinds.def

sabre at cs.uiuc.edu sabre at cs.uiuc.edu
Wed Jul 11 09:42:38 PDT 2007


Author: sabre
Date: Wed Jul 11 11:42:37 2007
New Revision: 39295

URL: http://llvm.org/viewvc/llvm-project?rev=39295&view=rev
Log:
Compile:
struct bork {
  int X[];
};

struct bink {
  struct bink a;
  int X[];  // ok.
};

to:
t.c:3:7: error: flexible array 'X' not allowed in otherwise empty struct
  int X[];
      ^
t.c:7:15: error: field 'a' has incomplete type
  struct bink a;
              ^

Modified:
    cfe/cfe/trunk/AST/SemaDecl.cpp
    cfe/cfe/trunk/Sema/SemaDecl.cpp
    cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def

Modified: cfe/cfe/trunk/AST/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaDecl.cpp?rev=39295&r1=39294&r2=39295&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/AST/SemaDecl.cpp Wed Jul 11 11:42:37 2007
@@ -392,10 +392,8 @@
     return;
   }
 
-  // Okay, we successfully defined 'Record'.
-  Record->setDefinition(true);
-  
   // Verify that all the fields are okay.
+  unsigned NumNamedMembers = 0;
   for (unsigned i = 0; i != NumFields; ++i) {
     FieldDecl *FD = cast_or_null<FieldDecl>(static_cast<Decl*>(Fields[i]));
     if (!FD) continue;  // Already issued a diagnostic.
@@ -404,16 +402,37 @@
     if (isa<FunctionType>(FD->getType())) {
       Diag(FD->getLocation(), diag::err_field_declared_as_function,
            FD->getName());
+      delete FD;
       continue;
     }
 
-    // C99 6.7.2.1p2 - A field may not be an incomplete type  except...
+    // C99 6.7.2.1p2 - A field may not be an incomplete type except...
     if (FD->getType()->isIncompleteType()) {
+      if (i != NumFields-1 ||                   // ... that the last member ...
+          Record->getKind() != Decl::Struct ||  // ... of a structure ...
+          !isa<ArrayType>(FD->getType())) {//... may have incomplete array type.
+        Diag(FD->getLocation(), diag::err_field_incomplete, FD->getName());
+        delete FD;
+        continue;
+      }
+      if (NumNamedMembers < 1) {           //... with more than named member ...
+        Diag(FD->getLocation(), diag::err_flexible_array_empty_struct,
+             FD->getName());
+        delete FD;
+        continue;
+      }
+    }
       
-      // 
       
-    }
+    // Keep track of the number of named members.
+    if (FD->getIdentifier())
+      ++NumNamedMembers;
   }
+ 
+  
+  // Okay, we successfully defined 'Record'.
+  Record->setDefinition(true);
+  
   
 }
 

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

==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:42:37 2007
@@ -392,10 +392,8 @@
     return;
   }
 
-  // Okay, we successfully defined 'Record'.
-  Record->setDefinition(true);
-  
   // Verify that all the fields are okay.
+  unsigned NumNamedMembers = 0;
   for (unsigned i = 0; i != NumFields; ++i) {
     FieldDecl *FD = cast_or_null<FieldDecl>(static_cast<Decl*>(Fields[i]));
     if (!FD) continue;  // Already issued a diagnostic.
@@ -404,16 +402,37 @@
     if (isa<FunctionType>(FD->getType())) {
       Diag(FD->getLocation(), diag::err_field_declared_as_function,
            FD->getName());
+      delete FD;
       continue;
     }
 
-    // C99 6.7.2.1p2 - A field may not be an incomplete type  except...
+    // C99 6.7.2.1p2 - A field may not be an incomplete type except...
     if (FD->getType()->isIncompleteType()) {
+      if (i != NumFields-1 ||                   // ... that the last member ...
+          Record->getKind() != Decl::Struct ||  // ... of a structure ...
+          !isa<ArrayType>(FD->getType())) {//... may have incomplete array type.
+        Diag(FD->getLocation(), diag::err_field_incomplete, FD->getName());
+        delete FD;
+        continue;
+      }
+      if (NumNamedMembers < 1) {           //... with more than named member ...
+        Diag(FD->getLocation(), diag::err_flexible_array_empty_struct,
+             FD->getName());
+        delete FD;
+        continue;
+      }
+    }
       
-      // 
       
-    }
+    // Keep track of the number of named members.
+    if (FD->getIdentifier())
+      ++NumNamedMembers;
   }
+ 
+  
+  // Okay, we successfully defined 'Record'.
+  Record->setDefinition(true);
+  
   
 }
 

Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39295&r1=39294&r2=39295&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:42:37 2007
@@ -439,6 +439,10 @@
 
 DIAG(err_field_declared_as_function, ERROR,
      "field '%s' declared as a function")
+DIAG(err_field_incomplete, ERROR,
+     "field '%s' has incomplete type")
+DIAG(err_flexible_array_empty_struct, ERROR,
+     "flexible array '%s' not allowed in otherwise empty struct")
 
 // Expressions.
 DIAG(ext_sizeof_function_type, EXTENSION,





More information about the cfe-commits mailing list