This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi,I have been investigating this very old and very weird issue where we wrongly reject:
class Foo { int u, v, w, x; typedef struct Bar { } Bar; virtual void foo(void) { struct Bar bar; } }; 46206.C: In member function ‘virtual void Foo::foo()’: 46206.C:6:12: error: using typedef-name ‘Foo::Bar’ after ‘struct’ 46206.C:4:26: note: ‘Foo::Bar’ has a previous declaration herewhereas we don't reject variants with one less data member, say x, or non-virtual foo, all sorts of variants corresponding to a smaller Foo!!
I figured out that when we parse "typedef struct Bar { } Bar;" we create two TYPE_DECL: first, one marked as DECL_IMPLICIT_TYPEDEF_P in pushtag_1 (via create_implicit_typedef); then a second, non-implicit, one in grokdeclarator, via build_lang_decl (TYPE_DECL... ). When we do lookup for "struct Bar bar", it happens that the *second* one is found, thus the check in check_elaborated_type_specifier triggers.
The latter function is called by lookup_and_check_tag, with the decl returned by lookup_name_prefer_type (name, 2). The latter, in turn, ends up calling lookup_name_real_1 which has:
/* If this is the kind of thing we're looking for, we're done. */ if (qualify_lookup (iter->value, flags)) binding = iter->value; else if ((flags & LOOKUP_PREFER_TYPES) && qualify_lookup (iter->type, flags)) binding = iter->type; else binding = NULL_TREE;and it happens that the first qualify_lookup succeeds but with iter->value which is the variant of the Bar TYPE_DECL with DECL_IMPLICIT_TYPEDEF_P not set. On the other hand, iter->type is the Ok variant, that which would not trigger the error.
Then I noticed the following comment in name_lookup.c, around line 4890, in lookup_type_scope_1:
We check ITER->TYPE before ITER->VALUE in order to handle typedef struct C {} C; correctly. */and after this comment, both pairs of qualify_lookup are called in that order. Thus I started seriously suspecting that something may be wrong in the if-else above, that is, that we really want something with iter->type *before* iter->value there too: the attached patchlet p works for the testcase and passes bootstrap & test. Does it make sense to you?
Final observation: in many cases, like for example, variants of the testcase with one less data member, what happens is that iter->type and iter->value are *both* the same variant of the TYPE_DECL Bar, the one which is fine, has DECL_IMPLICIT_TYPEDEF_P set. Thus the ordering doesn't matter. Frankly, at the moment I'm not sure to understand how exactly when the class becomes bigger the iter->type and iter->value become different and becomes important to handle the former first.
Fiuuuu ;) Thanks! Paolo. /////////////////////
Attachment:
p
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |