]> granicus.if.org Git - clang/commitdiff
Always try to fold array sizes, and warn if we could fold something that isn't an...
authorAnders Carlsson <andersca@mac.com>
Fri, 20 Feb 2009 18:53:20 +0000 (18:53 +0000)
committerAnders Carlsson <andersca@mac.com>
Fri, 20 Feb 2009 18:53:20 +0000 (18:53 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65140 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
lib/Sema/SemaType.cpp
test/Sema/typedef-variable-type.c

index 08b5a8c2ab1d9368d91257c5a2ceb45f30e85d48..b69453d44730b77fdf189ae428aa6c04f3ae27a8 100644 (file)
@@ -3398,36 +3398,6 @@ void Sema::ActOnTagFinishDefinition(Scope *S, DeclTy *TagD) {
   Consumer.HandleTagDeclDefinition(Tag);
 }
 
-/// TryToFixInvalidVariablyModifiedType - Helper method to turn variable array
-/// types into constant array types in certain situations which would otherwise
-/// be errors (for GCC compatibility).
-static QualType TryToFixInvalidVariablyModifiedType(QualType T,
-                                                    ASTContext &Context,
-                                                    bool &SizeIsNegative) {
-  // This method tries to turn a variable array into a constant
-  // array even when the size isn't an ICE.  This is necessary
-  // for compatibility with code that depends on gcc's buggy
-  // constant expression folding, like struct {char x[(int)(char*)2];}
-  SizeIsNegative = false;
-  
-  const VariableArrayType* VLATy = dyn_cast<VariableArrayType>(T);
-  if (!VLATy) return QualType();
-  
-  Expr::EvalResult EvalResult;
-  if (!VLATy->getSizeExpr() ||
-      !VLATy->getSizeExpr()->Evaluate(EvalResult, Context))
-    return QualType();
-    
-  assert(EvalResult.Val.isInt() && "Size expressions must be integers!");
-  llvm::APSInt &Res = EvalResult.Val.getInt();
-  if (Res >= llvm::APSInt(Res.getBitWidth(), Res.isUnsigned()))
-    return Context.getConstantArrayType(VLATy->getElementType(),
-                                        Res, ArrayType::Normal, 0);
-
-  SizeIsNegative = true;
-  return QualType();
-}
-
 bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, 
                           QualType FieldTy, const Expr *BitWidth) {
   // FIXME: 6.7.2.1p4 - verify the field type.
@@ -3473,20 +3443,9 @@ Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *TagD,
   // C99 6.7.2.1p8: A member of a structure or union may have any type other
   // than a variably modified type.
   if (T->isVariablyModifiedType()) {
-    bool SizeIsNegative;
-    QualType FixedTy = TryToFixInvalidVariablyModifiedType(T, Context,
-                                                           SizeIsNegative);
-    if (!FixedTy.isNull()) {
-      Diag(Loc, diag::warn_illegal_constant_array_size);
-      T = FixedTy;
-    } else {
-      if (SizeIsNegative)
-        Diag(Loc, diag::err_typecheck_negative_array_size);
-      else
-        Diag(Loc, diag::err_typecheck_field_variable_size);
-      T = Context.IntTy;
-      InvalidDecl = true;
-    }
+    Diag(Loc, diag::err_typecheck_field_variable_size);
+    T = Context.IntTy;
+    InvalidDecl = true;
   }
   
   if (BitWidth) {
index 252cd2d533cee1c63a89d120ae322565837cf30f..8727fbcd8cc5ff3d811f66510b05d55719fa0b93 100644 (file)
@@ -423,17 +423,26 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) {
         ArraySize->Destroy(Context);
         ATI.NumElts = ArraySize = 0;
       }
-      llvm::APSInt ConstVal(32);
+      Expr::EvalResult Result;
       if (!ArraySize) {
         T = Context.getIncompleteArrayType(T, ASM, ATI.TypeQuals);
       } else if (ArraySize->isValueDependent()) {
         T = Context.getDependentSizedArrayType(T, ArraySize, ASM, ATI.TypeQuals);
-      } else if (!ArraySize->isIntegerConstantExpr(ConstVal, Context) ||
+      } else if (!ArraySize->Evaluate(Result, Context) || 
                  !T->isConstantSizeType()) {
         // Per C99, a variable array is an array with either a non-constant
         // size or an element type that has a non-constant-size
         T = Context.getVariableArrayType(T, ArraySize, ASM, ATI.TypeQuals);
       } else {
+        const llvm::APSInt& ConstVal = Result.Val.getInt();
+        
+        // FIXME: We should really use Result.Diag here - which is supposed
+        // to be nonzero if we have a foldable expression that is not an ICE
+        // but for now we'll just warn if the array size is not an ICE.
+        if (!ArraySize->isIntegerConstantExpr(Context))
+          Diag(ArraySize->getLocStart(), 
+               diag::warn_illegal_constant_array_size);
+
         // C99 6.7.5.2p1: If the expression is a constant expression, it shall
         // have a value greater than zero.
         if (ConstVal.isSigned()) {
@@ -444,7 +453,8 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) {
             D.setInvalidType(true);
           } else if (ConstVal == 0) {
             // GCC accepts zero sized static arrays.
-            Diag(ArraySize->getLocStart(), diag::ext_typecheck_zero_array_size)
+            Diag(ArraySize->getLocStart(),
+                 diag::ext_typecheck_zero_array_size)
               << ArraySize->getSourceRange();
           }
         } 
index e982637feb36333d09ba1c52b7e6780ddac5bf12..703792fcdc56314cd3897950fee2766b54bedf49 100644 (file)
@@ -1,3 +1,3 @@
 // RUN: clang %s -verify -fsyntax-only -pedantic
 
-typedef int (*a)[!.0]; // expected-error{{variably modified type declaration not allowed at file scope}}
+typedef int (*a)[!.0]; // expected-warning{{size of static array must be an integer constant expression}}