Patchwork Yet another non-prototype builtin issue (PR middle-end/55890)

login
register
mail settings
Submitter Tom de Vries
Date Jan. 9, 2013, 10:11 a.m.
Message ID <50ED4241.4010904@mentor.com>
Download mbox | patch
Permalink /patch/210681/
State New
Headers show

Comments

Tom de Vries - Jan. 9, 2013, 10:11 a.m.
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.
Jakub Jelinek - Jan. 9, 2013, 10:17 a.m.
On Wed, Jan 09, 2013 at 11:11:13AM +0100, Tom de Vries wrote:
> OK for trunk after I've tested this on mips64?

Yes, thanks.

> 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))


	Jakub
Greta Yorsh - Jan. 11, 2013, 11:02 a.m.
Tom, are you going to apply this patch? 

There are similar failures on arm-none-eabi after r195008:

FAIL: gcc.dg/torture/pr55890-3.c -O0 (internal compiler error)
FAIL: gcc.dg/torture/pr55890-3.c -O0 (test for excess errors)
FAIL: gcc.dg/torture/pr55890-3.c -O1 (internal compiler error)
FAIL: gcc.dg/torture/pr55890-3.c -O1 (test for excess errors)

ICE with segfault same backtrace as in your report.

The failures are with -OO and -O1 but the test passes with -O2.

Your patch fixes these failures. I haven't tested the patch beyond that.

Thanks,
Greta

> -----Original Message-----
> From: Tom de Vries [mailto:Tom_deVries@mentor.com]
> Sent: 09 January 2013 10:11
> To: Richard Biener
> Cc: Jakub Jelinek; gcc-patches@gcc.gnu.org
> 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.
Tom de Vries - Jan. 11, 2013, 11:22 a.m.
On 11/01/13 12:02, Greta Yorsh wrote:
> Tom, are you going to apply this patch? 

Greta,

While testing I've ran into several issues with timeouts (not related to this
patch) that I needed to address, so it took me a bit, but I started the latest
build & test run yesterday evening so I expect to checked in the patch later today.

Thanks,
- Tom

Patch

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))