[cfe-commits] r41624 - in /cfe/trunk: Sema/SemaDecl.cpp Sema/SemaType.cpp include/clang/Basic/DiagnosticKinds.def test/Sema/array-constraint.c

Steve Naroff snaroff at apple.com
Thu Aug 30 15:35:45 PDT 2007


Author: snaroff
Date: Thu Aug 30 17:35:45 2007
New Revision: 41624

URL: http://llvm.org/viewvc/llvm-project?rev=41624&view=rev
Log:

Final phase of array cleanup (for now), removing a FIXME from yesterday.

Moved several array constraints checks from Sema::VerifyConstantArrayType() to
Sema::GetTypeForDeclarator(). VerifyConstantArrayType() is now very simple, and
could be removed eventually.

Now, we get the following (correct) messages for BlockVarDecls:-)

[dylan:~/llvm/tools/clang] admin% ../../Debug/bin/clang x.c -pedantic
x.c:4:20: error: size of array has non-integer type 'float'
  int size_not_int[f];
                   ^
x.c:5:21: error: array size is negative
  int negative_size[1-2];
                    ^~~
x.c:6:17: warning: zero size arrays are an extension
  int zero_size[0];
                ^
3 diagnostics generated.


Modified:
    cfe/trunk/Sema/SemaDecl.cpp
    cfe/trunk/Sema/SemaType.cpp
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/trunk/test/Sema/array-constraint.c

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

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Thu Aug 30 17:35:45 2007
@@ -25,59 +25,22 @@
 #include "llvm/ADT/SmallSet.h"
 using namespace clang;
 
-// C99: 6.7.5p3: Used by ParseDeclarator/ParseField to make sure we have
-// a constant expression of type int with a value greater than zero.
+// C99 6.7.2.1p8: Used by ParseDeclarator/ParseField to make sure we have
+// a constant expression. We return true if we don't have a ConstantArrayType. 
 bool Sema::VerifyConstantArrayType(const ArrayType *Array,
                                    SourceLocation DeclLoc) { 
   if (const VariableArrayType *VLA = dyn_cast<VariableArrayType>(Array)) {
     Expr *Size = VLA->getSizeExpr();
-    if (Size == 0)
-      return false; // incomplete type.
-  
-    if (!Size->getType()->isIntegerType()) {
-      Diag(Size->getLocStart(), diag::err_array_size_non_int, 
-           Size->getType().getAsString(), Size->getSourceRange());
-      return false;
-    }
-    // FIXME: I don't think this is needed. It remains to keep test
-    // builtin_classify_type() happy...will revisit soon (today is 8/29/07:-)
-    SourceLocation Loc;
-    llvm::APSInt SizeVal(32);
-    if (!Size->isIntegerConstantExpr(SizeVal, Context, &Loc)) {
+    if (Size) {  
       // FIXME: This emits the diagnostic to enforce 6.7.2.1p8, but the message
       // is wrong.  It is also wrong for static variables.
       // FIXME: This is also wrong for:
       // int sub1(int i, char *pi) { typedef int foo[i];
       // struct bar {foo f1; int f2:3; int f3:4} *p; }
       Diag(DeclLoc, diag::err_typecheck_illegal_vla, Size->getSourceRange());
-      return false;
     }
     return true;
   }
-  const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(Array);  
-
-  assert(CAT && "Sema::VerifyConstantArrayType(): Illegal array type");
-  
-  llvm::APSInt SizeVal(32);
-  SizeVal = CAT->getSize();
-
-  // We have a constant expression with an integer type, now make sure 
-  // value greater than zero (C99 6.7.5.2p1).
-  
-  // FIXME: This check isn't specific to static VLAs, this should be moved
-  // elsewhere or replicated.  'int X[-1];' inside a function should emit an
-  // error.
-  if (SizeVal.isSigned()) {
-    llvm::APSInt Zero(SizeVal.getBitWidth());
-    Zero.setIsUnsigned(false);
-    if (SizeVal < Zero) {
-      Diag(DeclLoc, diag::err_typecheck_negative_array_size);
-      return true;
-    } else if (SizeVal == 0) {
-      // GCC accepts zero sized static arrays.
-      Diag(DeclLoc, diag::err_typecheck_zero_array_size);
-    }
-  }
   return false;
 }
 

Modified: cfe/trunk/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaType.cpp?rev=41624&r1=41623&r2=41624&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaType.cpp (original)
+++ cfe/trunk/Sema/SemaType.cpp Thu Aug 30 17:35:45 2007
@@ -202,13 +202,33 @@
           D.setInvalidType(true);
         }
       }
+      // C99 6.7.5.2p1: The size expression shall have integer type.
+      if (ArraySize && !ArraySize->getType()->isIntegerType()) {
+        Diag(ArraySize->getLocStart(), diag::err_array_size_non_int, 
+             ArraySize->getType().getAsString(), ArraySize->getSourceRange());
+        D.setInvalidType(true);
+      }
       llvm::APSInt ConstVal(32);
       // If no expression was provided, we consider it a VLA.
       if (!ArraySize || !ArraySize->isIntegerConstantExpr(ConstVal, Context))
         T = Context.getVariableArrayType(T, ArraySize, ASM, ATI.TypeQuals);
-      else
+      else {
+        // C99 6.7.5.2p1: If the expression is a constant expression, it shall
+        // have a value greater than zero.
+        if (ConstVal.isSigned()) {
+          if (ConstVal.isNegative()) {
+            Diag(ArraySize->getLocStart(), 
+                 diag::err_typecheck_negative_array_size,
+                 ArraySize->getSourceRange());
+            D.setInvalidType(true);
+          } else if (ConstVal == 0) {
+            // GCC accepts zero sized static arrays.
+            Diag(ArraySize->getLocStart(), diag::ext_typecheck_zero_array_size,
+                 ArraySize->getSourceRange());
+          }
+        } 
         T = Context.getConstantArrayType(T, ConstVal, ASM, ATI.TypeQuals);
-        
+      }
       // If this is not C99, extwarn about VLA's and C99 array size modifiers.
       if (!getLangOptions().C99 && 
           (ASM != ArrayType::Normal ||

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

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Thu Aug 30 17:35:45 2007
@@ -534,7 +534,7 @@
      "variable length array declared outside of any function")
 DIAG(err_typecheck_negative_array_size, ERROR,
      "array size is negative")
-DIAG(err_typecheck_zero_array_size, EXTENSION,
+DIAG(ext_typecheck_zero_array_size, EXTENSION,
      "zero size arrays are an extension")
 DIAG(err_array_size_non_int, ERROR,
      "size of array has non-integer type '%0'")

Modified: cfe/trunk/test/Sema/array-constraint.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/array-constraint.c?rev=41624&r1=41623&r2=41624&view=diff

==============================================================================
--- cfe/trunk/test/Sema/array-constraint.c (original)
+++ cfe/trunk/test/Sema/array-constraint.c Thu Aug 30 17:35:45 2007
@@ -31,3 +31,11 @@
 pfunc xx(int f[](void)) { // expected-error {{'f' declared as array of functions}}
   return f;
 }
+
+void check_size() {
+  float f;
+  int size_not_int[f]; // expected-error {{size of array has non-integer type 'float'}}
+  int negative_size[1-2]; // expected-error{{array size is negative}}
+  int zero_size[0]; // expected-warning{{zero size arrays are an extension}}
+}
+





More information about the cfe-commits mailing list