From ab6607ab09238d79fb4d29557504c7c5d7cc3891 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Fri, 22 May 2015 05:49:41 +0000 Subject: [PATCH] [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 --- clang/lib/Sema/SemaDeclCXX.cpp | 3 ++- clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 28337171712c..e52d29e45c58 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(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 1e3734e54311..3986dc9565c3 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;