From: Richard Smith Date: Mon, 24 Oct 2011 18:26:35 +0000 (+0000) Subject: In accordance with the C89, C99 and C++98 standards, ICEs can only contain X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=32cb47174304bc7ec11478b9497c4e10f48273d9;p=clang In accordance with the C89, C99 and C++98 standards, ICEs can only contain floating-point literals if they are the immediate operands of casts. ImplicitCastExpr is not a cast in the language-standards sense. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142832 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 5d34aff7a6..3bf9eb516f 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -3114,9 +3114,12 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { case Expr::CXXFunctionalCastExprClass: case Expr::CXXStaticCastExprClass: case Expr::CXXReinterpretCastExprClass: - case Expr::CXXConstCastExprClass: + case Expr::CXXConstCastExprClass: case Expr::ObjCBridgedCastExprClass: { const Expr *SubExpr = cast(E)->getSubExpr(); + if (E->getStmtClass() != Expr::ImplicitCastExprClass && + isa(SubExpr->IgnoreParenImpCasts())) + return NoDiag(); switch (cast(E)->getCastKind()) { case CK_LValueToRValue: case CK_NoOp: @@ -3124,8 +3127,6 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { case CK_IntegralCast: return CheckICE(SubExpr, Ctx); default: - if (isa(SubExpr->IgnoreParens())) - return NoDiag(); return ICEDiag(2, E->getLocStart()); } } diff --git a/test/Sema/i-c-e.c b/test/Sema/i-c-e.c index 9b50916f85..cb9dcabafc 100644 --- a/test/Sema/i-c-e.c +++ b/test/Sema/i-c-e.c @@ -11,6 +11,9 @@ char w[__builtin_constant_p(expr) ? expr : 1]; char v[sizeof(__builtin_constant_p(0)) == sizeof(int) ? 1 : -1]; +int implicitConversion = 1.0; +char floatArith[(int)(1.0+2.0)]; // expected-warning {{must be an integer constant expression}} + // __builtin_constant_p as the condition of ?: allows arbitrary foldable // constants to be transmogrified into i-c-e's. char b[__builtin_constant_p((int)(1.0+2.0)) ? (int)(1.0+2.0) : -1]; diff --git a/test/SemaCXX/i-c-e-cxx.cpp b/test/SemaCXX/i-c-e-cxx.cpp index 4d02ca8f17..ba60054f2e 100644 --- a/test/SemaCXX/i-c-e-cxx.cpp +++ b/test/SemaCXX/i-c-e-cxx.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s // C++-specific tests for integral constant expressions. @@ -48,7 +48,7 @@ void pr6373(const unsigned x = 0) { namespace rdar9204520 { struct A { - static const int B = int(0.75 * 1000 * 1000); + static const int B = int(0.75 * 1000 * 1000); // expected-warning {{not a constant expression, accepted as an extension}} }; int foo() { return A::B; } @@ -59,5 +59,10 @@ const int x = 10; int* y = reinterpret_cast(x); // expected-error {{cannot initialize}} // This isn't an integral constant expression, but make sure it folds anyway. -struct PR8836 { char _; long long a; }; -int PR8836test[(__typeof(sizeof(int)))&reinterpret_cast((((PR8836*)0)->a))]; +struct PR8836 { char _; long long a; }; // expected-warning {{long long}} +int PR8836test[(__typeof(sizeof(int)))&reinterpret_cast((((PR8836*)0)->a))]; // expected-warning {{folded to constant array as an extension}} + +const int nonconst = 1.0; +int arr[nonconst]; // expected-warning {{folded to constant array as an extension}} +const int castfloat = static_cast(1.0); +int arr2[castfloat]; // ok