Skip to content

CWG3122 [temp.dep.constexpr] Inadequate value-dependence for reflect-expressions #808

@katzdm

Description

@katzdm

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-expression is value-dependent if

  • it is of the form ^^ reflection-name and either the reflection-name is

    • is a dependent qualified name,
    • is a dependent namespace-name, or
    • is the name of a template parameter , or
    • names a dependent member of the current instantiation ([temp.dep.type]),

    or lookup for the reflection-name finds a declaration that inhabits a scope corresponding to a templated entity,

  • it is of the form ^^ type-id and the type-id denotes a dependent type, or

  • it is of the form ^^ id-expression and the id-expression is 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.
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions