RetTy VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
{ return StmtVisitorTy::Visit(E->getExpr()); }
+ RetTy VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E) {
+ CCEDiag(E, diag::note_constexpr_invalid_cast) << 0;
+ return static_cast<Derived*>(this)->VisitCastExpr(E);
+ }
+ RetTy VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E) {
+ CCEDiag(E, diag::note_constexpr_invalid_cast) << 1;
+ return static_cast<Derived*>(this)->VisitCastExpr(E);
+ }
+
RetTy VisitBinaryOperator(const BinaryOperator *E) {
switch (E->getOpcode()) {
default:
return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
case CK_LValueBitCast:
+ this->CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
if (!Visit(E->getSubExpr()))
return false;
Result.Designator.setInvalid();
case CK_CPointerToObjCPointerCast:
case CK_BlockPointerToObjCPointerCast:
case CK_AnyPointerToBlockPointerCast:
+ // Bitcasts to cv void* are static_casts, not reinterpret_casts, so are
+ // permitted in constant expressions in C++11. Bitcasts from cv void* are
+ // also static_casts, but we disallow them as a resolution to DR1312.
+ if (!E->getType()->isVoidPointerType())
+ CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
if (!Visit(SubExpr))
return false;
Result.Designator.setInvalid();
return ValueInitialization(E);
case CK_IntegralToPointer: {
+ CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
+
CCValue Value;
if (!EvaluateIntegerOrLValue(SubExpr, Value, Info))
break;
}
case CK_PointerToIntegral: {
+ CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
+
LValue LV;
if (!EvaluatePointer(SubExpr, LV, Info))
return false;
-// RUN: %clang_cc1 -triple i686-linux -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -triple i686-linux -fsyntax-only -verify -std=c++11 -pedantic %s -Wno-comment
namespace StaticAssertFoldTest {
constexpr int f() { return 1; }
typedef double (*DoubleFn)();
typedef int (*IntFn)();
- int a[(int)DoubleFn(f)()]; // expected-error {{variable length array}}
+ int a[(int)DoubleFn(f)()]; // expected-error {{variable length array}} expected-warning{{extension}}
int b[(int)IntFn(f)()]; // ok
}
// test elsewhere.
constexpr bool dyncast = sptr == dynamic_cast<S*>(sptr);
+struct Str {
+ // FIXME: In C++ mode, we should say 'integral' not 'integer'
+ int a : dynamic_cast<S*>(sptr) == dynamic_cast<S*>(sptr); // \
+ expected-warning {{not integer constant expression}} \
+ expected-note {{dynamic_cast not allowed in a constant expression}}
+ int b : reinterpret_cast<S*>(sptr) == reinterpret_cast<S*>(sptr); // \
+ expected-warning {{not integer constant expression}} \
+ expected-note {{reinterpret_cast not allowed in a constant expression}}
+ int c : (S*)(long)(sptr) == (S*)(long)(sptr); // \
+ expected-warning {{not integer constant expression}} \
+ expected-note {{reinterpreting cast not allowed in a constant expression}}
+ int d : (S*)(42) == (S*)(42); // \
+ expected-warning {{not integer constant expression}} \
+ expected-note {{reinterpreting cast not allowed in a constant expression}}
+ int e : (Str*)(sptr) == (Str*)(sptr); // \
+ expected-warning {{not integer constant expression}} \
+ expected-note {{reinterpreting cast not allowed in a constant expression}}
+ int f : &(Str&)(*sptr) == &(Str&)(*sptr); // \
+ expected-warning {{not integer constant expression}} \
+ expected-note {{reinterpreting cast not allowed in a constant expression}}
+ int g : (S*)(void*)(sptr) == sptr; // \
+ expected-warning {{not integer constant expression}} \
+ expected-note {{reinterpreting cast not allowed in a constant expression}}
+};
+
extern char externalvar[];
// FIXME: This is not a constant expression; check we reject this and move this
// test elsewhere.
static_assert(**(**(zs + 1) + 1) == 11, "");
static_assert(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][-1] + 1) == 11, "");
-constexpr int arr[40] = { 1, 2, 3, [8] = 4 };
+constexpr int arr[40] = { 1, 2, 3, [8] = 4 }; // expected-warning {{extension}}
constexpr int SumNonzero(const int *p) {
return *p + (*p ? SumNonzero(p+1) : 0);
}
int b;
};
-constexpr U u[4] = { { .a = 0 }, { .b = 1 }, { .a = 2 }, { .b = 3 } };
+constexpr U u[4] = { { .a = 0 }, { .b = 1 }, { .a = 2 }, { .b = 3 } }; // expected-warning 4{{extension}}
static_assert(u[0].a == 0, "");
static_assert(u[0].b, ""); // expected-error {{constant expression}}
static_assert(u[1].b == 1, "");