Description
Issue description
We have an ambiguous grammar for member-declarator:
member-declarator:
- declarator virt-specifier-seq[opt] pure-specifier[opt]
- declarator brace-or-equal-initializer[opt]
pure-specifier:
=
0
The primary issue here is that foo = 0
matches both member-declarator productions. Secondarily, a declarator by itself is also ambiguous, but that's easily fixed by removing the [opt] from the second production and doesn't lead to two different program interpretations.
We then have:
- A brace-or-equal-initializer shall appear only in the declaration of a data member.
- A pure-specifier shall be used only in the declaration of a virtual function that is not a friend declaration.
... which make the two mutually exclusive but isn't itself a disambiguation rule.
Utterances like virtual FunctionType f = 0;
are valid, so we can't disambiguate based on the syntactic form of the declarator. In practice, implementations disambiguate based on whether decl-specifier-seq declarator declares a name with function type, and I believe that is the intent based on the rule in [temp.spec] that acquiring a function type through a dependent type is ill-formed.
Suggested resolution:
Option 1
Add a disambiguation rule, such as:
The token sequence
=
0
is treated as a pure-specifier if the type of the declarator-id [dcl.meaning.general] is a function type, and is otherwise treated as a brace-or-equal-initializer. [Note: If the member declaration acquires a function type through template instantiation, the program is ill-formed; see [temp.spec.general].]
... and remove the other ambiguity with a grammar change:
member-declarator:
- declarator virt-specifier-seq[opt] pure-specifier[opt]
- declarator brace-or-equal-initializer
[opt]
Option 2
Change the grammar to remove the ambiguity entirely:
member-declarator:
- declarator virt-specifier-seq[opt]
pure-specifier[opt]brace-or-equal-initializer[opt]declarator brace-or-equal-initializer[opt]
pure-specifier:
=
0
- A brace-or-equal-initializer shall appear only in the declaration of a data member or a function. [...]
- [...] . A brace-or-equal-initializer appearing in the declaration of a member function shall be of the form
=
0
, and is called a pure-specifier. A pure-specifier shall be used only in the declaration of a virtual function that is not a friend declaration.
Either way, this seems borderline editorial to me.