PR c++/83911 - ICE with multiversioned constructor.
authorJason Merrill <jason@redhat.com>
Fri, 16 Mar 2018 12:38:42 +0000 (08:38 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 16 Mar 2018 12:38:42 +0000 (08:38 -0400)
* cp-gimplify.c (cp_genericize_r): Replace versioned function with
dispatchere here.
* call.c (build_over_call): Not here.
PR c++/83911 - ICE with multiversioned constructor.

From-SVN: r258592

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-gimplify.c
gcc/testsuite/g++.dg/ext/mv27.C [new file with mode: 0644]

index 7322a76bd8648b8d670313a16a0348408d789092..a5808604b9a548a5fdbb6440fb35431b2ddfe31e 100644 (file)
@@ -1,3 +1,10 @@
+2018-03-16  Jason Merrill  <jason@redhat.com>
+
+       PR c++/83911 - ICE with multiversioned constructor.
+       * cp-gimplify.c (cp_genericize_r): Replace versioned function with
+       dispatchere here.
+       * call.c (build_over_call): Not here.
+
 2018-03-16  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/84874
index 45c22aaa312c96b4e8eb326cd7310a4b17b9ce48..67438ff2e94b2ab05f01fc023fc3e1a1c82d51a2 100644 (file)
@@ -8204,23 +8204,6 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
        }
     }
 
-  /* For calls to a multi-versioned function, overload resolution
-     returns the function with the highest target priority, that is,
-     the version that will checked for dispatching first.  If this
-     version is inlinable, a direct call to this version can be made
-     otherwise the call should go through the dispatcher.  */
-
-  if (DECL_FUNCTION_VERSIONED (fn)
-      && (current_function_decl == NULL
-         || !targetm.target_option.can_inline_p (current_function_decl, fn)))
-    {
-      fn = get_function_version_dispatcher (fn);
-      if (fn == NULL)
-       return NULL;
-      if (!already_used)
-       mark_versions_used (fn);
-    }
-
   if (!already_used
       && !mark_used (fn, complain))
     return error_mark_node;
index 0ddd435454c92d26c45f98a58c40290d3d53fe3b..653d1dcee264755c6e95206944737a256a152059 100644 (file)
@@ -1513,6 +1513,29 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
                       == REFERENCE_TYPE))
            *walk_subtrees = 0;
        }
+      /* Fall through.  */
+    case AGGR_INIT_EXPR:
+      /* For calls to a multi-versioned function, overload resolution
+        returns the function with the highest target priority, that is,
+        the version that will checked for dispatching first.  If this
+        version is inlinable, a direct call to this version can be made
+        otherwise the call should go through the dispatcher.  */
+      {
+       tree fn = cp_get_callee_fndecl (stmt);
+       if (fn && DECL_FUNCTION_VERSIONED (fn)
+           && (current_function_decl == NULL
+               || !targetm.target_option.can_inline_p (current_function_decl,
+                                                       fn)))
+         if (tree dis = get_function_version_dispatcher (fn))
+           {
+             mark_versions_used (dis);
+             dis = build_address (dis);
+             if (TREE_CODE (stmt) == CALL_EXPR)
+               CALL_EXPR_FN (stmt) = dis;
+             else
+               AGGR_INIT_EXPR_FN (stmt) = dis;
+           }
+      }
       break;
 
     default:
diff --git a/gcc/testsuite/g++.dg/ext/mv27.C b/gcc/testsuite/g++.dg/ext/mv27.C
new file mode 100644 (file)
index 0000000..443a54b
--- /dev/null
@@ -0,0 +1,18 @@
+// PR c++/83911
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+// { dg-require-ifunc "" }
+
+class SimdFloat
+{
+public:
+    __attribute__ ((target ("default")))
+    SimdFloat(float x) {}
+
+    __attribute__ ((target ("avx2")))
+    SimdFloat(float x) {}
+};
+
+SimdFloat foo()
+{
+    return 1;
+}