[c++]pt.c:most_specialized_class appears to substitute outer args for inner params

View: New views
2 Messages — Rating Filter:   Alert me  

[c++]pt.c:most_specialized_class appears to substitute outer args for inner params

by Larry Evans-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

The following code around trunk/gcc/cp/pt.c:15514:

15513 partial_spec_args = INNERMOST_TEMPLATE_ARGS (partial_spec_args);
15514 partial_spec_args = tsubst_template_args
15515  (partial_spec_args, outer_args, tf_none, NULL_TREE);

as shown here:

http://gcc.gnu.org/viewcvs/trunk/gcc/cp/pt.c?view=markup&pathrev=153822

appears to substitute outer_args in the place where inner parameters
are located.  Am I reading the code wrong?  I ask because gdb seems to
show this happening with the following code:

--{-- test code --
   struct
outer_arg0
;
   struct
inner_arg0
;
   struct
inner_arg1
;

//#define CLASS_SCOPE_SPECIALIZATION
   template
   < class OuterArg0
   >
   struct
outer_tmpl
{
       template
       < typename InnerArg0
       , typename InnerArg1
       >
       struct
     inner_tmpl
   #ifndef CLASS_SCOPE_SPECIALIZATION
     ;
   #else
     {};
       template
       < typename InnerArg0
       >
       struct
     inner_tmpl
       < InnerArg0
       , inner_arg1
       >
     {
             typedef
           InnerArg0
         inner_typdef
         ;
     };
   #endif
};

#ifndef CLASS_SCOPE_SPECIALIZATION
   template
   < //class OuterArg0
   >
       template
       < typename InnerArg0
       >
       struct
outer_tmpl
   < outer_arg0
   >::
     inner_tmpl
       < InnerArg0
       , inner_arg1
       >
     {
             typedef
           InnerArg0
         inner_typdef
         ;
     };
#endif

     typedef
   outer_tmpl<outer_arg0>
   ::inner_tmpl
   < inner_arg0
   , inner_arg1
   >
   ::inner_typdef //error here.
outer_inner_type
;
--}-- test code --

To be more specific, the following is part of a gdb session:

--{-- gdb session --

Breakpoint 5, tsubst_template_args (t=0x7f89a3765d80,
args=0x7f89a3788750, complain=0, in_decl=0x0) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/pt.c:8136
[@@]tsubst_template_args:.TREE_VEC_LENGTH(t)[@@]
[***]len=
$6 = 2
[***]inp t=
  <tree_vec 0x7f89a3765d80

     elt 0 <template_type_parm 0x7f89a3786a80 InnerArg0 type_0 type_6 VOID
         align 8 symtab 0 alias set -1 canonical type 0x7f89a3786000
        index 0 level 1 orig_level 1
         chain <type_decl 0x7f89a3786b40 InnerArg0>>

     elt 1 <record_type 0x7f89a3775e40 inner_arg1 type_5 type_6 VOID
         align 8 symtab 0 alias set -1 canonical type 0x7f89a3775e40
         full-name "struct inner_arg1"
         no-binfo use_template=0 interface-unknown
         chain <type_decl 0x7f89a3775f00 inner_arg1>>>
[***]inp args=
  <tree_vec 0x7f89a3788750

     elt 0 <record_type 0x7f89a3775b40 outer_arg0 type_5 type_6 VOID
         align 8 symtab 0 alias set -1 canonical type 0x7f89a3775b40
         full-name "struct outer_arg0"
         no-binfo use_template=0 interface-unknown
         chain <type_decl 0x7f89a3775c00 outer_arg0>>>
[***]bt:
#0  tsubst_template_args (t=0x7f89a3765d80, args=0x7f89a3788750,
complain=0, in_decl=0x0) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/pt.c:8136
#1  0x0000000000586ed4 in most_specialized_class (type=0x7f89a3789e40,
tmpl=0x7f89a37869c0) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/pt.c:15439
#2  0x000000000053fa43 in instantiate_class_template
(type=0x7f89a3789e40) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/pt.c:7324
#3  0x0000000000644002 in complete_type (type=0x7f89a3789e40) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/typeck.c:130
#4  0x000000000061507d in cp_parser_nested_name_specifier_opt
(parser=0x7f89a42cca50, typename_keyword_p=0 '\0', check_dependency_p=1
'\001', type_p=0 '\0', is_declaration=0 '\0') at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/parser.c:4255
#5  0x0000000000621ba0 in cp_parser_simple_type_specifier
(parser=0x7f89a42cca50, decl_specs=0x7fffac4025b0, flags=1) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/parser.c:11947
#6  0x0000000000621795 in cp_parser_type_specifier
(parser=0x7f89a42cca50, flags=1, decl_specs=0x7fffac4025b0,
is_declaration=1 '\001', declares_class_or_enum=0x7fffac402534,
is_cv_qualifier=0x7fffac402533 "") at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/parser.c:11749
#7  0x000000000061d3ff in cp_parser_decl_specifier_seq
(parser=0x7f89a42cca50, flags=1, decl_specs=0x7fffac4025b0,
declares_class_or_enum=0x7fffac4025ac) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/parser.c:9130
#8  0x000000000061ce17 in cp_parser_simple_declaration
(parser=0x7f89a42cca50, function_definition_allowed_p=1 '\001') at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/parser.c:8792
#9  0x000000000061cdcb in cp_parser_block_declaration
(parser=0x7f89a42cca50, statement_p=0 '\0') at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/parser.c:8753
#10 0x000000000061cbb5 in cp_parser_declaration (parser=0x7f89a42cca50)
at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/parser.c:8658
#11 0x000000000061c827 in cp_parser_declaration_seq_opt
(parser=0x7f89a42cca50) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/parser.c:8549
#12 0x0000000000612cd7 in cp_parser_translation_unit
(parser=0x7f89a42cca50) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/parser.c:3058
#13 0x0000000000639680 in c_parse_file () at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/cp/parser.c:22960
#14 0x00000000007a4773 in c_common_parse_file (set_yydebug=0) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/c-opts.c:1302
#15 0x0000000000bc2112 in compile_file () at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/toplev.c:1049
#16 0x0000000000bc434f in do_compile () at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/toplev.c:2408
#17 0x0000000000bc4425 in toplev_main (argc=2, argv=0x7fffac402948) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/toplev.c:2450
#18 0x00000000007b2cb0 in main (argc=2, argv=0x7fffac402948) at
/home/evansl/download/gcc/svn/patch.none.gdb/build/../src/gcc/main.c:35

--}-- gdb session --

I guessing that this misplaced substitution causes the compile to fail
with error message:

--{-- compilation --
make
/home/evansl/download/gcc/svn/patch.none/install/bin/g++ -c
bug.scope_specialization.cpp
bug.scope_specialization.cpp:84:3: error: 'inner_typdef' in class
'outer_tmpl<outer_arg0>::inner_tmpl<inner_arg0, inner_arg1>' does not
name a type
make: *** [bug.scope_specialization.o] Error 1
--}-- compilation --

Any clues about what's going wrong would be appreciated.
I would be happy to send anyone the gdb command file used
to set the breakpoints and create the above gdb session.

-regards,
Larry

(PS.  I'm obviously using an earlier version of the code rather than
that cited above.  The svn info command produces:

~/download/gcc/svn/patch.none.gdb/src $ svn info
Path: .
URL: svn://gcc.gnu.org/svn/gcc/trunk
Repository Root: svn://gcc.gnu.org/svn/gcc
Repository UUID: 138bc75d-0d04-0410-961f-82ee72b054a4
Revision: 152768
Node Kind: directory
Schedule: normal
Last Changed Author: rguenth
Last Changed Rev: 152768
Last Changed Date: 2009-10-14 09:14:44 -0500 (Wed, 14 Oct 2009)

)


Re: [c++]pt.c:most_specialized_class appears to substitute outer args for inner params

by Larry Evans-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 11/02/09 22:39, Larry Evans wrote:

> The following code around trunk/gcc/cp/pt.c:15514:
>
> 15513     partial_spec_args = INNERMOST_TEMPLATE_ARGS (partial_spec_args);
> 15514     partial_spec_args = tsubst_template_args
> 15515       (partial_spec_args, outer_args, tf_none, NULL_TREE);
>
> as shown here:
>
> http://gcc.gnu.org/viewcvs/trunk/gcc/cp/pt.c?view=markup&pathrev=153822
>
> appears to substitute outer_args in the place where inner parameters
> are located.  Am I reading the code wrong?  I ask because gdb seems to
> show this happening with the following code:
>
> --{-- test code --
>   struct
> outer_arg0
> ;
>   struct
> inner_arg0
> ;
>   struct
> inner_arg1
> ;
>
> //#define CLASS_SCOPE_SPECIALIZATION
>   template
>   < class OuterArg0
>   >
>   struct
> outer_tmpl
> {
>       template
>       < typename InnerArg0
>       , typename InnerArg1
>       >
>       struct
>     inner_tmpl
>   #ifndef CLASS_SCOPE_SPECIALIZATION
>     ;
>   #else
>     {};
>       template
>       < typename InnerArg0
>       >
>       struct
>     inner_tmpl
>       < InnerArg0
>       , inner_arg1
>       >
>     {
>             typedef
>           InnerArg0
>         inner_typdef
>         ;
>     };
>   #endif
> };
>
> #ifndef CLASS_SCOPE_SPECIALIZATION
>   template
>   < //class OuterArg0
>   >
>       template
>       < typename InnerArg0
>       >
>       struct
> outer_tmpl
>   < outer_arg0
>   >::
>     inner_tmpl
>       < InnerArg0
>       , inner_arg1
>       >
>     {
>             typedef
>           InnerArg0
>         inner_typdef
>         ;
>     };
> #endif
>
>     typedef
>   outer_tmpl<outer_arg0>
>   ::inner_tmpl
>   < inner_arg0
>   , inner_arg1
>   >
>   ::inner_typdef //error here.
> outer_inner_type
> ;
> --}-- test code --
[snip]
Just adding an outer_tmpl specialization solves the problem:

   template
   <// class OuterArg0
   >
   struct
outer_tmpl
   < outer_arg0
   >
{
       template
       < typename InnerArg0
       , typename InnerArg1
       >
       struct
     inner_tmpl
     ;
};