diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-07-07 06:00:13 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-07-07 06:00:13 +0000 |
commit | 22a5d61b5d3913b5967f5fa43ed4b1764a131a62 (patch) | |
tree | 9d49fcb86066603d1c3a4a1171ed3ef77cbdcf83 | |
parent | 45d099b995acacb165367edc7f3d77eb3cc8407d (diff) | |
download | bcm5719-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.td | 4 | ||||
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 9 | ||||
-rw-r--r-- | clang/test/SemaCXX/constant-expression-cxx11.cpp | 13 |
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 { |