From: David Majnemer Date: Fri, 22 May 2015 05:49:41 +0000 (+0000) Subject: [Sema] Don't crash on out-of-line virtual constexpr functions X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e3d035d044eaeae342b607424cfd7eabb45a99ad;p=clang [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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@237999 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 2833717171..e52d29e45c 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -828,7 +828,8 @@ bool Sema::CheckConstexprFunctionDecl(const FunctionDecl *NewFD) { // - it shall not be virtual; const CXXMethodDecl *Method = dyn_cast(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/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp index 1e3734e543..3986dc9565 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp +++ b/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;