From 5a27a197d8ee9ca67e567ecf220e16d9bc4b44b6 Mon Sep 17 00:00:00 2001
From: Richard Guenther <rguenther@suse.de>
Date: Tue, 11 Sep 2012 08:32:29 +0000
Subject: [PATCH] re PR middle-end/54515 (cc1plus sigsegv -O2 anonymous
 namespace)

2012-09-11  Richard Guenther  <rguenther@suse.de>

	PR middle-end/54515
	* gimple.c (get_base_address): Do not return NULL_TREE apart
	from for WITH_SIZE_EXPR.
	* gimple-fold.c (canonicalize_constructor_val): Do not call
	get_base_address when not necessary.

	* g++.dg/tree-ssa/pr54515.C: New testcase.

From-SVN: r191174
---
 gcc/ChangeLog                           |  8 ++++++++
 gcc/gimple-fold.c                       |  6 ++++--
 gcc/gimple.c                            | 14 +++++---------
 gcc/testsuite/ChangeLog                 |  5 +++++
 gcc/testsuite/g++.dg/tree-ssa/pr54515.C | 19 +++++++++++++++++++
 5 files changed, 41 insertions(+), 11 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr54515.C

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2b11aa5e51b6..f6c73d4cb86e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2012-09-11  Richard Guenther  <rguenther@suse.de>
+
+	PR middle-end/54515
+	* gimple.c (get_base_address): Do not return NULL_TREE apart
+	from for WITH_SIZE_EXPR.
+	* gimple-fold.c (canonicalize_constructor_val): Do not call
+	get_base_address when not necessary.
+
 2012-09-10  Andrew Pinski  <apinski@cavium.com>
 
 	PR tree-opt/54362
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 42bc0fcb83a7..bb13e1fd732d 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -154,13 +154,15 @@ canonicalize_constructor_val (tree cval, tree from_decl)
     }
   if (TREE_CODE (cval) == ADDR_EXPR)
     {
-      tree base = get_base_address (TREE_OPERAND (cval, 0));
-      if (!base && TREE_CODE (TREE_OPERAND (cval, 0)) == COMPOUND_LITERAL_EXPR)
+      tree base = NULL_TREE;
+      if (TREE_CODE (TREE_OPERAND (cval, 0)) == COMPOUND_LITERAL_EXPR)
 	{
 	  base = COMPOUND_LITERAL_EXPR_DECL (TREE_OPERAND (cval, 0));
 	  if (base)
 	    TREE_OPERAND (cval, 0) = base;
 	}
+      else
+	base = get_base_address (TREE_OPERAND (cval, 0));
       if (!base)
 	return NULL_TREE;
 
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 88fa7627e842..f639869e726a 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -2878,16 +2878,12 @@ get_base_address (tree t)
       && TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR)
     t = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
 
-  if (TREE_CODE (t) == SSA_NAME
-      || DECL_P (t)
-      || TREE_CODE (t) == STRING_CST
-      || TREE_CODE (t) == CONSTRUCTOR
-      || INDIRECT_REF_P (t)
-      || TREE_CODE (t) == MEM_REF
-      || TREE_CODE (t) == TARGET_MEM_REF)
-    return t;
-  else
+  /* ???  Either the alias oracle or all callers need to properly deal
+     with WITH_SIZE_EXPRs before we can look through those.  */
+  if (TREE_CODE (t) == WITH_SIZE_EXPR)
     return NULL_TREE;
+
+  return t;
 }
 
 void
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 11f82fb0f587..a68b6230fe68 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2012-09-11  Richard Guenther  <rguenther@suse.de>
+
+	PR middle-end/54515
+	* g++.dg/tree-ssa/pr54515.C: New testcase.
+
 2012-09-10  Andrew Pinski  <apinski@cavium.com>
 
 	PR tree-opt/c54362
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 000000000000..11ed46893bf9
--- /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);
+}
-- 
GitLab