ipa: Improve error handling for target_clone single value

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.
This commit is contained in:
Martin Liska 2022-02-28 13:27:22 +01:00
parent b88f683e57
commit 6df0c8d417
5 changed files with 44 additions and 25 deletions

View 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;

View 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)

View File

@ -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" } */

View 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 {

View 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 */