HerrCai0907 created this revision.
Herald added a project: All.
HerrCai0907 requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Fixed: https://github.com/llvm/llvm-project/issues/62408
`setInvalidDecl` for invalid `CXXDeductionGuideDecl` to
avoid crashes during semantic analysis.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D149516

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp
  clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
  clang/test/SemaCXX/invalid-deduction-guide-as-template-candidates.cpp

Index: clang/test/SemaCXX/invalid-deduction-guide-as-template-candidates.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/invalid-deduction-guide-as-template-candidates.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template <class T> class Foo {}; // expected-note {{candidate template ignored: couldn't infer template argument 'T'}} \
+                                 // expected-note {{candidate function template not viable: requires 1 argument, but 0 were provided}}
+Foo(); // expected-error {{deduction guide declaration without trailing return type}}
+Foo vs; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'Foo'}}
Index: clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
===================================================================
--- clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
+++ clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
@@ -241,9 +241,8 @@
 };
 
 struct A2 {
-  template <typename Ty> // expected-note {{non-deducible template parameter 'Ty'}}
+  template <typename 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}}
 };
 
Index: clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp
===================================================================
--- clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp
+++ clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp
@@ -173,10 +173,10 @@
 concept g = f<a, e>::h;
 template <class a, class e>
 concept i = g<e, a>;
-template <typename> class j { // expected-note {{candidate template ignored}}
+template <typename> class j {
   template <typename k>
   requires requires { requires i<j, k>; }
-  j(); // expected-note {{candidate template ignored}}
+  j();
 };
-template <> j(); // expected-error {{deduction guide declaration without trailing return type}} // expected-error {{no function template}}
+template <> j(); // expected-error {{deduction guide declaration without trailing return type}}
 }
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -11074,8 +11074,9 @@
 /// These aren't actually declarators in the grammar, so we need to check that
 /// the user didn't specify any pieces that are not part of the deduction-guide
 /// grammar.
-void Sema::CheckDeductionGuideDeclarator(Declarator &D, QualType &R,
+bool Sema::CheckDeductionGuideDeclarator(Declarator &D, QualType &R,
                                          StorageClass &SC) {
+  bool IsValid = true;
   TemplateName GuidedTemplate = D.getName().TemplateName.get().get();
   TemplateDecl *GuidedTemplateDecl = GuidedTemplate.getAsTemplateDecl();
   assert(GuidedTemplateDecl && "missing template decl for deduction guide");
@@ -11124,7 +11125,7 @@
   }
 
   if (D.isInvalidType())
-    return;
+    return IsValid;
 
   // Check the declarator is simple enough.
   bool FoundFunction = false;
@@ -11138,6 +11139,7 @@
       break;
     }
     if (!Chunk.Fun.hasTrailingReturnType()) {
+      IsValid = false;
       Diag(D.getName().getBeginLoc(),
            diag::err_deduction_guide_no_trailing_return_type);
       break;
@@ -11177,6 +11179,7 @@
     }
 
     if (!AcceptableReturnType) {
+      IsValid = false;
       Diag(TSI->getTypeLoc().getBeginLoc(),
            diag::err_deduction_guide_bad_trailing_return_type)
           << GuidedTemplate << TSI->getType()
@@ -11191,6 +11194,7 @@
 
   if (D.isFunctionDefinition())
     Diag(D.getIdentifierLoc(), diag::err_deduction_guide_defines_function);
+  return IsValid;
 }
 
 //===----------------------------------------------------------------------===//
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -9199,11 +9199,13 @@
       SemaRef.Diag(TrailingRequiresClause->getBeginLoc(),
                    diag::err_trailing_requires_clause_on_deduction_guide)
           << TrailingRequiresClause->getSourceRange();
-    SemaRef.CheckDeductionGuideDeclarator(D, R, SC);
+    bool IsValid = SemaRef.CheckDeductionGuideDeclarator(D, R, SC);
 
-    return CXXDeductionGuideDecl::Create(SemaRef.Context, DC, D.getBeginLoc(),
+    CXXDeductionGuideDecl* DGD = CXXDeductionGuideDecl::Create(SemaRef.Context, DC, D.getBeginLoc(),
                                          ExplicitSpecifier, NameInfo, R, TInfo,
                                          D.getEndLoc());
+    DGD->setInvalidDecl(!IsValid);
+    return DGD;
   } else if (DC->isRecord()) {
     // If the name of the function is the same as the name of the record,
     // then this must be an invalid constructor that has a return type.
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -7781,7 +7781,7 @@
   void CheckConversionDeclarator(Declarator &D, QualType &R,
                                  StorageClass& SC);
   Decl *ActOnConversionDeclarator(CXXConversionDecl *Conversion);
-  void CheckDeductionGuideDeclarator(Declarator &D, QualType &R,
+  bool CheckDeductionGuideDeclarator(Declarator &D, QualType &R,
                                      StorageClass &SC);
   void CheckDeductionGuideTemplate(FunctionTemplateDecl *TD);
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to