[clang] dd36138 - [clang] Error on explicit specialization of lambda call operator (#84343)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 8 00:52:45 PST 2024
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}}
+
+}
More information about the cfe-commits
mailing list