Patchwork More vector constexpr fixes

login
register
mail settings
Submitter Marc Glisse
Date Dec. 6, 2012, 10:24 p.m.
Message ID <alpine.DEB.2.02.1212062311260.8960@stedding.saclay.inria.fr>
Download mbox | patch
Permalink /patch/204330/
State New
Headers show

Comments

Marc Glisse - Dec. 6, 2012, 10:24 p.m.
Hello,

this comes on top of Jakub's patch from earlier today. The ce->index 
checks only turn an ICE into an error: constexpr vector subscripts are not 
handled yet, they are a bit more complicated.

2012-12-07  Marc Glisse  <marc.glisse@inria.fr>

 	PR c++/53094
cp/
 	* tree.c (cp_tree_equal): Handle VECTOR_CST.
 	* semantics.c (cxx_eval_bare_aggregate): Protect a dereference.
 	Handle VECTOR_CST.
testsuite/
 	* g++.dg/cpp0x/constexpr-53094-1.C: New testcase.
 	* g++.dg/cpp0x/constexpr-53094-2.C: Likewise.
 	* g++.dg/cpp0x/constexpr-53094-3.C: Likewise.
Jason Merrill - Dec. 11, 2012, 7:01 p.m.
OK.

Jason

Patch

Index: gcc/testsuite/g++.dg/cpp0x/constexpr-53094-2.C

===================================================================
--- gcc/testsuite/g++.dg/cpp0x/constexpr-53094-2.C	(revision 0)

+++ gcc/testsuite/g++.dg/cpp0x/constexpr-53094-2.C	(revision 0)

@@ -0,0 +1,6 @@ 

+// { dg-do compile }

+// { dg-options "-std=gnu++11" }

+

+typedef float __attribute__ ((vector_size (4 * sizeof (float)))) V4;

+constexpr V4 build (float x, float y, float z) { return (V4){ x, y, z, 0 };}

+constexpr V4 x = build (1, 0, 0);


Property changes on: gcc/testsuite/g++.dg/cpp0x/constexpr-53094-2.C
___________________________________________________________________
Added: svn:eol-style
   + native
Added: svn:keywords
   + Author Date Id Revision URL

Index: gcc/testsuite/g++.dg/cpp0x/constexpr-53094-1.C

===================================================================
--- gcc/testsuite/g++.dg/cpp0x/constexpr-53094-1.C	(revision 0)

+++ gcc/testsuite/g++.dg/cpp0x/constexpr-53094-1.C	(revision 0)

@@ -0,0 +1,6 @@ 

+// { dg-do compile }

+// { dg-options "-std=gnu++11" }

+

+typedef float __attribute__ ((vector_size (4 * sizeof (float)))) V4;

+constexpr V4 v = { 1, 1, 1, 0 };

+constexpr V4 r = v[0] + v; // { dg-bogus "not a constant expression" "" { xfail *-*-* } }


Property changes on: gcc/testsuite/g++.dg/cpp0x/constexpr-53094-1.C
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision URL
Added: svn:eol-style
   + native

Index: gcc/testsuite/g++.dg/cpp0x/constexpr-53094-3.C

===================================================================
--- gcc/testsuite/g++.dg/cpp0x/constexpr-53094-3.C	(revision 0)

+++ gcc/testsuite/g++.dg/cpp0x/constexpr-53094-3.C	(revision 0)

@@ -0,0 +1,19 @@ 

+// { dg-do compile }

+// { dg-options "-std=gnu++11" }

+

+typedef float __attribute__ ((vector_size (4 * sizeof (float)))) V4;

+

+struct Rot3 {

+  typedef float T;

+  typedef V4 Vec;

+  Vec axis[3];

+  constexpr Rot3 (V4 ix, V4 iy, V4 iz) : axis {ix, iy, iz} {}

+

+  constexpr Rot3(T xx, T xy, T xz, T yx, T yy, T yz, T zx, T zy, T zz) :

+    Rot3((Vec) { xx, xy, xz, 0 },

+	 (Vec) { yx, yy, yz, 0 },

+	 (Vec) { zx, zy, zz, 0 }) {}

+

+};

+

+constexpr Rot3 r1( 0, 1 ,0, 0, 0, 1,  1, 0, 0);


Property changes on: gcc/testsuite/g++.dg/cpp0x/constexpr-53094-3.C
___________________________________________________________________
Added: svn:eol-style
   + native
Added: svn:keywords
   + Author Date Id Revision URL

Index: gcc/cp/semantics.c

===================================================================
--- gcc/cp/semantics.c	(revision 194263)

+++ gcc/cp/semantics.c	(working copy)

@@ -7104,45 +7104,47 @@  cxx_eval_bare_aggregate (const constexpr

   for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
     {
       tree elt = cxx_eval_constant_expression (call, ce->value,
 					       allow_non_constant, addr,
 					       non_constant_p, overflow_p);
       /* Don't VERIFY_CONSTANT here.  */
       if (allow_non_constant && *non_constant_p)
 	goto fail;
       if (elt != ce->value)
 	changed = true;
-      if (TREE_CODE (ce->index) == COMPONENT_REF)

+      if (ce->index && TREE_CODE (ce->index) == COMPONENT_REF)

 	{
 	  /* This is an initialization of a vfield inside a base
 	     subaggregate that we already initialized; push this
 	     initialization into the previous initialization.  */
 	  constructor_elt *inner = base_field_constructor_elt (n, ce->index);
 	  inner->value = elt;
 	}
-      else if (TREE_CODE (ce->index) == NOP_EXPR)

+      else if (ce->index && TREE_CODE (ce->index) == NOP_EXPR)

 	{
 	  /* This is an initializer for an empty base; now that we've
 	     checked that it's constant, we can ignore it.  */
 	  gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (ce->index))));
 	}
       else
 	CONSTRUCTOR_APPEND_ELT (n, ce->index, elt);
     }
   if (*non_constant_p || !changed)
     {
     fail:
       vec_free (n);
       return t;
     }
   t = build_constructor (TREE_TYPE (t), n);
   TREE_CONSTANT (t) = true;
+  if (TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)

+    t = fold (t);

   return t;
 }
 
 /* Subroutine of cxx_eval_constant_expression.
    The expression tree T is a VEC_INIT_EXPR which denotes the desired
    initialization of a non-static data member of array type.  Reduce it to a
    CONSTRUCTOR.
 
    Note that apart from value-initialization (when VALUE_INIT is true),
    this is only intended to support value-initialization and the
Index: gcc/cp/tree.c

===================================================================
--- gcc/cp/tree.c	(revision 194263)

+++ gcc/cp/tree.c	(working copy)

@@ -2462,20 +2462,23 @@  cp_tree_equal (tree t1, tree t2)

 		    TREE_STRING_LENGTH (t1));
 
     case FIXED_CST:
       return FIXED_VALUES_IDENTICAL (TREE_FIXED_CST (t1),
 				     TREE_FIXED_CST (t2));
 
     case COMPLEX_CST:
       return cp_tree_equal (TREE_REALPART (t1), TREE_REALPART (t2))
 	&& cp_tree_equal (TREE_IMAGPART (t1), TREE_IMAGPART (t2));
 
+    case VECTOR_CST:

+      return operand_equal_p (t1, t2, OEP_ONLY_CONST);

+

     case CONSTRUCTOR:
       /* We need to do this when determining whether or not two
 	 non-type pointer to member function template arguments
 	 are the same.  */
       if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
 	  || CONSTRUCTOR_NELTS (t1) != CONSTRUCTOR_NELTS (t2))
 	return false;
       {
 	tree field, value;
 	unsigned int i;