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:
parent
b88f683e57
commit
6df0c8d417
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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" } */
|
24
gcc/tree.cc
24
gcc/tree.cc
|
@ -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 {
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue