summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-07-07 06:00:13 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-07-07 06:00:13 +0000
commit22a5d61b5d3913b5967f5fa43ed4b1764a131a62 (patch)
tree9d49fcb86066603d1c3a4a1171ed3ef77cbdcf83
parent45d099b995acacb165367edc7f3d77eb3cc8407d (diff)
downloadbcm5719-llvm-22a5d61b5d3913b5967f5fa43ed4b1764a131a62.tar.gz
bcm5719-llvm-22a5d61b5d3913b5967f5fa43ed4b1764a131a62.zip
Add an explicit diagnostic for the case where an expression is not a constant
expression because it uses 'this'. Inspired by PR20219 comment#2. llvm-svn: 212433
-rw-r--r--clang/include/clang/Basic/DiagnosticASTKinds.td4
-rw-r--r--clang/lib/AST/ExprConstant.cpp9
-rw-r--r--clang/test/SemaCXX/constant-expression-cxx11.cpp13
3 files changed, 24 insertions, 2 deletions
diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td
index 113e5649052..8d5a1c77233 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -89,6 +89,9 @@ def note_constexpr_call_limit_exceeded : Note<
"constexpr evaluation hit maximum call limit">;
def note_constexpr_step_limit_exceeded : Note<
"constexpr evaluation hit maximum step limit; possible infinite loop?">;
+def note_constexpr_this : Note<
+ "%select{|implicit }0use of 'this' pointer is only allowed within the "
+ "evaluation of a call to a 'constexpr' member function">;
def note_constexpr_lifetime_ended : Note<
"%select{read of|assignment to|increment of|decrement of}0 "
"%select{temporary|variable}1 whose lifetime has ended">;
@@ -138,6 +141,7 @@ def note_constexpr_calls_suppressed : Note<
"(skipping %0 call%s0 in backtrace; use -fconstexpr-backtrace-limit=0 to "
"see all)">;
def note_constexpr_call_here : Note<"in call to '%0'">;
+
def warn_integer_constant_overflow : Warning<
"overflow in expression; result is %0 with type %1">,
InGroup<DiagGroup<"integer-overflow">>;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 98061e6c494..3e8a0d0dc14 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -4666,8 +4666,13 @@ public:
// Can't look at 'this' when checking a potential constant expression.
if (Info.checkingPotentialConstantExpression())
return false;
- if (!Info.CurrentCall->This)
- return Error(E);
+ if (!Info.CurrentCall->This) {
+ if (Info.getLangOpts().CPlusPlus11)
+ Info.Diag(E, diag::note_constexpr_this) << E->isImplicit();
+ else
+ Info.Diag(E);
+ return false;
+ }
Result = *Info.CurrentCall->This;
return true;
}
diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index 86901240b5f..09d93fa73af 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -823,6 +823,19 @@ static_assert(X() == 0, "");
}
+struct This {
+ constexpr int f() const { return 0; }
+ static constexpr int g() { return 0; }
+ void h() {
+ constexpr int x = f(); // expected-error {{must be initialized by a constant}}
+ // expected-note@-1 {{implicit use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function}}
+ constexpr int y = this->f(); // expected-error {{must be initialized by a constant}}
+ // expected-note-re@-1 {{{{^}}use of 'this' pointer}}
+ constexpr int z = g();
+ static_assert(z == 0, "");
+ }
+};
+
}
namespace Temporaries {
OpenPOWER on IntegriCloud