Patchwork Fix PR54515

login
register
mail settings
Submitter Markus Trippelsdorf
Date Sept. 7, 2012, 9:01 p.m.
Message ID <20120907210135.GA3932@x4>
Download mbox | patch
Permalink /patch/182445/
State New
Headers show

Comments

Markus Trippelsdorf - Sept. 7, 2012, 9:01 p.m.
Here the problem is that get_base_address() can return NULL_TREE and
this later leads to a segfault. Fix by checking that the return value is
valid.
gcc-4.6 and 4.7 are also affected.

Please commit if this looks OK.
Thanks.

Tested on x86_64-pc-linux-gnu

2012-09-07  Markus Trippelsdorf  <markus@trippelsdorf.de>

	PR middle-end/54515
	* tree-sra.c (disqualify_base_of_expr): Check for possible
	NULL_TREE returned by get_base_address()

	* g++.dg/tree-ssa/pr54515.C: new testcase
Richard Guenther - Sept. 10, 2012, 9:45 a.m.
On Fri, Sep 7, 2012 at 11:01 PM, Markus Trippelsdorf
<markus@trippelsdorf.de> wrote:
> Here the problem is that get_base_address() can return NULL_TREE and
> this later leads to a segfault. Fix by checking that the return value is
> valid.
> gcc-4.6 and 4.7 are also affected.
>
> Please commit if this looks OK.
> Thanks.

Hmm, we call the function on

VIEW_CONVERT_EXPR<unsigned char[2]>(0)[0]

which should have been folded to a constant.  And get_base_address
should just return the constant tree instead of returning NULL (it does
return a plethora of base object kinds already).  Your patch looks ok for
the branches where I'll install it and come up with sth else for trunk.

Thanks,
Richard.

> Tested on x86_64-pc-linux-gnu
>
> 2012-09-07  Markus Trippelsdorf  <markus@trippelsdorf.de>
>
>         PR middle-end/54515
>         * tree-sra.c (disqualify_base_of_expr): Check for possible
>         NULL_TREE returned by get_base_address()
>
>         * g++.dg/tree-ssa/pr54515.C: new testcase
>
> diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr54515.C b/gcc/testsuite/g++.dg/tree-ssa/pr54515.C
> new file mode 100644
> index 0000000..11ed468
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/tree-ssa/pr54515.C
> @@ -0,0 +1,19 @@
> +// { dg-do compile }
> +// { dg-options "-O2" }
> +
> +template < typename T > T h2le (T)
> +{
> +    T a;
> +    unsigned short &b = a;
> +    short c = 0;
> +    unsigned char (&d)[2] = reinterpret_cast < unsigned char (&)[2] > (c);
> +    unsigned char (&e)[2] = reinterpret_cast < unsigned char (&)[2] > (b);
> +    e[0] = d[0];
> +    return a;
> +}
> +
> +void
> +bar ()
> +{
> +    h2le ((unsigned short) 0);
> +}
> diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
> index aafaa15..2bb92e9 100644
> --- a/gcc/tree-sra.c
> +++ b/gcc/tree-sra.c
> @@ -984,7 +984,8 @@ static void
>  disqualify_base_of_expr (tree t, const char *reason)
>  {
>    t = get_base_address (t);
> -  if (sra_mode == SRA_MODE_EARLY_IPA
> +  if (t
> +      && sra_mode == SRA_MODE_EARLY_IPA
>        && TREE_CODE (t) == MEM_REF)
>      t = get_ssa_base_param (TREE_OPERAND (t, 0));
>
> --
> Markus

Patch

diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr54515.C b/gcc/testsuite/g++.dg/tree-ssa/pr54515.C
new file mode 100644
index 0000000..11ed468
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr54515.C
@@ -0,0 +1,19 @@ 
+// { dg-do compile }
+// { dg-options "-O2" }
+
+template < typename T > T h2le (T)
+{
+    T a;
+    unsigned short &b = a;
+    short c = 0;
+    unsigned char (&d)[2] = reinterpret_cast < unsigned char (&)[2] > (c);
+    unsigned char (&e)[2] = reinterpret_cast < unsigned char (&)[2] > (b);
+    e[0] = d[0];
+    return a;
+}
+
+void
+bar ()
+{
+    h2le ((unsigned short) 0);
+}
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index aafaa15..2bb92e9 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -984,7 +984,8 @@  static void
 disqualify_base_of_expr (tree t, const char *reason)
 {
   t = get_base_address (t);
-  if (sra_mode == SRA_MODE_EARLY_IPA
+  if (t
+      && sra_mode == SRA_MODE_EARLY_IPA
       && TREE_CODE (t) == MEM_REF)
     t = get_ssa_base_param (TREE_OPERAND (t, 0));