aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2013-04-08 23:24:07 +0000
committerDouglas Gregor <dgregor@apple.com>2013-04-08 23:24:07 +0000
commit484f6fa0bd6b16b64e5c4cb40260f69a3dd52b4a (patch)
treec52fa061595291c7f0cc4c1fc09fdfc77ff70fd6
parent44b2ea97957b553e76e757c1926c3ad1fadbe1b2 (diff)
<rdar://problem/13584715> Converted constant expressions are expected to have integral values.
We were assuming that any expression used as a converted constant expression would either not have a folded constant value or would be an integer, which is not the case for some ill-formed constant expressions. Because converted constant expressions are only used where integral values are expected, we can simply treat this as an error path. If that ever changes, we'll need to widen the interface of Sema::CheckConvertedConstantExpression() anyway. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179068 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaOverload.cpp2
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp16
2 files changed, 17 insertions, 1 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 805fdd8b57..22b2a4a57d 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -5024,7 +5024,7 @@ ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,
Expr::EvalResult Eval;
Eval.Diag = &Notes;
- if (!Result.get()->EvaluateAsRValue(Eval, Context)) {
+ if (!Result.get()->EvaluateAsRValue(Eval, Context) || !Eval.Val.isInt()) {
// The expression can't be folded, so we can't keep it at this position in
// the AST.
Result = ExprError();
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
index cafdd63551..0cef31b6c8 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
@@ -137,3 +137,19 @@ namespace DR1364 {
return kGlobal; // expected-note {{read of non-const}}
}
}
+
+namespace rdar13584715 {
+ typedef __PTRDIFF_TYPE__ ptrdiff_t;
+
+ template<typename T> struct X {
+ static T value() {};
+ };
+
+ void foo(ptrdiff_t id) {
+ switch (id) {
+ case reinterpret_cast<ptrdiff_t>(&X<long>::value): // expected-error{{case value is not a constant expression}} \
+ // expected-note{{reinterpret_cast is not allowed in a constant expression}}
+ break;
+ }
+ }
+}