-
Notifications
You must be signed in to change notification settings - Fork 13.5k
decltype((x)) inside lambda is considered odr-use if x is captured #34771
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
Comments
For the case [expr.prim.lambda]p20 says that references to outer entities within decltype expressions, other than the special decltype(x) form, are type-checked as if the variables were notionally captured. gets invoked, there's also the contradictory "lambda capture 'v' is not required to be captured for this use" warning for the following code (https://godbolt.org/g/6pC74v): template auto f(T &&v) { template auto g(T &&v) { #include <type_traits> int main() { |
Prior to P0588R1: [expr.prim.lambda.capture]/14: "Every occurrence of decltype((x)) where x is a possibly parenthesized id-expression that names an entity of automatic storage duration is treated as if x were transformed into an access to a corresponding data member of the closure type that would have been declared if x were an odr-use of the denoted entity." This is clear that Clang is correct that B and D give decltype((x)) as const int&, not int&. But the types of A and C are unclear. After P0588R1, the wording is a bit clearer: [expr.prim.id.unqual]/1: "If the entity is a local entity and naming it from outside of an unevaluated operand within the declarative region where the unqualified-id appears would result in some intervening lambda-expression capturing it by copy, the type of the expression is the type of a class member access expression ([expr.ref]) naming the non-static data member that would be declared for such a capture in the closure object of the innermost such intervening lambda-expression. [ Note: If that lambda-expression is not declared mutable, the type of such an identifier will typically be const qualified. ]" Here we see that A and C should have type int& and B and D should have type const int&. |
mentioned in issue llvm/llvm-bugzilla-archive#35669 |
mentioned in issue llvm/llvm-bugzilla-archive#36753 |
Extended Description
https://godbolt.org/g/NmA3ZP
#include <type_traits>
int main() {
int x = 1;
int&& y = static_cast<int&&>(x);
}
I expected this to compile cleanly, but static asserts B and D fail under clang.
Here is how i would argue for my expectation:
http://eel.is/c++draft/expr.prim.lambda#capture-11.sentence-3
-- "An id-expression that is not an odr-use refers to the original entity, never to a member of the closure type."
http://eel.is/c++draft/basic.def.odr#def:potentially_evaluated
-- "An expression is potentially evaluated unless it is an unevaluated operand or a subexpression thereof."
http://eel.is/c++draft/basic.def.odr#def:odr-used
-- "A variable x whose name appears as a potentially-evaluated expression ex is odr-used by ex unless [...]"
http://eel.is/c++draft/dcl.type.simple#4.sentence-3
-- "The operand of the decltype specifier is an unevaluated operand."
The text was updated successfully, but these errors were encountered: