diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-10-24 18:26:35 +0000 | 
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-10-24 18:26:35 +0000 | 
| commit | c3e31e7bb2765aa2e1824ab10a551e61dd7c87a2 (patch) | |
| tree | 589a363ad1ad9787b19c16454a6e286bf8208281 | |
| parent | e594034f1ffedbd7c018f7454c70ae6d60b84ebb (diff) | |
| download | bcm5719-llvm-c3e31e7bb2765aa2e1824ab10a551e61dd7c87a2.tar.gz bcm5719-llvm-c3e31e7bb2765aa2e1824ab10a551e61dd7c87a2.zip  | |
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.
llvm-svn: 142832
| -rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 7 | ||||
| -rw-r--r-- | clang/test/Sema/i-c-e.c | 3 | ||||
| -rw-r--r-- | clang/test/SemaCXX/i-c-e-cxx.cpp | 13 | 
3 files changed, 16 insertions, 7 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 5d34aff7a63..3bf9eb516f7 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/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<CastExpr>(E)->getSubExpr(); +    if (E->getStmtClass() != Expr::ImplicitCastExprClass && +        isa<FloatingLiteral>(SubExpr->IgnoreParenImpCasts())) +      return NoDiag();      switch (cast<CastExpr>(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<FloatingLiteral>(SubExpr->IgnoreParens())) -        return NoDiag();        return ICEDiag(2, E->getLocStart());      }    } diff --git a/clang/test/Sema/i-c-e.c b/clang/test/Sema/i-c-e.c index 9b50916f85f..cb9dcabafce 100644 --- a/clang/test/Sema/i-c-e.c +++ b/clang/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/clang/test/SemaCXX/i-c-e-cxx.cpp b/clang/test/SemaCXX/i-c-e-cxx.cpp index 4d02ca8f174..ba60054f2e0 100644 --- a/clang/test/SemaCXX/i-c-e-cxx.cpp +++ b/clang/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<const char&>(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<const volatile char&>((((PR8836*)0)->a))]; +struct PR8836 { char _; long long a; }; // expected-warning {{long long}} +int PR8836test[(__typeof(sizeof(int)))&reinterpret_cast<const volatile char&>((((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<int>(1.0); +int arr2[castfloat]; // ok  | 

