Skip to content
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

[temp.res.general] p5: dependent qualified-id and using-declarator #4791

Open
xmh0511 opened this issue Aug 4, 2021 · 12 comments · May be fixed by #4793
Open

[temp.res.general] p5: dependent qualified-id and using-declarator #4791

xmh0511 opened this issue Aug 4, 2021 · 12 comments · May be fixed by #4793
Assignees

Comments

@xmh0511
Copy link
Contributor

xmh0511 commented Aug 4, 2021

In the current draft, [basic.lookup.qual#general-2] specifies the qualified name, where it seems that it intends to use qualified-id to cover such as a simple-type-specifier that has the form nested-name-specifieropttype-name. In other words, they all can form nested-name-specifier identifier on syntax. However, they are not the same thing on grammar.

Furthermore, [temp.res#general-5] also intends to use qualified-id to cover a simple-type-specifier that may have the aforementioned form. The meaning of the qualified-id is vague in such use, consider a using-declarator, which has the form nested-name-specifier unqualified-id

using T::identifier;

Does that mean any rule that uses the qualified-id to cover the form that is not a qualified-id on grammar can also impose on the using-declarator that has the same form? It seems a defect in the current standard. This issue is also mentioned on SO.

This example would illustrate the vague

struct X{
    typedef int Type;
};
template<typename T>
struct Test:T{
    using T::Type;  // #1
};
int main(){
   Test<X> obj;
}

GCC agrees on this example while Clang reports an error. If we say the using-declarator at #1 is considered as a qualified-id, then Clang is right due to [temp.res#general-5] imposes on it.

A qualified-id whose terminal name is dependent and that is in a type-only context is considered to denote a type.

I don't think it's a good example here, I still think Clang is wrong, even if T::Type is not considered to denote a type, I didn't see any big deal at #1. This issue intends to expose that the extra given meaning to qualified-id would make its meaning be a mess in some rules that mention qualified-id.

@xmh0511 xmh0511 changed the title The qualified-id has exceeded its designated extent in the intent of certain rules The qualified-id has exceeded its grammar meaning in the intent of certain rules Aug 4, 2021
@jensmaurer
Copy link
Member

First of all, a qualified name as defined in [basic.lookup.qual.general] is very much different from a qualified-id, and intentionally so.

Second, [temp.res.general] p5 expressly uses qualified-id and in the next sentence discusses using-declarator; applying an "if and only if" clarification to the second sentence in p5 fixes that issue without messing with qualified-id.

@opensdh, any thoughts here?

@jensmaurer jensmaurer changed the title The qualified-id has exceeded its grammar meaning in the intent of certain rules [temp.res.general] p5: dependent using-declaratorThe qualified-id has exceeded its grammar meaning in the intent of certain rules Aug 4, 2021
@jensmaurer jensmaurer changed the title [temp.res.general] p5: dependent using-declaratorThe qualified-id has exceeded its grammar meaning in the intent of certain rules [temp.res.general] p5: dependent using-declarator Aug 4, 2021
@xmh0511
Copy link
Contributor Author

xmh0511 commented Aug 4, 2021

Consider this example

struct Test{
  typedef int type;
};
Test::type a = 0; //#1

Is the terminal name in Test::type called a qualified name? I think it should be a qualified name, however, we cannot find simple-type-specifier in the list of [basic.lookup.qual#general-2]. Presumably, the rule intends to category the simple-type-specifier into qualified-id, otherwise, it cannot be interpreted. On grammar, a simple-type-specifier is not a qualified-id. @opensdh has confirmed this issue and said it could be considered a defect, please see this comment.

@jensmaurer
Copy link
Member

jensmaurer commented Aug 4, 2021

I'm certainly not going to address any specification ambiguities of a qualified-id vs. a simple-type-specifier vs. a using-declarator etc. in an editorial issue.

However, it seems plausible to add simple-type-specifier to the list in [basic.lookup.qual.general] p2.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Aug 4, 2021

@jensmaurer Agree. I also think the first sentence in [temp.res#general-5] should also avoid using qualified-id. Consider this example

template<class T>
struct C{
 T::type member_;
};

T::type is the decl-specifier of the member-declaration as said in [temp.res#general-4]. In the grammar tree of decl-specifier, it is impossible to be a qualified-id, however [temp.res#general-5] intends to use qualified-id to cover the simple-type-specifier(T::type). I think we could use "qualified name" to replace the qualified-id in the first sentence in [temp.res#general-5].

@jensmaurer
Copy link
Member

No, type is the qualified name here, not T::type, so this would be saying something different.

I think this is the operative paragraph where we differentiate between qualified-id and simple-type-specifier in a dependent context. I think it's too early to talk about either here, and we should simply talk about the grammatical form nested-name-specifier :: identifier and its disambiguation here.

@jensmaurer
Copy link
Member

If we already know we have a simple-type-specifier (because that's the only possibility per the grammar), we don't need temp.res.general p5 to tell us we're dealing with a type. It's only in the case where the general grammar rules would allow parsing as a qualified-id that we need the type-only context rules.

@jensmaurer jensmaurer linked a pull request Aug 4, 2021 that will close this issue
@xmh0511
Copy link
Contributor Author

xmh0511 commented Aug 5, 2021

I think this is the operative paragraph where we differentiate between qualified-id and simple-type-specifier in a dependent context. I think it's too early to talk about either here,

Violent agree! qualified-id can only appear as an expression, if we directly say it's a qualified-id, it has already meant it's an expression rather than anything others. The ambiguous case is

typename T::type * id;

T::type could be either a qualified-id or a type-specifier. However, we cannot arbitrarily say it's just a qualified-id and try to use [temp.res#general-5] to state it's considered to denote a type. It's contradictory.

In addition, I think the grammar nested-name-specifier :: identifier is not sufficient to list all possible components, such as T::type<template-argument-list>.

@jensmaurer
Copy link
Member

No, typename T::type is exactly not ambiguous (because it's a typename-specifier). Without typename, it's ambiguous, though.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Aug 5, 2021

That has enforced the subject of this issue. Since the component whose terminal name is in type-only context is one of them: typename-specifier, nested-name-specifier, elaborated-type-specifier, class-or-decltype, type-specifier, decl-specifier. How could these components be a qualified-id?

@xmh0511
Copy link
Contributor Author

xmh0511 commented Aug 5, 2021

T::type * id;

We could say T::type may be a qualified-id or a simple-type-specifier(it's ambiguous in this context). If its terminal name is in a type-only context, we say T::type is interpreted as a simple-type-specifier; otherwise, it's... However, if we say it's a qualified-id at the beginning, we have already designated it's just an expression, an expression can never be a type as per [expr.prim.id.qual#5].

I cannot figure out a simple way that can avoid use qualified-id but can mention all the grammars whose forms look like the qualified-id. Could we say

A potential qualified-id whose terminal name...

To emphasize that it's not necessary to be a qualified-id eventually?

@jensmaurer
Copy link
Member

jensmaurer commented Aug 5, 2021

I think we only need to discuss the two forms "nested-name-specifier identifier" and "nested-name-specifier template(opt) simple-type-id". Everything else is already unambiguous between simple-type-specifier and qualified-id.

@jensmaurer jensmaurer changed the title [temp.res.general] p5: dependent using-declarator [temp.res.general] p5: dependent qualified-id and using-declarator Aug 5, 2021
@jensmaurer jensmaurer self-assigned this Aug 5, 2021
@opensdh
Copy link
Contributor

opensdh commented Aug 31, 2021

For the record, I don't have anything to add here beyond what we said in the CWG review, which was itself not a complete answer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants