This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: Inner template classes confuse gcc-2.95 and gcc-2.95.1 compiler
- To: gcc-bugs at gcc dot gnu dot org
- Subject: Re: Inner template classes confuse gcc-2.95 and gcc-2.95.1 compiler
- From: Paul Burchard <burchard at pobox dot com>
- Date: Sat, 28 Aug 1999 02:38:07 -0700
- CC: Michael Vance <briareos at lokigames dot com>, Alexander Zvyagin <zvyagin at gams dot ihep dot su>
- References: <37C7806B.83B0E877@pobox.com>
Here is what I was able to determine about the following
frequently-reported bug about member templates (using Alexander
Zvyagin's version):
// Build don't link:
class A {
template <class T> class B {};
class C {
B<int> b; // gets bogus error - not a template
};
};
The name lookup logic seems to have some problems with intermediate
class scopes (between namespace scope and current class scope). Here is
what happens during the parse:
1. When `B<int>' is encountered, lookup_template_class() does not find
`B' in the current class scope `A::C' (that's correct), so it punts to
lookup_name_nonclass() (i.e., lookup_name_real() with the "nonclass
scope" flag set -- whatever that means exactly).
2. lookup_name_real() runs up the chain of bindings for the identifier
`B', checking for the condition LOCAL_BINDING_P. In our case, there is
exactly one binding for `B' (detailed below), which indeed refers to the
desired template `A::B<T>'. But this binding fails to satisfy
LOCAL_BINDING_P (why?).
3. Since that failed, lookup_name_real() goes on to check the enclosing
namespace scopes for a template `B', but at this point it's too late --
we've already missed our chance to find the correct `B'.
I'm actually a little confused about the term "nonclass scope" in GCC.
"Class scope" seems to mean "in the scope of the class currently being
defined". But is "nonclass scope" its opposite, as would be required
for the above logic to be correct? Or does it mean "not in the scope of
ANY class" (i.e., namespace scope)? Could this ambiguity be the source
of the bug?
In case it helps, here is what the binding for `B' actually contains:
<binding 0x8289e9c allocated from permanent_obstack
permanent scope 0x8288cb0
value <template_decl 0x8289dd0 B
type <record_type 0x8281698 B<T> allocated from
permanent_obstack
permanent type_5 VOID
size <integer_cst 0x8277f90 constant permanent 0>
align 1 symtab 0 alias set -1 fields <type_decl 0x8289f14 B>
context <record_type 0x82811c4 A>
n_parents 0 use_template=0 interface-unknown
pointer_to_this <pointer_type 0x8281744> chain <type_decl
0x8289d58 B<T>>>
allocated from permanent_obstack
permanent ignored VOID file notatempl3.C line 3
align 1 context <record_type 0x82811c4 A>
arguments <tree_list 0x8281658 allocated from permanent_obstack
permanent
purpose <integer_cst 0x8281640 constant permanent
0x100000000>
value <tree_vec 0x828162c type <template_decl 0x8289dd0 B>
allocated from permanent_obstack
permanent
elt 0 <tree_list 0x8281618>>>
result <type_decl 0x8289d58 B<T> type <record_type 0x8281698
B<T>>
allocated from permanent_obstack
permanent VOID file notatempl3.C line 3
align 1 context <record_type 0x82811c4 A> chain <type_decl
0x8281558 T>>
decl-main-variant 0x8289dd0
chain <type_decl 0x82813b4 A type <record_type 0x82811c4 A>
allocated from permanent_obstack
permanent nonlocal VOID file notatempl3.C line 2
align 1 context <record_type 0x82811c4 A>
decl-main-variant 0x82813b4 chain <type_decl 0x828a8a0 C>>>>
--
----------------------------------------------------------------------
Paul Burchard <burchard@pobox.com> http://www.pobox.com/~burchard/
----------------------------------------------------------------------