Author: Mariya Podchishchaeva Date: 2024-03-08T09:52:42+01:00 New Revision: dd36138e9c23c462ce5379a3d83530fb4ebec9e7
URL: https://github.com/llvm/llvm-project/commit/dd36138e9c23c462ce5379a3d83530fb4ebec9e7 DIFF: https://github.com/llvm/llvm-project/commit/dd36138e9c23c462ce5379a3d83530fb4ebec9e7.diff LOG: [clang] Error on explicit specialization of lambda call operator (#84343) Fixes https://github.com/llvm/llvm-project/issues/83267 Added: Modified: clang/docs/ReleaseNotes.rst clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/SemaDecl.cpp clang/test/SemaCXX/lambda-expressions.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index fe7bbe437831ed..225ca85e18115d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -250,6 +250,10 @@ Bug Fixes in This Version for variables created through copy initialization having side-effects in C++17 and later. Fixes (#GH64356) (#GH79518). +- Clang now emits errors for explicit specializations/instatiations of lambda call + operator. + Fixes (#GH83267). + Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index c8dfdc08f5ea07..a80c8b75e863ed 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -8170,6 +8170,8 @@ let CategoryName = "Lambda Issue" in { def warn_cxx11_compat_generic_lambda : Warning< "generic lambdas are incompatible with C++11">, InGroup<CXXPre14Compat>, DefaultIgnore; + def err_lambda_explicit_spec : Error< + "lambda call operator should not be explicitly specialized or instantiated">; // C++17 '*this' captures. def warn_cxx14_compat_star_this_lambda_capture : Warning< diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 67e56a917a51de..910d0dfbf9f65f 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -15795,10 +15795,19 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D, // captures during transformation of nested lambdas, it is necessary to // have the LSI properly restored. if (isGenericLambdaCallOperatorSpecialization(FD)) { - assert(inTemplateInstantiation() && - "There should be an active template instantiation on the stack " - "when instantiating a generic lambda!"); - RebuildLambdaScopeInfo(cast<CXXMethodDecl>(D)); + // C++2c 7.5.5.2p17 A member of a closure type shall not be explicitly + // instantiated, explicitly specialized. + if (FD->getTemplateSpecializationInfo() + ->isExplicitInstantiationOrSpecialization()) { + Diag(FD->getLocation(), diag::err_lambda_explicit_spec); + FD->setInvalidDecl(); + PushFunctionScope(); + } else { + assert(inTemplateInstantiation() && + "There should be an active template instantiation on the stack " + "when instantiating a generic lambda!"); + RebuildLambdaScopeInfo(cast<CXXMethodDecl>(D)); + } } else { // Enter a new function scope PushFunctionScope(); @@ -16317,9 +16326,8 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, } } - assert( - (FD == getCurFunctionDecl() || getCurLambda()->CallOperator == FD) && - "Function parsing confused"); + assert((FD == getCurFunctionDecl(/*AllowLambdas=*/true)) && + "Function parsing confused"); } else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(dcl)) { assert(MD == getCurMethodDecl() && "Method parsing confused"); MD->setBody(Body); diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp index 41cf5a46c38922..0516a5da31ae9a 100644 --- a/clang/test/SemaCXX/lambda-expressions.cpp +++ b/clang/test/SemaCXX/lambda-expressions.cpp @@ -732,3 +732,18 @@ void GH67492() { constexpr auto test = 42; auto lambda = (test, []() noexcept(true) {}); } + +namespace GH83267 { +auto l = [](auto a) { return 1; }; +using type = decltype(l); + +template<> +auto type::operator()(int a) const { // expected-error{{lambda call operator should not be explicitly specialized or instantiated}} + return c; // expected-error {{use of undeclared identifier 'c'}} +} + +auto ll = [](auto a) { return 1; }; // expected-error{{lambda call operator should not be explicitly specialized or instantiated}} +using t = decltype(ll); +template auto t::operator()<int>(int a) const; // expected-note {{in instantiation}} + +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits