]> granicus.if.org Git - clang/commitdiff
[Sema] Don't crash on out-of-line virtual constexpr functions
authorDavid Majnemer <david.majnemer@gmail.com>
Fri, 22 May 2015 05:49:41 +0000 (05:49 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Fri, 22 May 2015 05:49:41 +0000 (05:49 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@237999 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDeclCXX.cpp
test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp

index 28337171712c54f75006368fd79663d4264681fc..e52d29e45c58f0a226e9513570171a2986717c8c 100644 (file)
@@ -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.
index 1e3734e54311978bf20067e13bd8a0e300f386c7..3986dc9565c394dc038498de978519f9fd840bbf 100644 (file)
@@ -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;