]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[C++] Fix ICE for binding lax vector conversions to references (PR 93014)
authorRichard Sandiford <richard.sandiford@arm.com>
Mon, 23 Dec 2019 09:43:35 +0000 (09:43 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Mon, 23 Dec 2019 09:43:35 +0000 (09:43 +0000)
This test:

typedef unsigned int v4si __attribute__ ((vector_size(16)));
typedef unsigned char v16qi __attribute__ ((vector_size(16)));
extern v16qi x;
v4si &y = x;

ICEs with:

a.c:4:11: internal compiler error: in convert_like_real, at cp/call.c:7670

This started with r260780, which had the effect of making lvalue_kind
look through VIEW_CONVERT_EXPR in all cases, not just for location
wrappers.  This also means that:

typedef unsigned int v4si __attribute__ ((vector_size(16)));
typedef unsigned char v16qi __attribute__ ((vector_size(16)));
extern v16qi x;
v4si &y = reinterpret_cast<v4si>(x);

is now valid despite the result of the cast being an rvalue.

The patch attempts to fix that by calling rvalue on the input to the
conversion, so that the tree looks the same as for:

  extern v16qi x;
  v4si &y = (v4si)x;

which is already handled correctly.

2019-12-23  Richard Sandiford  <richard.sandiford@arm.com>

gcc/cp/
* cvt.c (ocp_convert): Apply rvalue to the source of vector
conversions.
* typeck.c (build_reinterpret_cast_1): Likewise.

gcc/testsuite/
* g++.dg/ext/vector39.C: New test.

From-SVN: r279716

gcc/cp/ChangeLog
gcc/cp/cvt.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/vector39.C [new file with mode: 0644]

index b047dbff0f2938b043f524e5e3404ce56ebc3f9e..720c3ee0e738f466236831dbb865331b455c407e 100644 (file)
@@ -1,3 +1,9 @@
+2019-12-23  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * cvt.c (ocp_convert): Apply rvalue to the source of vector
+       conversions.
+       * typeck.c (build_reinterpret_cast_1): Likewise.
+
 2019-12-19  Marek Polacek  <polacek@redhat.com>
 
        PR c++/92745 - bogus error when initializing array of vectors.
index e922e4d9b893e48a2a4fff93c3ed740c2fa2d1ee..9e29225cfbb88affc49d52a30356b057fe028467 100644 (file)
@@ -744,7 +744,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
       else if (TREE_CODE (type) == COMPLEX_TYPE)
        return convert_to_complex_maybe_fold (type, e, dofold);
       else if (VECTOR_TYPE_P (type))
-       return convert_to_vector (type, e);
+       return convert_to_vector (type, rvalue (e));
       else if (TREE_CODE (e) == TARGET_EXPR)
        {
          /* Don't build a NOP_EXPR of class type.  Instead, change the
@@ -881,7 +881,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
                      in_vtype, type);
          return error_mark_node;
        }
-      return convert_to_vector (type, e);
+      return convert_to_vector (type, rvalue (e));
     }
   if (code == REAL_TYPE || code == COMPLEX_TYPE)
     {
index 41ef8966f49f7f80fcafca54d3548ec3bc791de9..d2f4a001e503ab9e5321791d4838f86b61fdf839 100644 (file)
@@ -7858,7 +7858,7 @@ build_reinterpret_cast_1 (location_t loc, tree type, tree expr,
       return build_nop_reinterpret (type, expr);
     }
   else if (gnu_vector_type_p (type))
-    return convert_to_vector (type, expr);
+    return convert_to_vector (type, rvalue (expr));
   else if (gnu_vector_type_p (intype)
           && INTEGRAL_OR_ENUMERATION_TYPE_P (type))
     return convert_to_integer_nofold (type, expr);
index e7cdf80e546b1301919835cb600139599595a909..321d54b47fc9a4c268c791c2f44a1a2653397a85 100644 (file)
@@ -1,3 +1,7 @@
+2019-12-23  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * g++.dg/ext/vector39.C: New test.
+
 2019-12-21  Andrew Pinski  <apinski@marvell.com>
 
        PR testsuite/92998
diff --git a/gcc/testsuite/g++.dg/ext/vector39.C b/gcc/testsuite/g++.dg/ext/vector39.C
new file mode 100644 (file)
index 0000000..140784d
--- /dev/null
@@ -0,0 +1,96 @@
+// { dg-options "-flax-vector-conversions" }
+
+typedef unsigned char v16qi __attribute__((vector_size(16)));
+typedef unsigned int v4si __attribute__((vector_size(16)));
+
+extern v4si normal_v4si;
+extern const v4si const_v4si;
+extern v4si *normal_v4si_ptr;
+extern const v4si *const_v4si_ptr;
+extern v4si &normal_v4si_ref;
+extern const v4si &const_v4si_ref;
+
+extern v16qi normal_v16qi;
+extern const v16qi const_v16qi;
+extern v16qi *normal_v16qi_ptr;
+extern const v16qi *const_v16qi_ptr;
+extern v16qi &normal_v16qi_ref;
+extern const v16qi &const_v16qi_ref;
+
+namespace nonconst_refs {
+  v16qi &ref_normal_v4si = normal_v4si; // { dg-error {cannot bind non-const lvalue} }
+  v16qi &ref_const_v4si = const_v4si; // { dg-error {cannot bind non-const lvalue} }
+  v16qi &ref_normal_v4si_ptr = *normal_v4si_ptr; // { dg-error {cannot bind non-const lvalue} }
+  v16qi &ref_const_v4si_ptr = *const_v4si_ptr; // { dg-error {cannot bind non-const lvalue} }
+  v16qi &ref_normal_v4si_ref = normal_v4si_ref; // { dg-error {cannot bind non-const lvalue} }
+  v16qi &ref_const_v4si_ref = const_v4si_ref; // { dg-error {cannot bind non-const lvalue} }
+
+  v16qi &ref_normal_v16qi = normal_v16qi;
+  v16qi &ref_const_v16qi = const_v16qi; // { dg-error {discards qualifiers} }
+  v16qi &ref_normal_v16qi_ptr = *normal_v16qi_ptr;
+  v16qi &ref_const_v16qi_ptr = *const_v16qi_ptr; // { dg-error {discards qualifiers} }
+  v16qi &ref_normal_v16qi_ref = normal_v16qi_ref;
+  v16qi &ref_const_v16qi_ref = const_v16qi_ref; // { dg-error {discards qualifiers} }
+}
+
+#if __cplusplus >= 201103L
+namespace nonconst_rvalue_refs {
+  v16qi &&ref_normal_v4si = normal_v4si;
+  v16qi &&ref_const_v4si = const_v4si;
+  v16qi &&ref_normal_v4si_ptr = *normal_v4si_ptr;
+  v16qi &&ref_const_v4si_ptr = *const_v4si_ptr;
+  v16qi &&ref_normal_v4si_ref = normal_v4si_ref;
+  v16qi &&ref_const_v4si_ref = const_v4si_ref;
+
+  v16qi &&ref_normal_v16qi = normal_v16qi; // { dg-error {cannot bind rvalue reference} "" { target c++11 } }
+  v16qi &&ref_const_v16qi = const_v16qi; // { dg-error {cannot bind rvalue reference} "" { target c++11 } }
+  v16qi &&ref_normal_v16qi_ptr = *normal_v16qi_ptr; // { dg-error {cannot bind rvalue reference} "" { target c++11 } }
+  v16qi &&ref_const_v16qi_ptr = *const_v16qi_ptr; // { dg-error {cannot bind rvalue reference} "" { target c++11 } }
+  v16qi &&ref_normal_v16qi_ref = normal_v16qi_ref; // { dg-error {cannot bind rvalue reference} "" { target c++11 } }
+  v16qi &&ref_const_v16qi_ref = const_v16qi_ref; // { dg-error {cannot bind rvalue reference} "" { target c++11 } }
+}
+#endif
+
+namespace const_refs {
+  const v16qi &ref_normal_v4si = normal_v4si;
+  const v16qi &ref_const_v4si = const_v4si;
+  const v16qi &ref_normal_v4si_ptr = *normal_v4si_ptr;
+  const v16qi &ref_const_v4si_ptr = *const_v4si_ptr;
+  const v16qi &ref_normal_v4si_ref = normal_v4si_ref;
+  const v16qi &ref_const_v4si_ref = const_v4si_ref;
+
+  const v16qi &ref_normal_v16qi = normal_v16qi;
+  const v16qi &ref_const_v16qi = const_v16qi;
+  const v16qi &ref_normal_v16qi_ptr = *normal_v16qi_ptr;
+  const v16qi &ref_const_v16qi_ptr = *const_v16qi_ptr;
+  const v16qi &ref_normal_v16qi_ref = normal_v16qi_ref;
+  const v16qi &ref_const_v16qi_ref = const_v16qi_ref;
+}
+
+#if __cplusplus >= 201103L
+namespace const_rvalue_refs {
+  const v16qi &&ref_normal_v4si = normal_v4si;
+  const v16qi &&ref_const_v4si = const_v4si;
+  const v16qi &&ref_normal_v4si_ptr = *normal_v4si_ptr;
+  const v16qi &&ref_const_v4si_ptr = *const_v4si_ptr;
+  const v16qi &&ref_normal_v4si_ref = normal_v4si_ref;
+  const v16qi &&ref_const_v4si_ref = const_v4si_ref;
+
+  const v16qi &&ref_normal_v16qi = normal_v16qi; // { dg-error {cannot bind rvalue reference} "" { target c++11 } }
+  const v16qi &&ref_const_v16qi = const_v16qi; // { dg-error {cannot bind rvalue reference} "" { target c++11 } }
+  const v16qi &&ref_normal_v16qi_ptr = *normal_v16qi_ptr; // { dg-error {cannot bind rvalue reference} "" { target c++11 } }
+  const v16qi &&ref_const_v16qi_ptr = *const_v16qi_ptr; // { dg-error {cannot bind rvalue reference} "" { target c++11 } }
+  const v16qi &&ref_normal_v16qi_ref = normal_v16qi_ref; // { dg-error {cannot bind rvalue reference} "" { target c++11 } }
+  const v16qi &&ref_const_v16qi_ref = const_v16qi_ref; // { dg-error {cannot bind rvalue reference} "" { target c++11 } }
+}
+#endif
+
+namespace rvalue_reinterpret_refs {
+  v16qi &ref_normal_v4si = reinterpret_cast<v16qi>(normal_v4si); // { dg-error {cannot bind non-const lvalue} }
+  v16qi &ref_const_v4si = reinterpret_cast<v16qi>(const_v4si); // { dg-error {cannot bind non-const lvalue} }
+}
+
+namespace ref_reinterpret_refs {
+  v16qi &ref_normal_v4si = reinterpret_cast<v16qi &>(normal_v4si);
+  v16qi &ref_const_v4si = reinterpret_cast<v16qi &>(const_cast<v4si &>(const_v4si));
+}