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.
// 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) {
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()) {
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();
}
}