Author: Congcong Cai Date: 2023-05-23T22:14:12+02:00 New Revision: ca9683651e52196f590bc244d9c506ed39fe1d92
URL: https://github.com/llvm/llvm-project/commit/ca9683651e52196f590bc244d9c506ed39fe1d92 DIFF: https://github.com/llvm/llvm-project/commit/ca9683651e52196f590bc244d9c506ed39fe1d92.diff LOG: [Sema] `setInvalidDecl` for error deduction declaration Fixed: https://github.com/llvm/llvm-project/issues/62408 `setInvalidDecl` for invalid `CXXDeductionGuideDecl` to avoid crashes during semantic analysis. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D149516 Added: clang/test/SemaCXX/invalid-deduction-guide-as-template-candidates.cpp Modified: clang/docs/ReleaseNotes.rst 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/CXX/temp/temp.res/temp.local/p3.cpp clang/test/Parser/cxx1z-class-template-argument-deduction.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index a55e969fa21c1..915c9b0cf1014 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -392,6 +392,8 @@ Bug Fixes in This Version - Fix crash when attempting to perform parenthesized initialization of an aggregate with a base class with only non-public constructors. (`#62296 <https://github.com/llvm/llvm-project/issues/62296>`_) +- Fix crash when handling initialization candidates for invalid deduction guide. + (`#62408 <https://github.com/llvm/llvm-project/issues/62408>`_) - Fix crash when redefining a variable with an invalid type again with an invalid type. (`#62447 <https://github.com/llvm/llvm-project/issues/62447>`_) - Fix a stack overflow issue when evaluating ``consteval`` default arguments. diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index e869117a8ea66..cb38329ca73a5 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -7790,7 +7790,7 @@ class Sema final { 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); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 2f9c8c70e2093..859224780befa 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -9199,8 +9199,8 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, SemaRef.Diag(TrailingRequiresClause->getBeginLoc(), diag::err_trailing_requires_clause_on_deduction_guide) << TrailingRequiresClause->getSourceRange(); - SemaRef.CheckDeductionGuideDeclarator(D, R, SC); - + if (SemaRef.CheckDeductionGuideDeclarator(D, R, SC)) + return nullptr; return CXXDeductionGuideDecl::Create(SemaRef.Context, DC, D.getBeginLoc(), ExplicitSpecifier, NameInfo, R, TInfo, D.getEndLoc()); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index e68afaa61ef1c..e2a1de9ee5be2 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -11087,8 +11087,8 @@ struct BadSpecifierDiagnoser { /// Check the validity of a declarator that we parsed for a deduction-guide. /// 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, +/// grammar. Return true on invalid deduction-guide. +bool Sema::CheckDeductionGuideDeclarator(Declarator &D, QualType &R, StorageClass &SC) { TemplateName GuidedTemplate = D.getName().TemplateName.get().get(); TemplateDecl *GuidedTemplateDecl = GuidedTemplate.getAsTemplateDecl(); @@ -11138,7 +11138,7 @@ void Sema::CheckDeductionGuideDeclarator(Declarator &D, QualType &R, } if (D.isInvalidType()) - return; + return true; // Check the declarator is simple enough. bool FoundFunction = false; @@ -11151,11 +11151,9 @@ void Sema::CheckDeductionGuideDeclarator(Declarator &D, QualType &R, << D.getSourceRange(); break; } - if (!Chunk.Fun.hasTrailingReturnType()) { - Diag(D.getName().getBeginLoc(), - diag::err_deduction_guide_no_trailing_return_type); - break; - } + if (!Chunk.Fun.hasTrailingReturnType()) + return Diag(D.getName().getBeginLoc(), + diag::err_deduction_guide_no_trailing_return_type); // Check that the return type is written as a specialization of // the template specified as the deduction-guide's name. @@ -11190,13 +11188,12 @@ void Sema::CheckDeductionGuideDeclarator(Declarator &D, QualType &R, MightInstantiateToSpecialization = true; } - if (!AcceptableReturnType) { - Diag(TSI->getTypeLoc().getBeginLoc(), - diag::err_deduction_guide_bad_trailing_return_type) - << GuidedTemplate << TSI->getType() - << MightInstantiateToSpecialization - << TSI->getTypeLoc().getSourceRange(); - } + if (!AcceptableReturnType) + return Diag(TSI->getTypeLoc().getBeginLoc(), + diag::err_deduction_guide_bad_trailing_return_type) + << GuidedTemplate << TSI->getType() + << MightInstantiateToSpecialization + << TSI->getTypeLoc().getSourceRange(); // Keep going to check that we don't have any inner declarator pieces (we // could still have a function returning a pointer to a function). @@ -11204,7 +11201,9 @@ void Sema::CheckDeductionGuideDeclarator(Declarator &D, QualType &R, } if (D.isFunctionDefinition()) + // we can still create a valid deduction guide here. Diag(D.getIdentifierLoc(), diag::err_deduction_guide_defines_function); + return false; } //===----------------------------------------------------------------------===// diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp index e7428b5061c2e..763d983d20f61 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp @@ -173,10 +173,10 @@ template <class a, class e> 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}} } diff --git a/clang/test/CXX/temp/temp.res/temp.local/p3.cpp b/clang/test/CXX/temp/temp.res/temp.local/p3.cpp index 5e8a233d76d93..87589e1e5bcdc 100644 --- a/clang/test/CXX/temp/temp.res/temp.local/p3.cpp +++ b/clang/test/CXX/temp/temp.res/temp.local/p3.cpp @@ -28,8 +28,7 @@ namespace PR6717 { WebVector(const WebVector<T>& other) { } // expected-error{{undeclared identifier 'T'}} \ precxx17-error{{a type specifier is required}} \ - cxx17-error{{deduction guide declaration without trailing return type}} \ - cxx17-error{{deduction guide cannot have a function definition}} + cxx17-error{{deduction guide declaration without trailing return type}} template <typename C> WebVector<T>& operator=(const C& other) { } // expected-error{{undeclared identifier 'T'}} diff --git a/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp b/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp index 2f0e948022fbf..fd651ad1b1b48 100644 --- a/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp +++ b/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp @@ -241,9 +241,8 @@ struct A1 { }; 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}} }; diff --git a/clang/test/SemaCXX/invalid-deduction-guide-as-template-candidates.cpp b/clang/test/SemaCXX/invalid-deduction-guide-as-template-candidates.cpp new file mode 100644 index 0000000000000..e9b362d67cd23 --- /dev/null +++ b/clang/test/SemaCXX/invalid-deduction-guide-as-template-candidates.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -std=c++17 -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'}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits