-
Notifications
You must be signed in to change notification settings - Fork 7
Description
Full name of submitter: Dan Katz
Reference: [temp.dep.constexpr]
Issue description
[temp.dep.constexpr]/7.1.4 says that ^^operand is value-dependent when operand names a dependent member of the current instantiation, e.g.,
template <typename T>
struct TCls {
static T mem;
static constexpr info R = type_of(^^mem); // '^^mem' is value-dependent.
};This is good, but it doesn't go far enough: If the enclosing template is instead a function template, then the existing conditions for value-dependence fail to apply.
template <typename T>
consteval void f() {
T v;
info R = type_of(^^v);
// not currently value-dependent; really needs to be.
}Annotations are also affected:
template <int K>
int f() {
[[=K]] int v;
return annotations_of(^^v).size();
// Also not value-dependent, but really ought to be (even though 'v' is neither type nor value dependent).
}Applying parent_of in such a situation likewise proves a problem. Some of these circumstances would demand that the compiler surface a reflection that represents a dependent type; others become unnecessarily wide IFNDR traps.
Suggested resolution
The reflection of any templated entity (and more: any entity with a declaration in a templated context enclosing the reflect-expression) should be value-dependent.
Modify [temp.dep.constexpr]/7 as follows:
A
reflect-expressionis value-dependent if
it is of the form
^^reflection-nameand either thereflection-nameis
isa dependent qualified name,isa dependentnamespace-name, oristhe name of a template parameter, ornames a dependent member of the current instantiation ([temp.dep.type]),or lookup for the
reflection-namefinds a declaration that inhabits a scope corresponding to a templated entity,it is of the form
^^type-idand thetype-iddenotes a dependent type, orit is of the form
^^id-expressionand theid-expressionis value-dependent.
Note that the value-dependent id-expression bullet remains necessary to handle the case when the operand is a template-id (which is not a reflection-name), e.g.,
template <typename T>
static constexpr T zero = 0;
template <typename T>
unsigned f() {
return size_of(^^zero<T>);
// 'zero<T>' is a value-dependent id-expression that is not a reflect-expression.
}