diff options
| author | Eli Friedman <eli.friedman@gmail.com> | 2008-08-25 20:46:57 +0000 |
|---|---|---|
| committer | Eli Friedman <eli.friedman@gmail.com> | 2008-08-25 20:46:57 +0000 |
| commit | 0a2ba3f10b47a1bd64ede213d03d8a74431fb8b1 (patch) | |
| tree | f36d43b48ad49086f4e05583940424f52c2b4a8a /clang | |
| parent | f2e69888c578052cea81990c5526c73bb411dea1 (diff) | |
| download | bcm5719-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')
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 44 | ||||
| -rw-r--r-- | clang/test/Sema/const-ptr-int-ptr-cast.c | 3 |
2 files changed, 26 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()); diff --git a/clang/test/Sema/const-ptr-int-ptr-cast.c b/clang/test/Sema/const-ptr-int-ptr-cast.c new file mode 100644 index 00000000000..6bf44b05b35 --- /dev/null +++ b/clang/test/Sema/const-ptr-int-ptr-cast.c @@ -0,0 +1,3 @@ +// RUN: clang -fsyntax-only -verify %s + +char *a = (void*)(unsigned long long)(void*)&a; |

