[cfe-commits] r65140 - in /cfe/trunk: lib/Sema/SemaDecl.cpp lib/Sema/SemaType.cpp test/Sema/typedef-variable-type.c
Anders Carlsson
andersca at mac.com
Fri Feb 20 10:53:20 PST 2009
Author: andersca
Date: Fri Feb 20 12:53:20 2009
New Revision: 65140
URL: http://llvm.org/viewvc/llvm-project?rev=65140&view=rev
Log:
Always try to fold array sizes, and warn if we could fold something that isn't an ICE. This makes us compatible with GCC.
Modified:
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/test/Sema/typedef-variable-type.c
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=65140&r1=65139&r2=65140&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Feb 20 12:53:20 2009
@@ -3398,36 +3398,6 @@
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 @@
// 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) {
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=65140&r1=65139&r2=65140&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Fri Feb 20 12:53:20 2009
@@ -423,17 +423,26 @@
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 @@
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();
}
}
Modified: cfe/trunk/test/Sema/typedef-variable-type.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/typedef-variable-type.c?rev=65140&r1=65139&r2=65140&view=diff
==============================================================================
--- cfe/trunk/test/Sema/typedef-variable-type.c (original)
+++ cfe/trunk/test/Sema/typedef-variable-type.c Fri Feb 20 12:53:20 2009
@@ -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}}
More information about the cfe-commits
mailing list