summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2008-08-25 20:46:57 +0000
committerEli Friedman <eli.friedman@gmail.com>2008-08-25 20:46:57 +0000
commit0a2ba3f10b47a1bd64ede213d03d8a74431fb8b1 (patch)
treef36d43b48ad49086f4e05583940424f52c2b4a8a /clang/lib
parentf2e69888c578052cea81990c5526c73bb411dea1 (diff)
downloadbcm5719-llvm-0a2ba3f10b47a1bd64ede213d03d8a74431fb8b1.tar.gz
bcm5719-llvm-0a2ba3f10b47a1bd64ede213d03d8a74431fb8b1.zip
Fix for PR2720; be a little bit more permissive in initializers for
casting pointers to integers. Eventually, we should check whether we can evaluate an expression using Expr::tryEvaluate, and this codepath should be tightened to only handle standard-compliant cases. llvm-svn: 55331
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp44
1 files changed, 23 insertions, 21 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index d8d77b0d542..066969ce9e8 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -927,35 +927,37 @@ bool Sema::CheckAddressConstantExpression(const Expr* Init) {
return CheckAddressConstantExpression(PExp) ||
CheckArithmeticConstantExpression(IExp);
}
- case Expr::ImplicitCastExprClass: {
- const Expr* SubExpr = cast<ImplicitCastExpr>(Init)->getSubExpr();
-
- // Check for implicit promotion
- if (SubExpr->getType()->isFunctionType() ||
- SubExpr->getType()->isArrayType())
- return CheckAddressConstantExpressionLValue(SubExpr);
-
- // Check for pointer->pointer cast
- if (SubExpr->getType()->isPointerType())
- return CheckAddressConstantExpression(SubExpr);
-
- if (SubExpr->getType()->isArithmeticType())
- return CheckArithmeticConstantExpression(SubExpr);
-
- Diag(Init->getExprLoc(),
- diag::err_init_element_not_constant, Init->getSourceRange());
- return true;
- }
+ case Expr::ImplicitCastExprClass:
case Expr::ExplicitCastExprClass: {
const Expr* SubExpr = cast<CastExpr>(Init)->getSubExpr();
+ if (Init->getStmtClass() == Expr::ImplicitCastExprClass) {
+ // Check for implicit promotion
+ if (SubExpr->getType()->isFunctionType() ||
+ SubExpr->getType()->isArrayType())
+ return CheckAddressConstantExpressionLValue(SubExpr);
+ }
// Check for pointer->pointer cast
if (SubExpr->getType()->isPointerType())
return CheckAddressConstantExpression(SubExpr);
- // FIXME: Should we pedwarn for (int*)(0+0)?
- if (SubExpr->getType()->isArithmeticType())
+ if (SubExpr->getType()->isIntegralType()) {
+ // Check for the special-case of a pointer->int->pointer cast;
+ // this isn't standard, but some code requires it. See
+ // PR2720 for an example.
+ if (const CastExpr* SubCast = dyn_cast<CastExpr>(SubExpr)) {
+ if (SubCast->getSubExpr()->getType()->isPointerType()) {
+ unsigned IntWidth = Context.getIntWidth(SubCast->getType());
+ unsigned PointerWidth = Context.getTypeSize(Context.VoidPtrTy);
+ if (IntWidth >= PointerWidth) {
+ return CheckAddressConstantExpression(SubCast->getSubExpr());
+ }
+ }
+ }
+ }
+ if (SubExpr->getType()->isArithmeticType()) {
return CheckArithmeticConstantExpression(SubExpr);
+ }
Diag(Init->getExprLoc(),
diag::err_init_element_not_constant, Init->getSourceRange());
OpenPOWER on IntegriCloud