[C++] Fix C++ wrong-code due to constant_value_1 (PR c++/90810)

Message ID 20190610215232.GF19695@tucnak
State New
Headers show
Series
  • [C++] Fix C++ wrong-code due to constant_value_1 (PR c++/90810)
Related show

Commit Message

Jakub Jelinek June 10, 2019, 9:52 p.m.
Hi!

My PR85077
+	if (VECTOR_TYPE_P (TREE_TYPE (x)))
+	  x = fold (x);
cp_fold change apparently broke the following and similar testcases, if
split_nonconstant_init splits the initialization into a runtime part and
some CONSTRUCTOR, it clears TREE_READONLY on it, and constant_value_1
had code to avoid returning that CONSTRUCTOR as the value if not
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P because that CONSTRUCTOR is only
part of the story.  With the PR85077 change, such CONSTRUCTORs are turned
into VECTOR_CSTs by fold though and constant_value_1 then returns the wrong
thing.

Fixed thusly, bootstrapped/regtested on x86_64-linux, ok for trunk and
9.2/8.4?

2019-06-10  Jakub Jelinek  <jakub@redhat.com>

	PR c++/90810
	* init.c (constant_value_1): Handle VECTOR_CST DECL_INITIAL for
	!DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P decls like CONSTRUCTOR.

	* g++.dg/ext/vector37.C: New test.


	Jakub

Comments

Jason Merrill June 11, 2019, 12:41 p.m. | #1
On 6/10/19 5:52 PM, Jakub Jelinek wrote:
> Hi!

> 

> My PR85077

> +	if (VECTOR_TYPE_P (TREE_TYPE (x)))

> +	  x = fold (x);

> cp_fold change apparently broke the following and similar testcases, if

> split_nonconstant_init splits the initialization into a runtime part and

> some CONSTRUCTOR, it clears TREE_READONLY on it, and constant_value_1

> had code to avoid returning that CONSTRUCTOR as the value if not

> DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P because that CONSTRUCTOR is only

> part of the story.  With the PR85077 change, such CONSTRUCTORs are turned

> into VECTOR_CSTs by fold though and constant_value_1 then returns the wrong

> thing.

> 

> Fixed thusly, bootstrapped/regtested on x86_64-linux, ok for trunk and

> 9.2/8.4?


OK.

Jason

Patch

--- gcc/cp/init.c.jj	2019-05-23 12:57:16.624494279 +0200
+++ gcc/cp/init.c	2019-06-10 17:07:34.779366457 +0200
@@ -2339,8 +2339,11 @@  constant_value_1 (tree decl, bool strict
 		  || TREE_CODE (init) == STRING_CST)))
 	break;
       /* Don't return a CONSTRUCTOR for a variable with partial run-time
-	 initialization, since it doesn't represent the entire value.  */
-      if (TREE_CODE (init) == CONSTRUCTOR
+	 initialization, since it doesn't represent the entire value.
+	 Similarly for VECTOR_CSTs created by cp_folding those
+	 CONSTRUCTORs.  */
+      if ((TREE_CODE (init) == CONSTRUCTOR
+	   || TREE_CODE (init) == VECTOR_CST)
 	  && !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))
 	break;
       /* If the variable has a dynamic initializer, don't use its
--- gcc/testsuite/g++.dg/ext/vector37.C.jj	2019-06-10 17:12:29.092801825 +0200
+++ gcc/testsuite/g++.dg/ext/vector37.C	2019-06-10 17:11:35.641630817 +0200
@@ -0,0 +1,29 @@ 
+// PR c++/90810
+// { dg-do run }
+
+void
+foo (float x, float y)
+{
+  typedef float __attribute__ ((__vector_size__ (4 * sizeof (float)), __may_alias__)) V;
+  const V a = { x, x, x, x }, b = { y, y, y, y };
+  const V c = a / b;
+  if (c[0] != 6.0f || c[1] != 6.0f || c[2] != 6.0f || c[3] != 6.0f)
+    __builtin_abort ();
+}
+
+void
+bar (float y)
+{
+  typedef float __attribute__ ((__vector_size__ (4 * sizeof (float)), __may_alias__)) V;
+  const V a = { 7.0f, 8.0f, 9.0f, 10.0f }, b = { 1.0f, 2.0f, 3.0f, y };
+  const V c = a / b;
+  if (c[0] != 7.0f || c[1] != 4.0f || c[2] != 3.0f || c[3] != 5.0f)
+    __builtin_abort ();
+}
+
+int
+main ()
+{
+  foo (12.0f, 2.0f);
+  bar (2.0f);
+}