Decltype and opaque vectors (was: vector comparisons in C++)

Submitted by Marc Glisse on Sept. 15, 2012, 1:01 p.m.

Details

Message ID alpine.DEB.2.02.1209151438480.8109@stedding.saclay.inria.fr
State New
Headers show

Commit Message

Marc Glisse Sept. 15, 2012, 1:01 p.m.
On Fri, 14 Sep 2012, Jason Merrill wrote:

> On 09/14/2012 11:03 AM, Marc Glisse wrote:
>> I wanted to use decltype(x<x) to find an integer vector type of the same
>> size as x, and then actually be able to use it. Being opaque, it refuses
>> to be initialized (cp/decl.c:5550). Maybe decltype (and others?) could
>> return non-opaque types?
>
> That sounds like the right answer.

Hello,

does the attached make sense? It passes booststrap+testsuite, but with 
vectors that doesn't prove much...


2012-09-17  Marc Glisse  <marc.glisse@inria.fr>

 	PR c++/54581

gcc/cp/
 	* semantics.c (finish_decltype_type): Make vectors not opaque.

gcc/testsuite/
 	* g++.dg/cpp0x/decltype-54581.C: New testcase.

Comments

Jason Merrill Sept. 17, 2012, 3:09 p.m.
On 09/15/2012 09:01 AM, Marc Glisse wrote:
> +	  /* For vector types, pick a non-opaque variant.  */
> +	  if (TREE_CODE (type) == VECTOR_TYPE)
> +	    type = cp_build_qualified_type (TYPE_MAIN_VARIANT (type),
> +					    cp_type_quals (type));


I believe that template type deduction drops opacity by calling 
strip_typedefs, which also preserves type attributes.  So I think let's 
use it here as well.  OK with that change.

Jason

Patch hide | download patch | download mbox

Index: cp/semantics.c
===================================================================
--- cp/semantics.c	(revision 191341)
+++ cp/semantics.c	(working copy)
@@ -5305,20 +5305,25 @@  finish_decltype_type (tree expr, bool id
 	/* If the expression is just "this", we want the
 	   cv-unqualified pointer for the "this" type.  */
 	type = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
       else
 	{
 	  /* Otherwise, where T is the type of e, if e is an lvalue,
 	     decltype(e) is defined as T&; if an xvalue, T&&; otherwise, T. */
 	  cp_lvalue_kind clk = lvalue_kind (expr);
 	  type = unlowered_expr_type (expr);
 	  gcc_assert (TREE_CODE (type) != REFERENCE_TYPE);
+
+	  /* For vector types, pick a non-opaque variant.  */
+	  if (TREE_CODE (type) == VECTOR_TYPE)
+	    type = cp_build_qualified_type (TYPE_MAIN_VARIANT (type),
+					    cp_type_quals (type));
 	  if (clk != clk_none && !(clk & clk_class))
 	    type = cp_build_reference_type (type, (clk & clk_rvalueref));
 	}
     }
 
   return type;
 }
 
 /* Called from trait_expr_value to evaluate either __has_nothrow_assign or 
    __has_nothrow_copy, depending on assign_p.  */
Index: testsuite/g++.dg/cpp0x/decltype-54581.C
===================================================================
--- testsuite/g++.dg/cpp0x/decltype-54581.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/decltype-54581.C	(revision 0)
@@ -0,0 +1,28 @@ 
+/* { dg-do compile } */
+/* { dg-options "-std=gnu++11 -Wall" } */
+
+typedef float v4f __attribute__((vector_size(4*sizeof(float))));
+
+template <class T> void eat (T&&) {}
+
+void test1 ()
+{
+  v4f x = {0,1,2,3};
+  typedef decltype (x < x) v4i;
+  v4i y = {4,5,6,7}; // v4i is not opaque
+  eat (y);
+}
+
+template<class V>
+void test2 ()
+{
+  V x = {0,1,2,3};
+  typedef decltype (x < x) v4i;
+  v4i y = {4,5,6,7}; // v4i is not opaque
+  eat (y);
+}
+
+int main(){
+  test1();
+  test2<v4f>();
+}