https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70501

This fixes 70501. The cause is an omission in typeck when converting a scalar operand to a vector. We use build_vector_from_val, which can return a CONSTRUCTOR. We fail to wrap that CONSTRUCTOR in a TARGET_EXPR.

The ICE arises because at the point we meet that CONSTRUCTOR during the constexpr processing, the currently active object under construction is that for the result of the <= operator, which has type vector-of-bool, rather than vector-of-int. (thus this problem arises in other vector ops, but mostly undetected because the result type is the same as the operand type)

ok?

nathan
2016-04-04  Nathan Sidwell  <nat...@acm.org>

	PR c++/70501
	* typeck.c (cp_build_binary_op): Wrap vector constructors in
	target_exprs.

	* g++.dg/init/pr70501.C: New.

Index: cp/typeck.c
===================================================================
--- cp/typeck.c	(revision 234715)
+++ cp/typeck.c	(working copy)
@@ -4196,6 +4196,8 @@ cp_build_binary_op (location_t location,
               op0 = convert (TREE_TYPE (type1), op0);
 	      op0 = save_expr (op0);
               op0 = build_vector_from_val (type1, op0);
+	      if (TREE_CODE (op0) == CONSTRUCTOR)
+		op0 = get_target_expr (op0);
               type0 = TREE_TYPE (op0);
               code0 = TREE_CODE (type0);
               converted = 1;
@@ -4206,6 +4208,8 @@ cp_build_binary_op (location_t location,
               op1 = convert (TREE_TYPE (type0), op1);
 	      op1 = save_expr (op1);
               op1 = build_vector_from_val (type0, op1);
+	      if (TREE_CODE (op1) == CONSTRUCTOR)
+		op1 = get_target_expr (op1);
               type1 = TREE_TYPE (op1);
               code1 = TREE_CODE (type1);
               converted = 1;
Index: testsuite/g++.dg/init/pr70501.C
===================================================================
--- testsuite/g++.dg/init/pr70501.C	(nonexistent)
+++ testsuite/g++.dg/init/pr70501.C	(working copy)
@@ -0,0 +1,11 @@
+/* { dg-options "" } Not pedantic */
+
+typedef int v4si __attribute__ ((vector_size (16)));
+
+struct S { v4si v; };
+
+void
+fn2 (int i, int j)
+{
+  struct S s = { .v = i <= j + (v4si){(1, 2)} };
+}

Reply via email to