From 5ab8b6b550c078fed66f1939d310802963772edb Mon Sep 17 00:00:00 2001
From: Jason Merrill <jason@redhat.com>
Date: Thu, 5 Nov 2009 08:11:42 -0500
Subject: [PATCH] re PR c++/36912 (ICE with "-frounding-math -g")

	PR c++/36912
	* varasm.c (initializer_constant_valid_p): A PLUS_EXPR
	or MINUS_EXPR of REAL_TYPE is not a valid constant initializer.
	(output_constant): Avoid crash after error.

From-SVN: r153936
---
 gcc/ChangeLog                            |  7 +++++++
 gcc/testsuite/ChangeLog                  |  5 +++++
 gcc/testsuite/g++.dg/init/static-init2.C |  3 +++
 gcc/varasm.c                             | 10 ++++++++--
 4 files changed, 23 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/init/static-init2.C

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index dd3fa834e2b1..9643b5fff2ec 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2009-11-04  Jason Merrill  <jason@redhat.com>
+
+	PR c++/36912
+	* varasm.c (initializer_constant_valid_p): A PLUS_EXPR
+	or MINUS_EXPR of REAL_TYPE is not a valid constant initializer.
+	(output_constant): Avoid crash after error.
+
 2009-11-05  Martin Jambor  <mjambor@suse.cz>
 
 	* tree-sra.c (struct access): Changed comment of next_sibling field.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9d16f915c5a4..175c7f2c35e4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-11-04  Jason Merrill  <jason@redhat.com>
+
+	PR c++/36912
+	* g++.dg/init/static-init2.C: New.
+
 2009-11-05  Janus Weil  <janus@gcc.gnu.org>
 
 	PR fortran/41556
diff --git a/gcc/testsuite/g++.dg/init/static-init2.C b/gcc/testsuite/g++.dg/init/static-init2.C
new file mode 100644
index 000000000000..34bf2b2388bc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/static-init2.C
@@ -0,0 +1,3 @@
+// PR c++/36912
+// { dg-options -frounding-math }
+const double c = .1, d = c+1;
diff --git a/gcc/varasm.c b/gcc/varasm.c
index b6ff4ae149dd..c9953d128da8 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -4322,6 +4322,10 @@ initializer_constant_valid_p (tree value, tree endtype)
 
     case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
+      /* Any valid floating-point constants will have been folded by now;
+	 with -frounding-math we hit this with addition of two constants.  */
+      if (TREE_CODE (endtype) == REAL_TYPE)
+	return NULL_TREE;
       if (! INTEGRAL_TYPE_P (endtype)
 	  || TYPE_PRECISION (endtype)
 	     >= int_or_pointer_precision (TREE_TYPE (value)))
@@ -4345,6 +4349,8 @@ initializer_constant_valid_p (tree value, tree endtype)
       break;
 
     case MINUS_EXPR:
+      if (TREE_CODE (endtype) == REAL_TYPE)
+	return NULL_TREE;
       if (! INTEGRAL_TYPE_P (endtype)
 	  || TYPE_PRECISION (endtype)
 	     >= int_or_pointer_precision (TREE_TYPE (value)))
@@ -4560,8 +4566,8 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align)
     case REAL_TYPE:
       if (TREE_CODE (exp) != REAL_CST)
 	error ("initializer for floating value is not a floating constant");
-
-      assemble_real (TREE_REAL_CST (exp), TYPE_MODE (TREE_TYPE (exp)), align);
+      else
+	assemble_real (TREE_REAL_CST (exp), TYPE_MODE (TREE_TYPE (exp)), align);
       break;
 
     case COMPLEX_TYPE:
-- 
GitLab