ipa: Improve error handling for target_clone single value
authorMartin Liska <mliska@suse.cz>
Mon, 28 Feb 2022 12:27:22 +0000 (13:27 +0100)
committerMartin Liska <mliska@suse.cz>
Tue, 1 Mar 2022 09:10:29 +0000 (10:10 +0100)
PR ipa/104533

gcc/c-family/ChangeLog:

* c-attribs.cc (handle_target_clones_attribute): Use
get_target_clone_attr_len and report warning soon.

gcc/ChangeLog:

* multiple_target.cc (get_attr_len): Move to tree.c.
(expand_target_clones): Remove single value checking.
* tree.cc (get_target_clone_attr_len): New fn.
* tree.h (get_target_clone_attr_len): Likewise.

gcc/testsuite/ChangeLog:

* g++.target/i386/pr104533.C: New test.

gcc/c-family/c-attribs.cc
gcc/multiple_target.cc
gcc/testsuite/g++.target/i386/pr104533.C [new file with mode: 0644]
gcc/tree.cc
gcc/tree.h

index 3849dba..d394ea9 100644 (file)
@@ -5486,6 +5486,12 @@ handle_target_clones_attribute (tree *node, tree name, tree ARG_UNUSED (args),
                   "with %qs attribute", name, "target");
          *no_add_attrs = true;
        }
+      else if (get_target_clone_attr_len (args) == -1)
+       {
+         warning (OPT_Wattributes,
+                  "single %<target_clones%> attribute is ignored");
+         *no_add_attrs = true;
+       }
       else
       /* Do not inline functions with multiple clone targets.  */
        DECL_UNINLINABLE (*node) = 1;
index 5a5a75f..7fe02fb 100644 (file)
@@ -185,30 +185,6 @@ create_dispatcher_calls (struct cgraph_node *node)
     }
 }
 
-/* Return length of attribute names string,
-   if arglist chain > 1, -1 otherwise.  */
-
-static int
-get_attr_len (tree arglist)
-{
-  tree arg;
-  int str_len_sum = 0;
-  int argnum = 0;
-
-  for (arg = arglist; arg; arg = TREE_CHAIN (arg))
-    {
-      const char *str = TREE_STRING_POINTER (TREE_VALUE (arg));
-      size_t len = strlen (str);
-      str_len_sum += len + 1;
-      for (const char *p = strchr (str, ','); p; p = strchr (p + 1, ','))
-       argnum++;
-      argnum++;
-    }
-  if (argnum <= 1)
-    return -1;
-  return str_len_sum;
-}
-
 /* Create string with attributes separated by comma.
    Return number of attributes.  */
 
@@ -342,7 +318,7 @@ expand_target_clones (struct cgraph_node *node, bool definition)
     return false;
 
   tree arglist = TREE_VALUE (attr_target);
-  int attr_len = get_attr_len (arglist);
+  int attr_len = get_target_clone_attr_len (arglist);
 
   /* No need to clone for 1 target attribute.  */
   if (attr_len == -1)
diff --git a/gcc/testsuite/g++.target/i386/pr104533.C b/gcc/testsuite/g++.target/i386/pr104533.C
new file mode 100644 (file)
index 0000000..6a1d8de
--- /dev/null
@@ -0,0 +1,11 @@
+/* PR ipa/104533 */
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c++11 -fPIC -Ofast -fno-semantic-interposition" } */
+/* { dg-require-ifunc "" } */
+
+struct B
+{
+  virtual ~B();
+};
+__attribute__((target_clones("avx")))
+B::~B() = default; /* { dg-warning "single .target_clones. attribute is ignored" } */
index 2bbef2d..4522d90 100644 (file)
@@ -14553,6 +14553,30 @@ get_attr_nonstring_decl (tree expr, tree *ref)
   return NULL_TREE;
 }
 
+/* Return length of attribute names string,
+   if arglist chain > 1, -1 otherwise.  */
+
+int
+get_target_clone_attr_len (tree arglist)
+{
+  tree arg;
+  int str_len_sum = 0;
+  int argnum = 0;
+
+  for (arg = arglist; arg; arg = TREE_CHAIN (arg))
+    {
+      const char *str = TREE_STRING_POINTER (TREE_VALUE (arg));
+      size_t len = strlen (str);
+      str_len_sum += len + 1;
+      for (const char *p = strchr (str, ','); p; p = strchr (p + 1, ','))
+       argnum++;
+      argnum++;
+    }
+  if (argnum <= 1)
+    return -1;
+  return str_len_sum;
+}
+
 #if CHECKING_P
 
 namespace selftest {
index 95334b0..36ceed5 100644 (file)
@@ -6579,4 +6579,6 @@ extern unsigned fndecl_dealloc_argno (tree);
    object or pointer.  Otherwise return null.  */
 extern tree get_attr_nonstring_decl (tree, tree * = NULL);
 
+extern int get_target_clone_attr_len (tree);
+
 #endif  /* GCC_TREE_H  */