Skip to content

Commit

Permalink
GH60642: Fix ICE when checking a lambda defined in a concept definition
Browse files Browse the repository at this point in the history
As reported in GH60642, we asserted when there was a lambda defined in a
template arguments inside of a concept, which caused us to not properly
set up the list of instantiation args.  This patch ensures that the
'lambda context decl' correctly falls-through the template argument
instantiation, so that it is available when instantiating the lambda,
and thus, when setting up the lambda instantiation args list.

(cherry picked from commit 4bf6cc6)
  • Loading branch information
Erich Keane authored and tstellar committed Feb 22, 2023
1 parent 3c27086 commit 80a3a5f
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 2 deletions.
2 changes: 1 addition & 1 deletion clang/lib/Sema/TreeTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -4569,7 +4569,7 @@ bool TreeTransform<Derived>::TransformTemplateArgument(
getSema(),
Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
: Sema::ExpressionEvaluationContext::ConstantEvaluated,
/*LambdaContextDecl=*/nullptr, /*ExprContext=*/
Sema::ReuseLambdaContextDecl, /*ExprContext=*/
Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);

Expr *InputExpr = Input.getSourceExpression();
Expand Down
26 changes: 25 additions & 1 deletion clang/test/SemaTemplate/concepts-lambda.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// RUN: %clang_cc1 -std=c++20 -verify %s
// RUN: %clang_cc1 -std=c++20 -verify %s -triple powerpc64-ibm-aix
// expected-no-diagnostics

namespace GH57945 {
template<typename T>
Expand Down Expand Up @@ -92,3 +91,28 @@ struct Foo {
static_assert(ConstructibleWithN<Foo>);

}

// GH60642 reported an assert being hit, make sure we don't assert.
namespace GH60642 {
template<auto Q> concept C = requires { Q.template operator()<float>(); };
template<class> concept D = true;
static_assert(C<[]<D>{}>); // ok
template<class> concept E = C<[]<D>{}>;
static_assert(E<int>); // previously Asserted.

// ensure we properly diagnose when "D" is false.
namespace DIsFalse {
template<auto Q> concept C = requires { Q.template operator()<float>(); };
template<class> concept D = false;
static_assert(C<[]<D>{}>);
// expected-error@-1{{static assertion failed}}
// expected-note@-2{{does not satisfy 'C'}}
// expected-note@-5{{because 'Q.template operator()<float>()' would be invalid: no matching member function for call to 'operator()'}}
template<class> concept E = C<[]<D>{}>;
static_assert(E<int>);
// expected-error@-1{{static assertion failed}}
// expected-note@-2{{because 'int' does not satisfy 'E'}}
// expected-note@-4{{does not satisfy 'C'}}
// expected-note@-11{{because 'Q.template operator()<float>()' would be invalid: no matching member function for call to 'operator()'}}
}
}

0 comments on commit 80a3a5f

Please sign in to comment.