This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Yet another non-prototype builtin issue (PR middle-end/55890)
- From: Tom de Vries <Tom_deVries at mentor dot com>
- To: Richard Biener <richard dot guenther at gmail dot com>
- Cc: Jakub Jelinek <jakub at redhat dot com>, "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 9 Jan 2013 11:11:13 +0100
- Subject: [PATCH] Yet another non-prototype builtin issue (PR middle-end/55890)
Richard,
I've build r195008 for target mips64-linux-gnu with low optimization level
({CFLAGS,CXXFLAGS,BOOT_CFLAGS}='-g -O0'), and noticed failures for
gcc.dg/torture/pr55890-{1,2,3}.c at -O0 and -O1 (which are not there without the
low optimization level).
The -O1 pr55890-1.c failure looks like this:
...
$ mips64-linux-gnu-gcc gcc/testsuite/gcc.dg/torture/pr55890-1.c
-fno-diagnostics-show-caret -O1 -S -o pr55890-1.s
gcc/testsuite/gcc.dg/torture/pr55890-1.c: In function 'main':
gcc/testsuite/gcc.dg/torture/pr55890-1.c:6:11: internal compiler error:
Segmentation fault
0x86dad80 crash_signal
gcc/toplev.c:334
0x82bec14 expand_call(tree_node*, rtx_def*, int)
gcc/calls.c:3139
0x82adae3 expand_builtin(tree_node*, rtx_def*, rtx_def*, machine_mode, int)
gcc-mainline/gcc/builtins.c:6866
0x83d5484 expand_expr_real_1(tree_node*, rtx_def*, machine_mode,
expand_modifier, rtx_def**)
gcc-mainline/gcc/expr.c:10141
0x82d7721 expand_call_stmt
gcc-mainline/gcc/cfgexpand.c:2115
0x82d77eb expand_gimple_stmt_1
gcc/cfgexpand.c:2153
0x82d7e51 expand_gimple_stmt
gcc/cfgexpand.c:2305
0x82d8f76 expand_gimple_basic_block
gcc/cfgexpand.c:4084
0x82d9d53 gimple_expand_cfg
gcc/cfgexpand.c:4603
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
...
The segv occurs when evaluating GET_MODE (args[arg_nr].reg) here:
...
if (pass == 1 && (return_flags & ERF_RETURNS_ARG))
{
int arg_nr = return_flags & ERF_RETURN_ARG_MASK;
if (PUSH_ARGS_REVERSED)
arg_nr = num_actuals - arg_nr - 1;
if (args[arg_nr].reg
&& valreg
&& REG_P (valreg)
&& GET_MODE (args[arg_nr].reg) == GET_MODE (valreg))
call_fusage
= gen_rtx_EXPR_LIST (TYPE_MODE (TREE_TYPE (args[arg_nr].tree_value)),
gen_rtx_SET (VOIDmode, valreg, args[arg_nr].reg),
call_fusage);
}
...
The expression (return_flags & ERF_RETURNS_ARG) is true because we're
calculating return_flags using fndecl == memmove, and for memmove we're indeed
returning the first arg.
So arg_nr evaluates to 0, and we're accessing args[arg_nr].reg. But num_actuals
is 0, so args is the result of alloca (0) and args[arg_nr] contains some random
value, which causes the segv when evaluating GET_MODE (args[arg_nr].reg) (unless
args[arg_nr].reg happens to be NULL, in which case we don't get there).
Attached patch fixes this by testing whether arg_nr is in range before using it.
Using the patch and a cc1 recompile, I'm able to run pr55890-{1,2,3}.c successfully.
OK for trunk after I've tested this on mips64?
Thanks,
- Tom
2013-01-09 Tom de Vries <tom@codesourcery.com>
PR middle-end/55890
* calls.c (expand_call): Check if arg_nr is valid.
Index: gcc/calls.c
===================================================================
--- gcc/calls.c (revision 195008)
+++ gcc/calls.c (working copy)
@@ -3136,7 +3136,9 @@ expand_call (tree exp, rtx target, int i
int arg_nr = return_flags & ERF_RETURN_ARG_MASK;
if (PUSH_ARGS_REVERSED)
arg_nr = num_actuals - arg_nr - 1;
- if (args[arg_nr].reg
+ if (arg_nr >= 0
+ && arg_nr < num_actuals
+ && args[arg_nr].reg
&& valreg
&& REG_P (valreg)
&& GET_MODE (args[arg_nr].reg) == GET_MODE (valreg))