Skip to content

Commit 3eeed79

Browse files
authored
[clang] Correctly implement CWG 2672 (llvm#75001)
1 parent 7648371 commit 3eeed79

16 files changed

+39
-54
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -723,7 +723,8 @@ Bug Fixes to C++ Support
723723

724724
- Clang emits an error on substitution failure within lambda body inside a
725725
requires-expression. This fixes:
726-
(`#64138 <https://github.com/llvm/llvm-project/issues/64138>`_).
726+
(`#64138 <https://github.com/llvm/llvm-project/issues/64138>`_) and
727+
(`#71684 <https://github.com/llvm/llvm-project/issues/71684>`_).
727728

728729
- Update ``FunctionDeclBitfields.NumFunctionDeclBits``. This fixes:
729730
(`#64171 <https://github.com/llvm/llvm-project/issues/64171>`_).

clang/lib/Sema/SemaTemplateInstantiate.cpp

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
#include "clang/Sema/Template.h"
3636
#include "clang/Sema/TemplateDeduction.h"
3737
#include "clang/Sema/TemplateInstCallback.h"
38-
#include "llvm/ADT/ScopeExit.h"
3938
#include "llvm/ADT/StringExtras.h"
4039
#include "llvm/Support/ErrorHandling.h"
4140
#include "llvm/Support/TimeProfiler.h"
@@ -1142,8 +1141,7 @@ std::optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
11421141
case CodeSynthesisContext::DeducedTemplateArgumentSubstitution:
11431142
// We're either substituting explicitly-specified template arguments,
11441143
// deduced template arguments. SFINAE applies unless we are in a lambda
1145-
// expression, see [temp.deduct]p9.
1146-
[[fallthrough]];
1144+
// body, see [temp.deduct]p9.
11471145
case CodeSynthesisContext::ConstraintSubstitution:
11481146
case CodeSynthesisContext::RequirementInstantiation:
11491147
case CodeSynthesisContext::RequirementParameterInstantiation:
@@ -1445,13 +1443,6 @@ namespace {
14451443
LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
14461444
Sema::ConstraintEvalRAII<TemplateInstantiator> RAII(*this);
14471445

1448-
Sema::CodeSynthesisContext C;
1449-
C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution;
1450-
C.PointOfInstantiation = E->getBeginLoc();
1451-
SemaRef.pushCodeSynthesisContext(C);
1452-
auto PopCtx =
1453-
llvm::make_scope_exit([this] { SemaRef.popCodeSynthesisContext(); });
1454-
14551446
ExprResult Result = inherited::TransformLambdaExpr(E);
14561447
if (Result.isInvalid())
14571448
return Result;

clang/lib/Sema/TreeTransform.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13685,10 +13685,17 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
1368513685
getSema().PushExpressionEvaluationContext(
1368613686
Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
1368713687

13688+
Sema::CodeSynthesisContext C;
13689+
C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution;
13690+
C.PointOfInstantiation = E->getBody()->getBeginLoc();
13691+
getSema().pushCodeSynthesisContext(C);
13692+
1368813693
// Instantiate the body of the lambda expression.
1368913694
StmtResult Body =
1369013695
Invalid ? StmtError() : getDerived().TransformLambdaBody(E, E->getBody());
1369113696

13697+
getSema().popCodeSynthesisContext();
13698+
1369213699
// ActOnLambda* will pop the function scope for us.
1369313700
FuncScopeCleanup.disable();
1369413701

clang/test/CXX/drs/dr26xx.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ void f(...);
211211

212212
template <class T>
213213
void bar(T) requires requires {
214-
decltype([]() -> T {})::foo();
214+
[]() -> decltype(T::foo()) {};
215215
};
216216
void bar(...);
217217

clang/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ struct NoDefaultCtor {
3535
template<typename T>
3636
void defargs_in_template_unused(T t) {
3737
auto l1 = [](const T& value = T()) { }; // expected-error{{no matching constructor for initialization of 'NoDefaultCtor'}} \
38-
// expected-note {{in instantiation of default function argument expression for 'operator()<NoDefaultCtor>' required here}} \
39-
// expected-note {{while substituting into a lambda expression here}}
38+
// expected-note {{in instantiation of default function argument expression for 'operator()<NoDefaultCtor>' required here}}
4039
l1(t);
4140
}
4241

@@ -46,8 +45,7 @@ template void defargs_in_template_unused(NoDefaultCtor); // expected-note{{in i
4645
template<typename T>
4746
void defargs_in_template_used() {
4847
auto l1 = [](const T& value = T()) { }; // expected-error{{no matching constructor for initialization of 'NoDefaultCtor'}} \
49-
// expected-note {{in instantiation of default function argument expression for 'operator()<NoDefaultCtor>' required here}} \
50-
// expected-note {{while substituting into a lambda expression here}}
48+
// expected-note {{in instantiation of default function argument expression for 'operator()<NoDefaultCtor>' required here}}
5149
l1();
5250
}
5351

clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ auto init_kind_2 = [ec = ExplicitCopy()] {}; // expected-error {{no matching con
3535
template<typename T> void init_kind_template() {
3636
auto init_kind_1 = [ec(T())] {};
3737
auto init_kind_2 = [ec = T()] {}; // expected-error {{no matching constructor}}
38-
// expected-note@-1 {{while substituting into a lambda expression here}}
3938
}
4039
template void init_kind_template<int>();
4140
template void init_kind_template<ExplicitCopy>(); // expected-note {{instantiation of}}
@@ -53,7 +52,6 @@ auto bad_init_6 = [a{overload_fn}] {}; // expected-error {{cannot deduce type fo
5352
auto bad_init_7 = [a{{1}}] {}; // expected-error {{cannot deduce type for lambda capture 'a' from nested initializer list}}
5453

5554
template<typename...T> void pack_1(T...t) { (void)[a(t...)] {}; } // expected-error {{initializer missing for lambda capture 'a'}}
56-
// expected-note@-1 {{while substituting into a lambda expression here}}
5755
template void pack_1<>(); // expected-note {{instantiation of}}
5856

5957
// No lifetime-extension of the temporary here.

clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ void init_capture_pack_err(Args ...args) {
8585
template<typename ...Args>
8686
void init_capture_pack_multi(Args ...args) {
8787
[as(args...)] {} (); // expected-error {{initializer missing for lambda capture 'as'}} expected-error {{multiple}}
88-
// expected-note@-1 2{{while substituting into a lambda expression}}
8988
}
9089
template void init_capture_pack_multi(); // expected-note {{instantiation}}
9190
template void init_capture_pack_multi(int);

clang/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,11 @@ void test_result_type(int N) { // expected-note {{declared here}}
5555
template <typename T>
5656
void test_result_type_tpl(int N) { // expected-note 2{{declared here}}
5757
auto l1 = []() -> T {}; // expected-error{{incomplete result type 'Incomplete' in lambda expression}}
58-
// expected-note@-1{{while substituting into a lambda expression here}}
5958
typedef int vla[N]; // expected-warning 2{{variable length arrays in C++ are a Clang extension}} \
6059
expected-note 2{{function parameter 'N' with unknown value cannot be used in a constant expression}}
6160
auto l2 = []() -> vla {}; // expected-error{{function cannot return array type 'vla' (aka 'int[N]')}}
6261
}
6362

6463
void test_result_type_call() {
65-
test_result_type_tpl<Incomplete>(10); // expected-note 2{{requested here}}
64+
test_result_type_tpl<Incomplete>(10); // expected-note {{requested here}}
6665
}

clang/test/CXX/temp/temp.deduct/p9.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,14 @@ template <class T>
2828
auto h(T) -> decltype([x = T::invalid]() { });
2929
void h(...);
3030
void test_h() {
31-
h(0); // expected-error@-3 {{type 'int' cannot be used prior to '::'}}
32-
// expected-note@-1 {{while substituting deduced template arguments}}
33-
// expected-note@-5 {{while substituting into a lambda expression here}}
31+
h(0);
3432
}
3533

3634
template <class T>
3735
auto i(T) -> decltype([]() -> typename T::invalid { });
3836
void i(...);
3937
void test_i() {
40-
i(0); // expected-error@-3 {{type 'int' cannot be used prior to '::'}}
41-
// expected-note@-1 {{while substituting deduced template arguments}}
42-
// expected-note@-5 {{while substituting into a lambda expression here}}
38+
i(0);
4339
}
4440

4541

clang/test/SemaCXX/cxx1y-init-captures.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,17 @@ namespace variadic_expansion {
2121
return a;
2222
}() ...);
2323
};
24-
auto N2 = [x = y, //expected-note3{{begins here}} expected-note 6 {{default capture by}} expected-note 2 {{substituting into a lambda}}
24+
auto N2 = [x = y, //expected-note3{{begins here}} expected-note 6 {{default capture by}}
2525
&z = y, n = f(t...),
26-
o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...)](T& ... s) { // expected-note 6 {{capture 't' by}}
27-
fv([&a(t)]()->decltype(auto) { //expected-error 3{{captured}} expected-note 2{{substituting into a lambda}}
26+
o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...)](T& ... s) { // expected-note 6 {{capture 't' by}} expected-note {{substituting into a lambda}}
27+
fv([&a(t)]()->decltype(auto) { //expected-error 3{{captured}}
2828
return a;
2929
}() ...);
3030
};
3131

3232
}
3333

34-
void h(int i, char c) { g(i, c); } //expected-note 2{{in instantiation}}
34+
void h(int i, char c) { g(i, c); } // expected-note {{requested here}}
3535
}
3636

3737
namespace odr_use_within_init_capture {

clang/test/SemaCXX/cxx1z-lambda-star-this.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class B {
4646
template <class T = int>
4747
void foo() {
4848
(void)[this] { return x; };
49-
(void)[*this] { return x; }; //expected-error2{{call to deleted}} expected-note {{while substituting into a lambda}}
49+
(void)[*this] { return x; }; //expected-error2{{call to deleted}}
5050
}
5151

5252
B() = default;
@@ -63,7 +63,7 @@ class B {
6363
public:
6464
template <class T = int>
6565
auto foo() {
66-
const auto &L = [*this](auto a) mutable { //expected-error{{call to deleted}} expected-note {{while substituting into a lambda}}
66+
const auto &L = [*this](auto a) mutable { //expected-error{{call to deleted}}
6767
d += a;
6868
return [this](auto b) { return d += b; };
6969
};

clang/test/SemaCXX/lambda-expressions.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ struct S {
393393
namespace PR18473 {
394394
template<typename T> void f() {
395395
T t(0);
396-
(void) [=]{ int n = t; }; // expected-error {{deleted}} expected-note {{while substituting into a lambda}}
396+
(void) [=]{ int n = t; }; // expected-error {{deleted}}
397397
}
398398

399399
template void f<int>();
@@ -476,7 +476,7 @@ namespace error_in_transform_prototype {
476476
void f(T t) {
477477
// expected-error@+2 {{type 'int' cannot be used prior to '::' because it has no members}}
478478
// expected-error@+1 {{no member named 'ns' in 'error_in_transform_prototype::S'}}
479-
auto x = [](typename T::ns::type &k) {}; // expected-note 2 {{while substituting into a lambda}}
479+
auto x = [](typename T::ns::type &k) {};
480480
}
481481
class S {};
482482
void foo() {

clang/test/SemaCXX/lambda-pack-expansion.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ struct X {
88

99
void take_by_copy(auto &...args) {
1010
[...args = args] {}(); // expected-error {{call to deleted constructor}}
11-
// expected-note@-1 {{substituting into a lambda}}
1211
}
1312

1413
void take_by_ref(auto &...args) {

clang/test/SemaCXX/vartemplate-lambda.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ template<typename T> auto v1 = [](int a = T()) { return a; }();
88
// expected-error@-1{{cannot initialize a parameter of type 'int' with an rvalue of type 'int *'}}
99
// expected-note@-2{{in instantiation of default function argument expression for 'operator()<int *>' required here}}
1010
// expected-note@-3{{passing argument to parameter 'a' here}}
11-
// expected-note@-4{{substituting into a lambda}}
1211

1312
struct S {
1413
template<class T>

clang/test/SemaCXX/warn-unused-lambda-capture.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -145,38 +145,38 @@ void test_templated() {
145145
auto explicit_by_value_used_generic = [i](auto c) { return i + 1; };
146146
auto explicit_by_value_used_void = [i] { (void)i; };
147147

148-
auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}} expected-note {{substituting into a lambda}}
149-
auto explicit_by_value_unused_sizeof = [i] { return sizeof(i); }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}} expected-note {{substituting into a lambda}}
150-
auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; // expected-warning{{lambda capture 'i' is not used}} expected-note {{substituting into a lambda}}
151-
auto explicit_by_value_unused_const = [k] { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}} expected-note {{substituting into a lambda}}
152-
auto explicit_by_value_unused_const_generic = [k](auto c) { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}} expected-note {{substituting into a lambda}}
148+
auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
149+
auto explicit_by_value_unused_sizeof = [i] { return sizeof(i); }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
150+
auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; // expected-warning{{lambda capture 'i' is not used}}
151+
auto explicit_by_value_unused_const = [k] { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}}
152+
auto explicit_by_value_unused_const_generic = [k](auto c) { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}}
153153

154154
auto explicit_by_reference_used = [&i] { i++; };
155-
auto explicit_by_reference_unused = [&i] {}; // expected-warning{{lambda capture 'i' is not used}} expected-note {{substituting into a lambda}}
155+
auto explicit_by_reference_unused = [&i] {}; // expected-warning{{lambda capture 'i' is not used}}
156156

157157
auto explicit_initialized_reference_used = [&j = i] { return j + 1; };
158-
auto explicit_initialized_reference_unused = [&j = i]{}; // expected-warning{{lambda capture 'j' is not used}} expected-note {{substituting into a lambda}}
158+
auto explicit_initialized_reference_unused = [&j = i]{}; // expected-warning{{lambda capture 'j' is not used}}
159159

160160
auto explicit_initialized_value_used = [j = 1] { return j + 1; };
161-
auto explicit_initialized_value_unused = [j = 1] {}; // expected-warning{{lambda capture 'j' is not used}} expected-note {{substituting into a lambda}}
161+
auto explicit_initialized_value_unused = [j = 1] {}; // expected-warning{{lambda capture 'j' is not used}}
162162
auto explicit_initialized_value_non_trivial_constructor = [j = NonTrivialConstructor()]{};
163163
auto explicit_initialized_value_non_trivial_destructor = [j = NonTrivialDestructor()]{};
164-
auto explicit_initialized_value_trivial_init = [j = Trivial()]{}; // expected-warning{{lambda capture 'j' is not used}} expected-note {{substituting into a lambda}}
164+
auto explicit_initialized_value_trivial_init = [j = Trivial()]{}; // expected-warning{{lambda capture 'j' is not used}}
165165
auto explicit_initialized_value_non_trivial_init = [j = Trivial(42)]{};
166166
auto explicit_initialized_value_with_side_effect = [j = side_effect()]{};
167167
auto explicit_initialized_value_generic_used = [i = 1](auto c) mutable { i++; };
168-
auto explicit_initialized_value_generic_unused = [i = 1](auto c) mutable {}; // expected-warning{{lambda capture 'i' is not used}} expected-note {{substituting into a lambda}}
168+
auto explicit_initialized_value_generic_unused = [i = 1](auto c) mutable {}; // expected-warning{{lambda capture 'i' is not used}}
169169

170170
auto nested = [&i] { // expected-note {{substituting into a lambda}}
171171
auto explicit_by_value_used = [i] { return i + 1; };
172-
auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}} expected-note {{substituting into a lambda}}
172+
auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
173173
};
174174

175175
Trivial trivial;
176-
auto explicit_by_value_trivial = [trivial] {}; // expected-warning{{lambda capture 'trivial' is not used}} expected-note {{substituting into a lambda}}
176+
auto explicit_by_value_trivial = [trivial] {}; // expected-warning{{lambda capture 'trivial' is not used}}
177177

178178
NonTrivialConstructor cons;
179-
auto explicit_by_value_non_trivial_constructor = [cons] {}; // expected-warning{{lambda capture 'cons' is not used}} expected-note {{substituting into a lambda}}
179+
auto explicit_by_value_non_trivial_constructor = [cons] {}; // expected-warning{{lambda capture 'cons' is not used}}
180180

181181
NonTrivialCopyConstructor copy_cons;
182182
auto explicit_by_value_non_trivial_copy_constructor = [copy_cons] {};
@@ -189,7 +189,7 @@ void test_templated() {
189189
}
190190

191191
void test_use_template() {
192-
test_templated<int>(); // expected-note 13{{in instantiation of function template specialization 'test_templated<int>' requested here}}
192+
test_templated<int>(); // expected-note 3 {{requested here}}
193193
}
194194

195195
namespace pr35555 {

clang/test/SemaTemplate/instantiate-local-class.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -473,8 +473,7 @@ namespace rdar23721638 {
473473
template <typename T> void bar() {
474474
auto lambda = [](T a = "") {}; // expected-error {{conversion function from 'const char[1]' to 'rdar23721638::A' invokes a deleted function}} \
475475
// expected-note {{in instantiation of default function argument expression for 'operator()<rdar23721638::A>' required here}} \
476-
// expected-note {{passing argument to parameter 'a' here}} \
477-
// expected-note {{while substituting into a lambda}}
476+
// expected-note {{passing argument to parameter 'a' here}}
478477
lambda();
479478
}
480479
template void bar<A>(); // expected-note {{in instantiation}}
@@ -497,7 +496,6 @@ namespace PR45000 {
497496
// expected-error@-1 {{cannot initialize a parameter of type 'int' with an rvalue of type 'std::nullptr_t'}}
498497
// expected-note@-2 {{in instantiation of default function argument expression for 'operator()<int>' required here}}
499498
// expected-note@-3 {{passing argument to parameter 'x' here}}
500-
// expected-note@-4 {{while substituting into a lambda}}
501499

502500
void g() { f<int>(); }
503501
// expected-note@-1 {{in instantiation of default function argument expression for 'f<int>' required here}}

0 commit comments

Comments
 (0)