Latent calls_function_1 bug.
Jan Hubicka
hubicka@atrey.karlin.mff.cuni.cz
Fri Apr 28 04:45:00 GMT 2000
Hi
(Mark, Jeff and Richard: I am sorry for re-sending it, I've made typo
in email address)
(Jeff: Does this fix your PA-64 problems? I hope so.)
(Mark: please take a look at this, since it is needed for next email I am
sending to you)
Following testcase (originally constructed for another bug)
struct c { int a, b, c; };
struct c missalign_me (int *);
void I_dont_need_alignment (int a, int b, int c, int d);
main ()
{
I_dont_need_alignment (missalign_me (alloca (10)).a, 1, 2, 3);
}
triggers latent bug in calls_function_1 - it don't traverse TREE_LIST
subexpressions. The bugs shows as crash in my sanity checking code in
alloca expander. This patch fixes it and makes gcc to die bit later
on that testcase in expand_call place, where I originaly intended to
make it die at.
I am not tree expert and I was very surprised to see that walking trees
is so non-trivial task. Is there some infrastructure to help this?
I see there is walk_tree in c++ backend, but it don't work for C,
perhaps someone who understands trees can donate walk_tree to the other
frontends as well, so it can be used in common code.
Older versions of gcc misscompile this example.
Honza
Fri Apr 28 13:35:01 MET DST 2000 Jan Hubicka <jh@suse.cz>
* calls.c (calls_function_1): Propertly handle TREE_LIST expressions;
use special_function_p to detect alloca.
Index: egcs/gcc/calls.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/calls.c,v
retrieving revision 1.126
diff -c -3 -p -r1.126 calls.c
*** calls.c 2000/04/27 16:44:23 1.126
--- calls.c 2000/04/28 11:34:33
*************** calls_function_1 (exp, which)
*** 254,264 ****
if ((int) code >= NUM_TREE_CODES)
return 1;
- /* Only expressions and references can contain calls. */
- if (type != 'e' && type != '<' && type != '1' && type != '2' && type != 'r'
- && type != 'b')
- return 0;
-
switch (code)
{
case CALL_EXPR:
--- 253,258 ----
*************** calls_function_1 (exp, which)
*** 269,280 ****
== FUNCTION_DECL))
{
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
!
! if ((DECL_BUILT_IN (fndecl)
! && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
! && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_ALLOCA)
! || (DECL_SAVED_INSNS (fndecl)
! && DECL_SAVED_INSNS (fndecl)->calls_alloca))
return 1;
}
--- 263,270 ----
== FUNCTION_DECL))
{
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
! int flags = special_function_p (fndecl, 0);
! if (flags & ECF_MAY_BE_ALLOCA)
return 1;
}
*************** calls_function_1 (exp, which)
*** 311,316 ****
--- 301,311 ----
return 1;
}
return 0;
+ case TREE_LIST:
+ for (; exp != 0; exp = TREE_CHAIN (exp))
+ if (calls_function_1 (TREE_VALUE (exp), which))
+ return 1;
+ return 0;
case METHOD_CALL_EXPR:
length = 3;
*************** calls_function_1 (exp, which)
*** 322,331 ****
case RTL_EXPR:
return 0;
!
default:
break;
}
for (i = 0; i < length; i++)
if (TREE_OPERAND (exp, i) != 0
--- 317,331 ----
case RTL_EXPR:
return 0;
!
default:
break;
}
+
+ /* Only expressions and references can contain calls. */
+ if (type != 'e' && type != '<' && type != '1' && type != '2' && type != 'r'
+ && type != 'b')
+ return 0;
for (i = 0; i < length; i++)
if (TREE_OPERAND (exp, i) != 0
More information about the Gcc-patches
mailing list