Skip to content

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

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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions