struct foo_bar; typedef foo_bar bar; struct foo_bar { typedef int baz; bar::baz ii; }; t.C:7: error: ‘baz’ in class ‘bar’ does not name a type or as originally reported: struct foo_bar; namespace foo { typedef foo_bar bar; }; struct foo_bar { typedef int baz; foo::bar::baz ii; }; t.C:9: error: ‘baz’ in class ‘foo::bar’ does not name a type moving the declaration of ii out of foo_bar, the code is accepted: struct foo_bar; typedef foo_bar bar; struct foo_bar { typedef int baz; }; bar::baz ii; EDG happily accepts the code in strict-ansi mode.
What I can find that supports rejecting the code is: 3.4.3(1) "Qualified name lookup": "If the name found is not a class-name (clause 9) or namespace-name (7.3.1), the program is ill-formed." 7.1.3 "The typedef specifier" it says: "A name declared with the typedef specifier becomes a typedef-name." but then the last example should be rejected as well?
(In reply to comment #1) > What I can find that supports rejecting the code is: > > 3.4.3(1) "Qualified name lookup": > > "If the name found is not a class-name (clause 9) or namespace-name > (7.3.1), the program is ill-formed." > > 7.1.3 "The typedef specifier" it says: > > "A name declared with the typedef specifier becomes a typedef-name." > > but then the last example should be rejected as well? I think this isn't the problem you run into. The real problem with the typedef is that if you use typedef_name::nested_name from within the class that typedef_name points to, then typedef_name is still an incomplete type because you haven't reached the closing brace yet. In your last example, you *have* reached the closing brace and the pointed class is complete so using typedef_name::nested_name succeeds. W.
Yes, this is what debugging cc1plus reveals - the typedef-name type decl is still incomplete. Now, the question is if this is valid C++ or not ;) Using foo_bar instead of bar works as well (though foo_bar also is incomplete).
That is the following: struct foo_bar; typedef foo_bar bar; struct foo_bar { typedef int baz; foo_bar::baz ii; }; is fine.
I believe these cases to be valid.
Testing a patch.
Subject: Bug 33516 Author: jakub Date: Fri Nov 2 21:37:35 2007 New Revision: 129862 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=129862 Log: PR c++/33516 * parser.c (cp_parser_nested_name_specifier_opt): Use TYPE_MAIN_VARIANT (new_scope) as scope if new_scope is an incomplete typedef of currently open class. * g++.dg/lookup/typedef1.C: New test. Added: trunk/gcc/testsuite/g++.dg/lookup/typedef1.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/parser.c trunk/gcc/testsuite/ChangeLog
Fixed on the trunk so far.
Closing 4.1 branch.
Closing 4.2 branch, fixed in 4.3.