[cfe-commits] r146371 - in /cfe/trunk: include/clang/Basic/DiagnosticASTKinds.td lib/AST/ExprConstant.cpp test/SemaCXX/constant-expression-cxx11.cpp
Richard Smith
richard-llvm at metafoo.co.uk
Mon Dec 12 04:46:16 PST 2011
Author: rsmith
Date: Mon Dec 12 06:46:16 2011
New Revision: 146371
URL: http://llvm.org/viewvc/llvm-project?rev=146371&view=rev
Log:
Implement C++11 constant expression cast restrictions.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td?rev=146371&r1=146370&r2=146371&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td Mon Dec 12 06:46:16 2011
@@ -12,6 +12,9 @@
//def note_comma_in_ice : Note<
// "C does not permit evaluated commas in an integer constant expression">;
def note_expr_divide_by_zero : Note<"division by zero">;
+def note_constexpr_invalid_cast : Note<
+ "%select{reinterpret_cast|dynamic_cast|reinterpreting cast}0 not allowed "
+ "in a constant expression">;
// inline asm related.
let CategoryName = "Inline Assembly Issue" in {
Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=146371&r1=146370&r2=146371&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Mon Dec 12 06:46:16 2011
@@ -1616,6 +1616,15 @@
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:
@@ -1988,6 +1997,7 @@
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();
@@ -2213,6 +2223,11 @@
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();
@@ -2251,6 +2266,8 @@
return ValueInitialization(E);
case CK_IntegralToPointer: {
+ CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
+
CCValue Value;
if (!EvaluateIntegerOrLValue(SubExpr, Value, Info))
break;
@@ -3826,6 +3843,8 @@
}
case CK_PointerToIntegral: {
+ CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
+
LValue LV;
if (!EvaluatePointer(SubExpr, LV, Info))
return false;
Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=146371&r1=146370&r2=146371&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Mon Dec 12 06:46:16 2011
@@ -1,4 +1,4 @@
-// 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 {
@@ -165,7 +165,7 @@
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
}
@@ -297,6 +297,31 @@
// 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.
@@ -414,7 +439,7 @@
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);
}
@@ -677,7 +702,7 @@
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, "");
More information about the cfe-commits
mailing list