[clang] a1879e5 - Fix crash on invalid code involving late parsed inline methods

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Thu Dec 16 04:58:59 PST 2021


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}}
+};
+
+}


        


More information about the cfe-commits mailing list