Skip to content

Commit

Permalink
[Clang] Treat default template argument as constant expressions (#107073
Browse files Browse the repository at this point in the history
)

We only check that a default argument is a converted constant expression
when using the default argument.

However, when parsing a default argument, we need to make sure to parse
it as a constant expression such as not ODR-use variables. (otherwise,
we would try to capture default template arguments of generic lambdas)

Fixes #107048
  • Loading branch information
cor3ntin authored Sep 4, 2024
1 parent 12d678a commit 030e4d0
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 1 deletion.
1 change: 1 addition & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ Bug Fixes to C++ Support
- Fix handling of ``_`` as the name of a lambda's init capture variable. (#GH107024)
- Fix an issue with dependent source location expressions (#GH106428), (#GH81155), (#GH80210), (#GH85373)
- Fixed a bug in the substitution of empty pack indexing types. (#GH105903)
- Clang no longer tries to capture non-odr used default arguments of template parameters of generic lambdas (#GH107048)

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Parse/ParseTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -959,7 +959,7 @@ Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) {
++CurTemplateDepthTracker;
EnterExpressionEvaluationContext ConstantEvaluated(
Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
DefaultArg = Actions.CorrectDelayedTyposInExpr(ParseInitializer());
DefaultArg = Actions.ActOnConstantExpression(ParseInitializer());
if (DefaultArg.isInvalid())
SkipUntil(tok::comma, tok::greater, StopAtSemi | StopBeforeMatch);
}
Expand Down
34 changes: 34 additions & 0 deletions clang/test/SemaCXX/cxx2a-template-lambdas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,37 @@ void foo() {

}
#endif

#if __cplusplus >= 202002L
namespace {
struct S {};
constexpr S gs;
void f() {
constexpr int x{};
const int y{};
auto b = []<int=x, int=y>{};
using A = decltype([]<int=x>{});

int z; // expected-note {{'z' declared here}}
auto c = []<int t=z>{
// expected-error@-1 {{no matching function for call to object of type}} \
// expected-error@-1 {{variable 'z' cannot be implicitly captured in a lambda with no capture-default specified}} \
// expected-note@-1 {{lambda expression begins here}} \
// expected-note@-1 4{{capture}} \
// expected-note@-1 {{candidate template ignored: substitution failure: reference to local variable 'z' declared in enclosing function}}
return t;
}();

auto class_type_global = []<S=gs>{};

static constexpr S static_s;
auto class_type_static = []<S=static_s>{};

constexpr S s; // expected-note {{'s' declared here}}
auto class_type = []<S=s>{};
// expected-error@-1 {{variable 's' cannot be implicitly captured in a lambda with no capture-default specified}} \
// expected-note@-1 {{lambda expression begins here}} \
// expected-note@-1 4{{capture}}
}
}
#endif

0 comments on commit 030e4d0

Please sign in to comment.