[Bug c++/69701] "v.operator T()" incorrectly parsed if "v.T()" present.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69701 Language Lawyer changed: What|Removed |Added CC||language.lawyer at gmail dot com --- Comment #7 from Language Lawyer --- Another example related to CWG2396: struct B { struct S {}; operator S(); }; auto v = B{}.operator struct S(); // error: 'struct B' has no member named 'operator S' It can be checked that GCC injects unrelated `struct S` into the global namespace and then tries to find `operator struct ::S` in B. However, according to P1787R6 [basic.lookup.unqual]/5: An unqualified name that is a component name of a type-specifier or ptr-operator of a conversion-type-id is looked up in the same fashion as the conversion-function-id in which it appears. In an elaborated-type-specifier of the form "class-key identifier", such as `struct S`, identifier is a component name ([dcl.type.elab]/1), so S shall be searched in B first.
[Bug c++/69701] "v.operator T()" incorrectly parsed if "v.T()" present.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69701 --- Comment #6 from Andrew Pinski --- http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1291 [Accepted at the November, 2020 meeting as part of paper P1787R6 and moved to DR at the February, 2021 meeting.] So there is a defect report in this area after all
[Bug c++/69701] "v.operator T()" incorrectly parsed if "v.T()" present.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69701 Andrew Pinski changed: What|Removed |Added Keywords|accepts-invalid | --- Comment #5 from Andrew Pinski --- So I think clang and MSVC have a bug in this area too. See basic.lookup.classref/7 : If the id-expression is a conversion-function-id, its conversion-type-id is first looked up in the class of the object expression (11.8) and the name, if found, is used. Otherwise it is looked up in the context of the entire postfix-expression. In each of these lookups, only names that denote types or templates whose specializations are types are considered. [Example: struct A { }; namespace N { struct A { void g() { } template operator T(); }; } int main() { N::A a; a.operator A(); // calls N::A::operator N::A } — end example] If we take the example, clang and MSVC calls N::A::operator ::A and not what the standard says. GCC I think is still wrong in the original testcase I think because B::A does not represent a type . In my example in comment #4, GCC and ICC does the correct thing and selects the correct type.
[Bug c++/69701] "v.operator T()" incorrectly parsed if "v.T()" present.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69701 Andrew Pinski changed: What|Removed |Added Ever confirmed|0 |1 Last reconfirmed||2021-12-03 Keywords||accepts-invalid Status|UNCONFIRMED |NEW --- Comment #4 from Andrew Pinski --- Here is a different testcase which shows we also have an accepts invalid: class A {}; class B { typedef int AT; public: operator AT () const noexcept { return {}; } typedef int A; }; int main() { B b; b.operator A(); } I have not looked up in the standard which A is supposed to be found here (for b.operator A) is it B::A or ::A?
[Bug c++/69701] "v.operator T()" incorrectly parsed if "v.T()" present.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69701 --- Comment #3 from Andrew Pinski --- ICC also rejects this for the same reason as GCC while both MSVC and clang accept it. Maybe there is a defect report about this.
[Bug c++/69701] "v.operator T()" incorrectly parsed if "v.T()" present.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69701 --- Comment #1 from Andrew Pinski --- I think this should be diagnose differently in that A changes meanings inside the class. That is if we used: operator A () const noexcept { return {}; } We get the following error message: t9.cc:8:12: error: declaration of ‘void B::A()’ [-fpermissive] void A() {} ^ t9.cc:2:7: error: changes meaning of ‘A’ from ‘class A’ [-fpermissive] class A {}; ^
[Bug c++/69701] "v.operator T()" incorrectly parsed if "v.T()" present.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69701 --- Comment #2 from Eric Fiselier --- @Andrew The in-class diagnostics are pretty good. My concern is that users outside the class cannot name the conversion operator. I don't think they care that "A" changes meaning *within* B. I don't think any error should be emitted for the reproducer.