re PR c++/55742 (__attribute__ in class function declaration cause "prototype does not match" errors.)
PR c++/55742 * config/i386/i386.c (ix86_valid_target_attribute_inner_p): Diagnose invalid args instead of ICEing on it. (ix86_valid_target_attribute_tree): Return error_mark_node if ix86_valid_target_attribute_inner_p failed. (ix86_valid_target_attribute_p): Return false only if ix86_valid_target_attribute_tree returned error_mark_node. Allow target("default") attribute. (sorted_attr_string): Change argument from const char * to tree, merge in all target attribute arguments rather than just one. Formatting fix. Use XNEWVEC instead of xmalloc and XDELETEVEC instead of free. Avoid using strcat. (ix86_mangle_function_version_assembler_name): Mangle target("default") as if no target attribute is present. Adjust sorted_attr_string caller. Avoid leaking memory. Use XNEWVEC instead of xmalloc and XDELETEVEC instead of free. (ix86_function_versions): Don't return true if one of the decls doesn't have target attribute. If they don't and one of the decls is DECL_FUNCTION_VERSIONED, report an error. Adjust sorted_attr_string caller. Use XDELETEVEC instead of free. (ix86_supports_function_versions): Remove. (make_name): Fix up formatting. (make_dispatcher_decl): Remove resolver_name and its initialization. Avoid leaking memory. (is_function_default_version): Return true if there is target("default") attribute rather than no target attribute at all. (make_resolver_func): Avoid leaking memory. (ix86_generate_version_dispatcher_body): Likewise. (TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS): Remove. * target.def (supports_function_versions): Remove. * doc/tm.texi.in (SUPPORTS_FUNCTION_VERSIONS): Remove. * doc/tm.texi: Regenerated. * c-common.c (handle_target_attribute): Revert 2012-12-26 change. * g++.dg/mv1.C: Moved to... * g++.dg/ext/mv1.C: ... here. Adjust test. * g++.dg/mv2.C: Moved to... * g++.dg/ext/mv2.C: ... here. Adjust test. * g++.dg/mv3.C: Moved to... * g++.dg/ext/mv3.C: ... here. * g++.dg/mv4.C: Moved to... * g++.dg/ext/mv4.C: ... here. * g++.dg/mv5.C: Moved to... * g++.dg/ext/mv5.C: ... here. Adjust test. * g++.dg/mv6.C: Moved to... * g++.dg/ext/mv6.C: ... here. Adjust test. * g++.dg/ext/mv7.C: New test. * g++.dg/ext/mv8.C: New test. * g++.dg/ext/mv9.C: New test. * g++.dg/ext/mv10.C: New test. * g++.dg/ext/mv11.C: New test. From-SVN: r195584
This commit is contained in:
parent
73cca0cc94
commit
3288746035
@ -1,3 +1,38 @@
|
||||
2013-01-30 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/55742
|
||||
* config/i386/i386.c (ix86_valid_target_attribute_inner_p): Diagnose
|
||||
invalid args instead of ICEing on it.
|
||||
(ix86_valid_target_attribute_tree): Return error_mark_node if
|
||||
ix86_valid_target_attribute_inner_p failed.
|
||||
(ix86_valid_target_attribute_p): Return false only if
|
||||
ix86_valid_target_attribute_tree returned error_mark_node. Allow
|
||||
target("default") attribute.
|
||||
(sorted_attr_string): Change argument from const char * to tree,
|
||||
merge in all target attribute arguments rather than just one.
|
||||
Formatting fix. Use XNEWVEC instead of xmalloc and XDELETEVEC
|
||||
instead of free. Avoid using strcat.
|
||||
(ix86_mangle_function_version_assembler_name): Mangle
|
||||
target("default") as if no target attribute is present. Adjust
|
||||
sorted_attr_string caller. Avoid leaking memory. Use XNEWVEC
|
||||
instead of xmalloc and XDELETEVEC instead of free.
|
||||
(ix86_function_versions): Don't return true if one of the decls
|
||||
doesn't have target attribute. If they don't and one of the decls
|
||||
is DECL_FUNCTION_VERSIONED, report an error. Adjust
|
||||
sorted_attr_string caller. Use XDELETEVEC instead of free.
|
||||
(ix86_supports_function_versions): Remove.
|
||||
(make_name): Fix up formatting.
|
||||
(make_dispatcher_decl): Remove resolver_name and its initialization.
|
||||
Avoid leaking memory.
|
||||
(is_function_default_version): Return true if there is
|
||||
target("default") attribute rather than no target attribute at all.
|
||||
(make_resolver_func): Avoid leaking memory.
|
||||
(ix86_generate_version_dispatcher_body): Likewise.
|
||||
(TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS): Remove.
|
||||
* target.def (supports_function_versions): Remove.
|
||||
* doc/tm.texi.in (SUPPORTS_FUNCTION_VERSIONS): Remove.
|
||||
* doc/tm.texi: Regenerated.
|
||||
|
||||
2013-01-30 Vladimir Makarov <vmakarov@redhat.com>
|
||||
|
||||
PR rtl-optimization/56144
|
||||
|
@ -1,3 +1,8 @@
|
||||
2013-01-30 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/55742
|
||||
* c-common.c (handle_target_attribute): Revert 2012-12-26 change.
|
||||
|
||||
2013-01-18 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR target/54908
|
||||
|
@ -8759,12 +8759,8 @@ handle_target_attribute (tree *node, tree name, tree args, int flags,
|
||||
warning (OPT_Wattributes, "%qE attribute ignored", name);
|
||||
*no_add_attrs = true;
|
||||
}
|
||||
/* Do not strip invalid target attributes for targets which support function
|
||||
multiversioning as the target string is used to determine versioned
|
||||
functions. */
|
||||
else if (! targetm.target_option.valid_attribute_p (*node, name, args,
|
||||
flags)
|
||||
&& ! targetm.target_option.supports_function_versions ())
|
||||
flags))
|
||||
*no_add_attrs = true;
|
||||
|
||||
return NULL_TREE;
|
||||
|
@ -4225,7 +4225,10 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[],
|
||||
}
|
||||
|
||||
else if (TREE_CODE (args) != STRING_CST)
|
||||
gcc_unreachable ();
|
||||
{
|
||||
error ("attribute %<target%> argument not a string");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Handle multiple arguments separated by commas. */
|
||||
next_optstr = ASTRDUP (TREE_STRING_POINTER (args));
|
||||
@ -4370,7 +4373,7 @@ ix86_valid_target_attribute_tree (tree args)
|
||||
/* Process each of the options on the chain. */
|
||||
if (! ix86_valid_target_attribute_inner_p (args, option_strings,
|
||||
&enum_opts_set))
|
||||
return NULL_TREE;
|
||||
return error_mark_node;
|
||||
|
||||
/* If the changed options are different from the default, rerun
|
||||
ix86_option_override_internal, and then save the options away.
|
||||
@ -4435,6 +4438,15 @@ ix86_valid_target_attribute_p (tree fndecl,
|
||||
{
|
||||
struct cl_target_option cur_target;
|
||||
bool ret = true;
|
||||
|
||||
/* attribute((target("default"))) does nothing, beyond
|
||||
affecting multi-versioning. */
|
||||
if (TREE_VALUE (args)
|
||||
&& TREE_CODE (TREE_VALUE (args)) == STRING_CST
|
||||
&& TREE_CHAIN (args) == NULL_TREE
|
||||
&& strcmp (TREE_STRING_POINTER (TREE_VALUE (args)), "default") == 0)
|
||||
return true;
|
||||
|
||||
tree old_optimize = build_optimization_node ();
|
||||
tree new_target, new_optimize;
|
||||
tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
|
||||
@ -4451,10 +4463,10 @@ ix86_valid_target_attribute_p (tree fndecl,
|
||||
new_target = ix86_valid_target_attribute_tree (args);
|
||||
new_optimize = build_optimization_node ();
|
||||
|
||||
if (!new_target)
|
||||
if (new_target == error_mark_node)
|
||||
ret = false;
|
||||
|
||||
else if (fndecl)
|
||||
else if (fndecl && new_target)
|
||||
{
|
||||
DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
|
||||
|
||||
@ -28948,26 +28960,44 @@ attr_strcmp (const void *v1, const void *v2)
|
||||
return strcmp (c1, c2);
|
||||
}
|
||||
|
||||
/* STR is the argument to target attribute. This function tokenizes
|
||||
/* ARGLIST is the argument to target attribute. This function tokenizes
|
||||
the comma separated arguments, sorts them and returns a string which
|
||||
is a unique identifier for the comma separated arguments. It also
|
||||
replaces non-identifier characters "=,-" with "_". */
|
||||
|
||||
static char *
|
||||
sorted_attr_string (const char *str)
|
||||
sorted_attr_string (tree arglist)
|
||||
{
|
||||
tree arg;
|
||||
size_t str_len_sum = 0;
|
||||
char **args = NULL;
|
||||
char *attr_str, *ret_str;
|
||||
char *attr = NULL;
|
||||
unsigned int argnum = 1;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < strlen (str); i++)
|
||||
if (str[i] == ',')
|
||||
argnum++;
|
||||
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;
|
||||
if (arg != arglist)
|
||||
argnum++;
|
||||
for (i = 0; i < strlen (str); i++)
|
||||
if (str[i] == ',')
|
||||
argnum++;
|
||||
}
|
||||
|
||||
attr_str = (char *)xmalloc (strlen (str) + 1);
|
||||
strcpy (attr_str, str);
|
||||
attr_str = XNEWVEC (char, str_len_sum);
|
||||
str_len_sum = 0;
|
||||
for (arg = arglist; arg; arg = TREE_CHAIN (arg))
|
||||
{
|
||||
const char *str = TREE_STRING_POINTER (TREE_VALUE (arg));
|
||||
size_t len = strlen (str);
|
||||
memcpy (attr_str + str_len_sum, str, len);
|
||||
attr_str[str_len_sum + len] = TREE_CHAIN (arg) ? ',' : '\0';
|
||||
str_len_sum += len + 1;
|
||||
}
|
||||
|
||||
/* Replace "=,-" with "_". */
|
||||
for (i = 0; i < strlen (attr_str); i++)
|
||||
@ -28988,18 +29018,20 @@ sorted_attr_string (const char *str)
|
||||
attr = strtok (NULL, ",");
|
||||
}
|
||||
|
||||
qsort (args, argnum, sizeof (char*), attr_strcmp);
|
||||
qsort (args, argnum, sizeof (char *), attr_strcmp);
|
||||
|
||||
ret_str = (char *)xmalloc (strlen (str) + 1);
|
||||
strcpy (ret_str, args[0]);
|
||||
for (i = 1; i < argnum; i++)
|
||||
ret_str = XNEWVEC (char, str_len_sum);
|
||||
str_len_sum = 0;
|
||||
for (i = 0; i < argnum; i++)
|
||||
{
|
||||
strcat (ret_str, "_");
|
||||
strcat (ret_str, args[i]);
|
||||
size_t len = strlen (args[i]);
|
||||
memcpy (ret_str + str_len_sum, args[i], len);
|
||||
ret_str[str_len_sum + len] = i < argnum - 1 ? '_' : '\0';
|
||||
str_len_sum += len + 1;
|
||||
}
|
||||
|
||||
free (args);
|
||||
free (attr_str);
|
||||
XDELETEVEC (args);
|
||||
XDELETEVEC (attr_str);
|
||||
return ret_str;
|
||||
}
|
||||
|
||||
@ -29011,8 +29043,8 @@ static tree
|
||||
ix86_mangle_function_version_assembler_name (tree decl, tree id)
|
||||
{
|
||||
tree version_attr;
|
||||
const char *orig_name, *version_string, *attr_str;
|
||||
char *assembler_name;
|
||||
const char *orig_name, *version_string;
|
||||
char *attr_str, *assembler_name;
|
||||
|
||||
if (DECL_DECLARED_INLINE_P (decl)
|
||||
&& lookup_attribute ("gnu_inline",
|
||||
@ -29036,9 +29068,11 @@ ix86_mangle_function_version_assembler_name (tree decl, tree id)
|
||||
version_string
|
||||
= TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (version_attr)));
|
||||
|
||||
attr_str = sorted_attr_string (version_string);
|
||||
assembler_name = (char *) xmalloc (strlen (orig_name)
|
||||
+ strlen (attr_str) + 2);
|
||||
if (strcmp (version_string, "default") == 0)
|
||||
return id;
|
||||
|
||||
attr_str = sorted_attr_string (TREE_VALUE (version_attr));
|
||||
assembler_name = XNEWVEC (char, strlen (orig_name) + strlen (attr_str) + 2);
|
||||
|
||||
sprintf (assembler_name, "%s.%s", orig_name, attr_str);
|
||||
|
||||
@ -29046,7 +29080,10 @@ ix86_mangle_function_version_assembler_name (tree decl, tree id)
|
||||
if (DECL_ASSEMBLER_NAME_SET_P (decl))
|
||||
SET_DECL_RTL (decl, NULL);
|
||||
|
||||
return get_identifier (assembler_name);
|
||||
tree ret = get_identifier (assembler_name);
|
||||
XDELETEVEC (attr_str);
|
||||
XDELETEVEC (assembler_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This function returns true if FN1 and FN2 are versions of the same function,
|
||||
@ -29057,10 +29094,9 @@ static bool
|
||||
ix86_function_versions (tree fn1, tree fn2)
|
||||
{
|
||||
tree attr1, attr2;
|
||||
const char *attr_str1, *attr_str2;
|
||||
char *target1, *target2;
|
||||
bool result;
|
||||
|
||||
|
||||
if (TREE_CODE (fn1) != FUNCTION_DECL
|
||||
|| TREE_CODE (fn2) != FUNCTION_DECL)
|
||||
return false;
|
||||
@ -29072,15 +29108,35 @@ ix86_function_versions (tree fn1, tree fn2)
|
||||
if (attr1 == NULL_TREE && attr2 == NULL_TREE)
|
||||
return false;
|
||||
|
||||
/* If one function does not have a target attribute, these are versions. */
|
||||
/* Diagnose missing target attribute if one of the decls is already
|
||||
multi-versioned. */
|
||||
if (attr1 == NULL_TREE || attr2 == NULL_TREE)
|
||||
return true;
|
||||
{
|
||||
if (DECL_FUNCTION_VERSIONED (fn1) || DECL_FUNCTION_VERSIONED (fn2))
|
||||
{
|
||||
if (attr2 != NULL_TREE)
|
||||
{
|
||||
tree tem = fn1;
|
||||
fn1 = fn2;
|
||||
fn2 = tem;
|
||||
attr1 = attr2;
|
||||
}
|
||||
error_at (DECL_SOURCE_LOCATION (fn2),
|
||||
"missing %<target%> attribute for multi-versioned %D",
|
||||
fn2);
|
||||
error_at (DECL_SOURCE_LOCATION (fn1),
|
||||
"previous declaration of %D", fn1);
|
||||
/* Prevent diagnosing of the same error multiple times. */
|
||||
DECL_ATTRIBUTES (fn2)
|
||||
= tree_cons (get_identifier ("target"),
|
||||
copy_node (TREE_VALUE (attr1)),
|
||||
DECL_ATTRIBUTES (fn2));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
attr_str1 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr1)));
|
||||
attr_str2 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr2)));
|
||||
|
||||
target1 = sorted_attr_string (attr_str1);
|
||||
target2 = sorted_attr_string (attr_str2);
|
||||
target1 = sorted_attr_string (TREE_VALUE (attr1));
|
||||
target2 = sorted_attr_string (TREE_VALUE (attr2));
|
||||
|
||||
/* The sorted target strings must be different for fn1 and fn2
|
||||
to be versions. */
|
||||
@ -29089,20 +29145,12 @@ ix86_function_versions (tree fn1, tree fn2)
|
||||
else
|
||||
result = true;
|
||||
|
||||
free (target1);
|
||||
free (target2);
|
||||
XDELETEVEC (target1);
|
||||
XDELETEVEC (target2);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* This target supports function multiversioning. */
|
||||
|
||||
static bool
|
||||
ix86_supports_function_versions (void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static tree
|
||||
ix86_mangle_decl_assembler_name (tree decl, tree id)
|
||||
{
|
||||
@ -29143,10 +29191,10 @@ make_name (tree decl, const char *suffix, bool make_unique)
|
||||
|
||||
/* Use '.' to concatenate names as it is demangler friendly. */
|
||||
if (make_unique)
|
||||
snprintf (global_var_name, name_len, "%s.%s.%s", name,
|
||||
unique_name, suffix);
|
||||
snprintf (global_var_name, name_len, "%s.%s.%s", name, unique_name,
|
||||
suffix);
|
||||
else
|
||||
snprintf (global_var_name, name_len, "%s.%s", name, suffix);
|
||||
snprintf (global_var_name, name_len, "%s.%s", name, suffix);
|
||||
|
||||
return global_var_name;
|
||||
}
|
||||
@ -29161,7 +29209,7 @@ static tree
|
||||
make_dispatcher_decl (const tree decl)
|
||||
{
|
||||
tree func_decl;
|
||||
char *func_name, *resolver_name;
|
||||
char *func_name;
|
||||
tree fn_type, func_type;
|
||||
bool is_uniq = false;
|
||||
|
||||
@ -29169,14 +29217,13 @@ make_dispatcher_decl (const tree decl)
|
||||
is_uniq = true;
|
||||
|
||||
func_name = make_name (decl, "ifunc", is_uniq);
|
||||
resolver_name = make_name (decl, "resolver", is_uniq);
|
||||
gcc_assert (resolver_name);
|
||||
|
||||
fn_type = TREE_TYPE (decl);
|
||||
func_type = build_function_type (TREE_TYPE (fn_type),
|
||||
TYPE_ARG_TYPES (fn_type));
|
||||
|
||||
func_decl = build_fn_decl (func_name, func_type);
|
||||
XDELETEVEC (func_name);
|
||||
TREE_USED (func_decl) = 1;
|
||||
DECL_CONTEXT (func_decl) = NULL_TREE;
|
||||
DECL_INITIAL (func_decl) = error_mark_node;
|
||||
@ -29198,9 +29245,14 @@ make_dispatcher_decl (const tree decl)
|
||||
static bool
|
||||
is_function_default_version (const tree decl)
|
||||
{
|
||||
return (TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& DECL_FUNCTION_VERSIONED (decl)
|
||||
&& lookup_attribute ("target", DECL_ATTRIBUTES (decl)) == NULL_TREE);
|
||||
if (TREE_CODE (decl) != FUNCTION_DECL
|
||||
|| !DECL_FUNCTION_VERSIONED (decl))
|
||||
return false;
|
||||
tree attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
|
||||
gcc_assert (attr);
|
||||
attr = TREE_VALUE (TREE_VALUE (attr));
|
||||
return (TREE_CODE (attr) == STRING_CST
|
||||
&& strcmp (TREE_STRING_POINTER (attr), "default") == 0);
|
||||
}
|
||||
|
||||
/* Make a dispatcher declaration for the multi-versioned function DECL.
|
||||
@ -29394,6 +29446,7 @@ make_resolver_func (const tree default_decl,
|
||||
/* Create the alias for dispatch to resolver here. */
|
||||
/*cgraph_create_function_alias (dispatch_decl, decl);*/
|
||||
cgraph_same_body_alias (NULL, dispatch_decl, decl);
|
||||
XDELETEVEC (resolver_name);
|
||||
return decl;
|
||||
}
|
||||
|
||||
@ -29455,7 +29508,7 @@ ix86_generate_version_dispatcher_body (void *node_p)
|
||||
}
|
||||
|
||||
dispatch_function_versions (resolver_decl, &fn_ver_vec, &empty_bb);
|
||||
|
||||
fn_ver_vec.release ();
|
||||
rebuild_cgraph_edges ();
|
||||
pop_cfun ();
|
||||
return resolver_decl;
|
||||
@ -42443,10 +42496,6 @@ ix86_memmodel_check (unsigned HOST_WIDE_INT val)
|
||||
#undef TARGET_OPTION_FUNCTION_VERSIONS
|
||||
#define TARGET_OPTION_FUNCTION_VERSIONS ix86_function_versions
|
||||
|
||||
#undef TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS
|
||||
#define TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS \
|
||||
ix86_supports_function_versions
|
||||
|
||||
#undef TARGET_CAN_INLINE_P
|
||||
#define TARGET_CAN_INLINE_P ix86_can_inline_p
|
||||
|
||||
|
@ -9907,11 +9907,6 @@ different target specific attributes, that is, they are compiled for
|
||||
different target machines.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} bool TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS (void)
|
||||
This target hook returns @code{true} if the target supports function
|
||||
multiversioning.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} bool TARGET_CAN_INLINE_P (tree @var{caller}, tree @var{callee})
|
||||
This target hook returns @code{false} if the @var{caller} function
|
||||
cannot inline @var{callee}, based on target specific information. By
|
||||
|
@ -9768,11 +9768,6 @@ different target specific attributes, that is, they are compiled for
|
||||
different target machines.
|
||||
@end deftypefn
|
||||
|
||||
@hook TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS
|
||||
This target hook returns @code{true} if the target supports function
|
||||
multiversioning.
|
||||
@end deftypefn
|
||||
|
||||
@hook TARGET_CAN_INLINE_P
|
||||
This target hook returns @code{false} if the @var{caller} function
|
||||
cannot inline @var{callee}, based on target specific information. By
|
||||
|
@ -2831,14 +2831,6 @@ DEFHOOK
|
||||
bool, (tree decl1, tree decl2),
|
||||
hook_bool_tree_tree_false)
|
||||
|
||||
/* This function returns true if the target supports function
|
||||
multiversioning. */
|
||||
DEFHOOK
|
||||
(supports_function_versions,
|
||||
"",
|
||||
bool, (void),
|
||||
hook_bool_void_false)
|
||||
|
||||
/* Function to determine if one function can inline another function. */
|
||||
#undef HOOK_PREFIX
|
||||
#define HOOK_PREFIX "TARGET_"
|
||||
|
@ -1,3 +1,24 @@
|
||||
2013-01-30 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/55742
|
||||
* g++.dg/mv1.C: Moved to...
|
||||
* g++.dg/ext/mv1.C: ... here. Adjust test.
|
||||
* g++.dg/mv2.C: Moved to...
|
||||
* g++.dg/ext/mv2.C: ... here. Adjust test.
|
||||
* g++.dg/mv3.C: Moved to...
|
||||
* g++.dg/ext/mv3.C: ... here.
|
||||
* g++.dg/mv4.C: Moved to...
|
||||
* g++.dg/ext/mv4.C: ... here.
|
||||
* g++.dg/mv5.C: Moved to...
|
||||
* g++.dg/ext/mv5.C: ... here. Adjust test.
|
||||
* g++.dg/mv6.C: Moved to...
|
||||
* g++.dg/ext/mv6.C: ... here. Adjust test.
|
||||
* g++.dg/ext/mv7.C: New test.
|
||||
* g++.dg/ext/mv8.C: New test.
|
||||
* g++.dg/ext/mv9.C: New test.
|
||||
* g++.dg/ext/mv10.C: New test.
|
||||
* g++.dg/ext/mv11.C: New test.
|
||||
|
||||
2013-01-30 Vladimir Makarov <vmakarov@redhat.com>
|
||||
|
||||
PR rtl-optimization/56144
|
||||
|
@ -6,7 +6,8 @@
|
||||
#include <assert.h>
|
||||
|
||||
/* Default version. */
|
||||
int foo ();
|
||||
int foo (); // Extra declaration that is merged with the second one.
|
||||
int foo () __attribute__ ((target("default")));
|
||||
/* The other versions of foo. Mix up the ordering and
|
||||
check if the dispatching does it in the order of priority. */
|
||||
/* Check combination of target attributes. */
|
||||
@ -65,7 +66,8 @@ int main ()
|
||||
return 0;
|
||||
}
|
||||
|
||||
int foo ()
|
||||
int __attribute__ ((target("default")))
|
||||
foo ()
|
||||
{
|
||||
return 0;
|
||||
}
|
12
gcc/testsuite/g++.dg/ext/mv10.C
Normal file
12
gcc/testsuite/g++.dg/ext/mv10.C
Normal file
@ -0,0 +1,12 @@
|
||||
// { dg-do assemble { target i?86-*-* x86_64-*-* } }
|
||||
// { dg-options "" }
|
||||
|
||||
__attribute__((target ("popcnt"), used))
|
||||
void foo (void)
|
||||
{
|
||||
}
|
||||
|
||||
__attribute__((target ("popcnt","avx"), used))
|
||||
void foo (void)
|
||||
{
|
||||
}
|
23
gcc/testsuite/g++.dg/ext/mv11.C
Normal file
23
gcc/testsuite/g++.dg/ext/mv11.C
Normal file
@ -0,0 +1,23 @@
|
||||
// { dg-do compile { target i?86-*-* x86_64-*-* } }
|
||||
// { dg-options "-msse2" }
|
||||
|
||||
int foo () __attribute__ ((target("default")));
|
||||
int foo () __attribute__ ((target("sse2")));
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return foo ();
|
||||
}
|
||||
|
||||
int __attribute__ ((target("default")))
|
||||
foo ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __attribute__ ((target("sse2")))
|
||||
foo ()
|
||||
{
|
||||
return 0;
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
#include <assert.h>
|
||||
|
||||
/* Default version. */
|
||||
int foo ();
|
||||
int foo () __attribute__ ((target ("default")));
|
||||
/* The dispatch checks should be in the exact reverse order of the
|
||||
declarations below. */
|
||||
int foo () __attribute__ ((target ("mmx")));
|
||||
@ -51,7 +51,7 @@ int main ()
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
int __attribute__ ((target("default")))
|
||||
foo ()
|
||||
{
|
||||
return 0;
|
@ -7,7 +7,7 @@
|
||||
|
||||
|
||||
/* Default version. */
|
||||
inline int
|
||||
inline int __attribute__ ((target ("default")))
|
||||
foo ()
|
||||
{
|
||||
return 0;
|
@ -8,6 +8,7 @@ class Foo
|
||||
{
|
||||
public:
|
||||
/* Default version of foo. */
|
||||
__attribute__ ((target("default")))
|
||||
int foo ()
|
||||
{
|
||||
return 0;
|
12
gcc/testsuite/g++.dg/ext/mv7.C
Normal file
12
gcc/testsuite/g++.dg/ext/mv7.C
Normal file
@ -0,0 +1,12 @@
|
||||
// { dg-do compile { target i?86-*-* x86_64-*-* } }
|
||||
// { dg-options "" }
|
||||
|
||||
__attribute__((target ("default")))
|
||||
void foo (void) // { dg-error "previously defined here" }
|
||||
{
|
||||
}
|
||||
|
||||
__attribute__((target (128)))
|
||||
void foo (void) // { dg-error "(not a string|redefinition)" }
|
||||
{
|
||||
}
|
7
gcc/testsuite/g++.dg/ext/mv8.C
Normal file
7
gcc/testsuite/g++.dg/ext/mv8.C
Normal file
@ -0,0 +1,7 @@
|
||||
// { dg-do compile { target i?86-*-* x86_64-*-* } }
|
||||
// { dg-options "" }
|
||||
|
||||
__attribute__((target (11,12)))
|
||||
void foo (void) // { dg-error "not a string" }
|
||||
{
|
||||
}
|
9
gcc/testsuite/g++.dg/ext/mv9.C
Normal file
9
gcc/testsuite/g++.dg/ext/mv9.C
Normal file
@ -0,0 +1,9 @@
|
||||
// { dg-do compile { target i?86-*-* x86_64-*-* } }
|
||||
// { dg-options "" }
|
||||
|
||||
void foo ();
|
||||
void foo () __attribute__((target ("sse4")));
|
||||
void foo () __attribute__((target ("default"))); // { dg-error "previous declaration" }
|
||||
void foo () // { dg-error "attribute for multi-versioned" }
|
||||
{
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user