Skip to content

Templated lambda ends up with dependent type in C++11 #113792

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
tbaederr opened this issue Oct 27, 2024 · 3 comments
Open

Templated lambda ends up with dependent type in C++11 #113792

tbaederr opened this issue Oct 27, 2024 · 3 comments
Assignees
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" lambda C++11 lambda expressions

Comments

@tbaederr
Copy link
Contributor

This is an issue for the bug from #108598

This code:

template<typename T>
constexpr T outer() {
  return []<T x>() { return x; }.template operator()<123>();
}
static_assert(outer<int>() == 123);

ends up with a dependent type that we assert on in codegen.

This starts when we deduce the type of the call operator, which is dependent in C++11 but auto in later versions:

case DeclSpec::TST_unspecified:
// If this is a missing declspec in a block literal return context, then it
// is inferred from the return statements inside the block.
// The declspec is always missing in a lambda expr context; it is either
// specified with a trailing return type or inferred.
if (S.getLangOpts().CPlusPlus14 &&
declarator.getContext() == DeclaratorContext::LambdaExpr) {
// In C++1y, a lambda's implicit return type is 'auto'.
Result = Context.getAutoDeductType();
break;
} else if (declarator.getContext() == DeclaratorContext::LambdaExpr ||
checkOmittedBlockReturnType(S, declarator,
Context.DependentTy)) {
Result = Context.DependentTy;
break;
}

and we never seem to clean this up.

@tbaederr tbaederr added the clang:frontend Language frontend issues, e.g. anything involving "Sema" label Oct 27, 2024
@llvmbot
Copy link
Member

llvmbot commented Oct 27, 2024

@llvm/issue-subscribers-clang-frontend

Author: Timm Baeder (tbaederr)

This is an issue for the bug from https://github.com//pull/108598

This code:

template&lt;typename T&gt;
constexpr T outer() {
  return []&lt;T x&gt;() { return x; }.template operator()&lt;123&gt;();
}
static_assert(outer&lt;int&gt;() == 123);

ends up with a dependent type that we assert on in codegen.

This starts when we deduce the type of the call operator, which is dependent in C++11 but auto in later versions:

case DeclSpec::TST_unspecified:
// If this is a missing declspec in a block literal return context, then it
// is inferred from the return statements inside the block.
// The declspec is always missing in a lambda expr context; it is either
// specified with a trailing return type or inferred.
if (S.getLangOpts().CPlusPlus14 &&
declarator.getContext() == DeclaratorContext::LambdaExpr) {
// In C++1y, a lambda's implicit return type is 'auto'.
Result = Context.getAutoDeductType();
break;
} else if (declarator.getContext() == DeclaratorContext::LambdaExpr ||
checkOmittedBlockReturnType(S, declarator,
Context.DependentTy)) {
Result = Context.DependentTy;
break;
}

and we never seem to clean this up.

@cor3ntin
Copy link
Contributor

@mizvekov

@mizvekov mizvekov self-assigned this Oct 27, 2024
@tbaederr
Copy link
Contributor Author

tbaederr commented Dec 1, 2024

@mizvekov Any update on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" lambda C++11 lambda expressions
Projects
None yet
Development

No branches or pull requests

5 participants