summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-05-22 05:49:41 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-05-22 05:49:41 +0000
commitab6607ab09238d79fb4d29557504c7c5d7cc3891 (patch)
tree837be6ba60f5f42a79fa17822388f000e66df976
parent0c54197d31d178b96c9ee1fcde3f4722c637b91c (diff)
downloadbcm5719-llvm-ab6607ab09238d79fb4d29557504c7c5d7cc3891.tar.gz
bcm5719-llvm-ab6607ab09238d79fb4d29557504c7c5d7cc3891.zip
[Sema] Don't crash on out-of-line virtual constexpr functions
The method wasn't an overrider but didn't have 'virtual' textually written because our CXXMethodDecl was an out-of-line definition. Make sure we use the canonical decl instead. This fixes PR23629. llvm-svn: 237999
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp3
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp4
2 files changed, 6 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 28337171712..e52d29e45c5 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -828,7 +828,8 @@ bool Sema::CheckConstexprFunctionDecl(const FunctionDecl *NewFD) {
// - it shall not be virtual;
const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(NewFD);
if (Method && Method->isVirtual()) {
- Diag(NewFD->getLocation(), diag::err_constexpr_virtual);
+ Method = Method->getCanonicalDecl();
+ Diag(Method->getLocation(), diag::err_constexpr_virtual);
// If it's not obvious why this function is virtual, find an overridden
// function which uses the 'virtual' keyword.
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
index 1e3734e5431..3986dc9565c 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
@@ -36,6 +36,8 @@ struct T : SS, NonLiteral {
constexpr int ImplicitlyVirtual() const { return 0; } // expected-error {{virtual function cannot be constexpr}}
+ virtual constexpr int OutOfLineVirtual() const; // expected-error {{virtual function cannot be constexpr}}
+
// - its return type shall be a literal type;
constexpr NonLiteral NonLiteralReturn() const { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}}
constexpr void VoidReturn() const { return; }
@@ -67,6 +69,8 @@ struct T : SS, NonLiteral {
// expected-error@-5 {{defaulted definition of copy assignment operator is not constexpr}}
#endif
};
+
+constexpr int T::OutOfLineVirtual() const { return 0; }
#ifdef CXX1Y
struct T2 {
int n = 0;
OpenPOWER on IntegriCloud