[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
This commit is contained in:
David Majnemer 2015-05-22 05:49:41 +00:00
parent 0c54197d31
commit ab6607ab09
2 changed files with 6 additions and 1 deletions

View File

@ -828,7 +828,8 @@ bool Sema::CheckConstexprFunctionDecl(const FunctionDecl *NewFD) {
// - it shall not be virtual; // - it shall not be virtual;
const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(NewFD); const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(NewFD);
if (Method && Method->isVirtual()) { 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 // If it's not obvious why this function is virtual, find an overridden
// function which uses the 'virtual' keyword. // function which uses the 'virtual' keyword.

View File

@ -36,6 +36,8 @@ struct T : SS, NonLiteral {
constexpr int ImplicitlyVirtual() const { return 0; } // expected-error {{virtual function cannot be constexpr}} 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; // - 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 NonLiteral NonLiteralReturn() const { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}}
constexpr void VoidReturn() const { return; } 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}} // expected-error@-5 {{defaulted definition of copy assignment operator is not constexpr}}
#endif #endif
}; };
constexpr int T::OutOfLineVirtual() const { return 0; }
#ifdef CXX1Y #ifdef CXX1Y
struct T2 { struct T2 {
int n = 0; int n = 0;