summaryrefslogtreecommitdiff
path: root/gcc/multiple_target.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2018-03-07 10:16:07 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2018-03-07 10:16:07 +0100
commit0f1de8d013d92e2996f6936ecb25b2561e48ca56 (patch)
tree2db484bc4a8d437f58ff81f1b50abf3051bdeb07 /gcc/multiple_target.c
parentd06202a0cb01ed4452b27a4bd9c5922510f85ada (diff)
re PR middle-end/84723 (ICE in create_target_clone, at multiple_target.c:275)
PR middle-end/84723 * multiple_target.c: Include tree-inline.h and intl.h. (expand_target_clones): Diagnose and fail if node->definition and !tree_versionable_function_p (node->decl). * gcc.target/i386/pr84723-1.c: New test. * gcc.target/i386/pr84723-2.c: New test. * gcc.target/i386/pr84723-3.c: New test. * gcc.target/i386/pr84723-4.c: New test. * gcc.target/i386/pr84723-5.c: New test. From-SVN: r258316
Diffstat (limited to 'gcc/multiple_target.c')
-rw-r--r--gcc/multiple_target.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/gcc/multiple_target.c b/gcc/multiple_target.c
index ecf69fc2124..a6767985774 100644
--- a/gcc/multiple_target.c
+++ b/gcc/multiple_target.c
@@ -36,6 +36,8 @@ along with GCC; see the file COPYING3. If not see
#include "pretty-print.h"
#include "gimple-iterator.h"
#include "gimple-walk.h"
+#include "tree-inline.h"
+#include "intl.h"
/* Walker callback that replaces all FUNCTION_DECL of a function that's
going to be versioned. */
@@ -312,6 +314,22 @@ expand_target_clones (struct cgraph_node *node, bool definition)
return false;
}
+ if (node->definition
+ && !tree_versionable_function_p (node->decl))
+ {
+ error_at (DECL_SOURCE_LOCATION (node->decl),
+ "clones for %<target_clones%> attribute cannot be created");
+ const char *reason = NULL;
+ if (lookup_attribute ("noclone", DECL_ATTRIBUTES (node->decl)))
+ reason = G_("function %q+F can never be copied "
+ "because it has %<noclone%> attribute");
+ else
+ reason = copy_forbidden (DECL_STRUCT_FUNCTION (node->decl));
+ if (reason)
+ inform (DECL_SOURCE_LOCATION (node->decl), reason, node->decl);
+ return false;
+ }
+
char *attr_str = XNEWVEC (char, attr_len);
int attrnum = get_attr_str (arglist, attr_str);
char **attrs = XNEWVEC (char *, attrnum);