[clang] [clang] Error on explicit specialization of lambda call operator (PR #84343)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 7 09:00:00 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Mariya Podchishchaeva (Fznamznon)
<details>
<summary>Changes</summary>
Fixes https://github.com/llvm/llvm-project/issues/83267
---
Full diff: https://github.com/llvm/llvm-project/pull/84343.diff
4 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+4)
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+2)
- (modified) clang/lib/Sema/SemaDecl.cpp (+15-7)
- (modified) clang/test/SemaCXX/lambda-expressions.cpp (+15)
``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 1b901a27fd19d1..aa28ebf2558509 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -241,6 +241,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 6b81ee183cc440..31d615189385e5 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}}
+
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/84343
More information about the cfe-commits
mailing list