Author: Aaron Ballman Date: 2021-12-16T07:58:51-05:00 New Revision: a1879e52e3ae9424b59747d9b837a7a87bcb996d
URL: https://github.com/llvm/llvm-project/commit/a1879e52e3ae9424b59747d9b837a7a87bcb996d DIFF: https://github.com/llvm/llvm-project/commit/a1879e52e3ae9424b59747d9b837a7a87bcb996d.diff LOG: Fix crash on invalid code involving late parsed inline methods When parsing the following construct, we parse it as an erroneous deduction guide declaration and correctly diagnose the issues with it. template<class> struct B; struct A { B() noexcept(false); }; However, we then go on to finish late parsing the declaration and this expects that what we've parsed is a CXXMethodDecl. A CXXDeductionGuideDecl is not a CXXMethodDecl (it's a FunctionDecl), and so we assert on the cast. This fixes the crash by switching from cast<> to dyn_cast<> and not setting up a "this" scope when the declaration is not a CXXMethodDecl. This fixes PR49735. Added: Modified: clang/lib/Parse/ParseCXXInlineMethods.cpp clang/test/Parser/cxx1z-class-template-argument-deduction.cpp Removed: ################################################################################ diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index 116724a0d50ba..19cddc69ebfc7 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -452,13 +452,14 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { CXXMethodDecl *Method; if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(LM.Method)) - Method = cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl()); + Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl()); else - Method = cast<CXXMethodDecl>(LM.Method); + Method = dyn_cast<CXXMethodDecl>(LM.Method); - Sema::CXXThisScopeRAII ThisScope(Actions, Method->getParent(), - Method->getMethodQualifiers(), - getLangOpts().CPlusPlus11); + Sema::CXXThisScopeRAII ThisScope( + Actions, Method ? Method->getParent() : nullptr, + Method ? Method->getMethodQualifiers() : Qualifiers{}, + Method && getLangOpts().CPlusPlus11); // Parse the exception-specification. SourceRange SpecificationRange; diff --git a/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp b/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp index 532c893f2132f..2f0e948022fbf 100644 --- a/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp +++ b/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp @@ -230,3 +230,21 @@ namespace within_template_arg_list { template<int ...N> struct Z { Y<X(N)...> y; }; } + +namespace PR49735 { +// Ensure that we do not crash when parsing code which looks like an invalid +// deduction guide declaration. +template<class> struct B; // expected-note 2{{template is declared here}} +struct A1 { + B() noexcept(false); // expected-error {{deduction guide must be declared in the same scope as template 'PR49735::B'}} \ + // expected-error {{deduction guide declaration without trailing return type}} +}; + +struct A2 { + template <typename Ty> // expected-note {{non-deducible template parameter 'Ty'}} + B() noexcept(false); // expected-error {{deduction guide must be declared in the same scope as template 'PR49735::B'}} \ + // expected-error {{deduction guide template contains a template parameter that cannot be deduced}} \ + // expected-error {{deduction guide declaration without trailing return type}} +}; + +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits