This is the mail archive of the gcc-bugs@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]

G++ test failure robertl/eb127.C


Okay, I'm getting tired of the autobuilder messages... let's see how
far I can get chasing this one.

$ ./cc1plus eb127.ii -quiet -fmessage-length=0
eb127.C: In method `void ODEsolver::timeloop (vector<double, 
	 allocator<double> > &, double, double, double)':
eb127.C:49: Internal compiler error 20000406.
eb127.C:49: Please submit a full bug report.
eb127.C:49: See <URL:http://www.gnu.org/software/gcc/bugs.html> 
	    for instructions.

(gdb) bt
#0  my_friendly_abort (i=145) at cp/typeck2.c:305
#1  0x82474a9 in build_x_function_call 
    (function=0x40409000, params=0x40409060, decl=0x40405540) 
    at cp/typeck.c:2673
#2  0x826261a in finish_call_expr (fn=0x91, args=0x40409060, koenig=0)
    at cp/semantics.c:1480
#3  0x823c247 in yyparse () at parse.y:1488
#4  0x804b8b2 in compile_file (name=0x40108140 "\001") at toplev.c:2399
#5  0x804eb69 in main (argc=4, argv=0xbffffaf4) at toplev.c:4680
(gdb) up
(gdb) call debug_tree (function)
 <offset_ref 0x40409000
    type <offset_type 0x406c0980
	basetype <record_type 0x406a4e00 ODEsolver>>

    arg 0 <indirect_ref 0x40405540
        type <record_type 0x406a4e00 ODEsolver>
        arg 0 <nop_expr 0x40405520 type <pointer_type 0x406a4e80>
            arg 0 <parm_decl 0x406c0e00 this>>>
    arg 1 <field_decl 0x406a6380 useMethod>>

I trimmed the debug_tree dump massively - I'm guessing the details are
not terribly relevant, and the bug is that we got an OFFSET_REF in
build_x_function_call in the first place.  Going up...

#2  0x826261a in finish_call_expr (fn=0x91, args=0x40409060, koenig=0) 
    at cp/semantics.c:1480
1480      result = build_x_function_call (fn, args, current_class_ref);

koenig is false, so finish_call_expr was called with the OFFSET_REF.
The debug info for yyparse() is nonsense, but it has to have been the
third of these rules (starred):

primary:
	/* ... */
        | notype_unqualified_id '(' nonnull_exprlist ')'
               { $$ = finish_call_expr ($1, $3, 1); }
        | notype_unqualified_id LEFT_RIGHT
               { $$ = finish_call_expr ($1, NULL_TREE, 1); }
*	| primary '(' nonnull_exprlist ')'
               { $$ = finish_call_expr ($1, $3, 0); }
	| primary LEFT_RIGHT
               { $$ = finish_call_expr ($1, NULL_TREE, 0); }

because that is the only one that calls finish_call_expr with Koenig
off and an argument list.  Note that this rule accepts a PRIMARY in
function call position.

The code fragment that triggered this was:

void ODEsolver::timeloop(vector<double>& y, double ts, double te, double dt)
{
  (ODEsolver::useMethod)(y,ts,dt);
}

  ODEsolver::useMethod is a notype_qualified_id.  Here's some -dy
  output:

Reading a token: Next token is 257 (IDENTIFIER `useMethod')
Shifting token 257 (IDENTIFIER), Entering state 301
Reducing via rule 281 (line 1363), IDENTIFIER  -> notype_unqualified_id
state stack now 0 1 4 47 184 456 733 1021 1213 331 356
Entering state 255
Reducing via rule 626 (line 2862), nested_name_specifier notype_unqualified_id  -> notype_qualified_id
state stack now 0 1 4 47 184 456 733 1021 1213 331
Entering state 353
Reducing via rule 628 (line 2871), notype_qualified_id  -> overqualified_id
state stack now 0 1 4 47 184 456 733 1021 1213 331
Entering state 354
Reading a token: Next token is 41 (')')
Reducing via rule 333 (line 1546), overqualified_id  -> primary

There is nothing particularly interesting about the rule reducing a
notype_qualified_id to an overqualified_id.  However, the rule
reducing an overqualified_id to a primary _is_ interesting:

primary:
	overqualified_id  %prec HYPERUNARY
		{ $$ = build_offset_ref (OP0 ($$), OP1 ($$)); }

There's our OFFSET_REF.  The very next rule is the one that _should_
have fired - or so I imagine, given that it fires if I take off the
extra parens around ODEsolver::useMethod.

primary:
	overqualified_id '(' nonnull_exprlist ')'
                { $$ = finish_qualified_call_expr ($1, $3); }

This doesn't match, because '(' overqualified_id ')' is not itself an
overqualified_id.

If I change the overqualified_id pattern to read

overqualified_id:
	  notype_qualified_id
	| global_scope notype_qualified_id
		{ $$ = $2; }
	| '(' overqualified_id ')'
		{ $$ = $2; }
	;

then I get an additional shift-reduce conflict and cc1plus produces:

eb127.C: In method `void ODEsolver::timeloop (vector<double,
	 allocator<double> > &, double, double, double)':
eb127.C:49: pointer-to-member function this->ODEsolver::useMethod
	    cannot be called without an object; consider using .* or ->*

I do not know if this error is appropriate for the code.  However, I
do get the exact same message if I take off the parens, and parens
around a function name aren't significant... right?

I will see if that change breaks anything else, and report tomorrow
morning.

zw

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]