aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Macleod <amacleod@redhat.com>2015-12-15 19:24:44 +0000
committerAndrew Macleod <amacleod@redhat.com>2015-12-15 19:24:44 +0000
commitb2f2c95f2a1288e3d9af7859319d56d6ee8933f1 (patch)
tree85b517fa8222f5647605014a315a79608f09a4e2
parente5883cd4bca4586cf8cdcfe294f5efc9eccfcbbd (diff)
handle_tm_attribute needs to be split into decl and type now.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/ttype-2015@231662 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/c-family/c-common.c82
-rw-r--r--gcc/testsuite/g++.dg/plugin/attribute_plugin.c2
2 files changed, 58 insertions, 26 deletions
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 13b891f5886..bc7b37dea50 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -369,7 +369,8 @@ static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
static tree handle_no_limit_stack_attribute (tree *, tree, tree, int,
bool *);
static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
-static tree handle_tm_attribute (tree *, tree, tree, int, bool *);
+static tree handle_tm_decl_attribute (tree *, tree, tree, int, bool *);
+static tree handle_tm_type_attribute (tree *, tree, tree, int, bool *);
static tree handle_tm_wrap_attribute (tree *, tree, tree, int, bool *);
static tree handle_novops_attribute (tree *, tree, tree, int, bool *);
static tree handle_deprecated_type_attribute (tree *, tree, tree, int,
@@ -743,19 +744,25 @@ const struct attribute_spec c_common_attribute_table[] =
{ "pure", 0, 0, true, false, false,
handle_pure_attribute, NULL, false },
{ "transaction_callable", 0, 0, false, true, false,
- NULL, handle_tm_attribute, false },
+ handle_tm_decl_attribute,
+ handle_tm_type_attribute, false },
{ "transaction_unsafe", 0, 0, false, true, false,
- NULL, handle_tm_attribute, true },
+ handle_tm_decl_attribute,
+ handle_tm_type_attribute, true },
{ "transaction_safe", 0, 0, false, true, false,
- NULL, handle_tm_attribute, true },
+ handle_tm_decl_attribute,
+ handle_tm_type_attribute, true },
{ "transaction_safe_dynamic", 0, 0, true, false, false,
- NULL, handle_tm_attribute, false },
+ handle_tm_decl_attribute,
+ handle_tm_type_attribute, false },
{ "transaction_may_cancel_outer", 0, 0, false, true, false,
- NULL, handle_tm_attribute, false },
+ handle_tm_decl_attribute,
+ handle_tm_type_attribute, false },
/* ??? These two attributes didn't make the transition from the
Intel language document to the multi-vendor language document. */
{ "transaction_pure", 0, 0, false, true, false,
- NULL, handle_tm_attribute, false },
+ handle_tm_decl_attribute,
+ handle_tm_type_attribute, false },
{ "transaction_wrap", 1, 1, true, false, false,
handle_tm_wrap_attribute, NULL, false },
/* For internal use (marking of builtins) only. The name contains space
@@ -9225,7 +9232,49 @@ find_tm_attribute (tree list)
processing given by function_type_required. */
static tree
-handle_tm_attribute (tree *node, tree name, tree args,
+handle_tm_decl_attribute (tree *node, tree name, tree args,
+ int flags, bool *no_add_attrs)
+{
+ /* Only one path adds the attribute; others don't. */
+ *no_add_attrs = true;
+
+ switch (TREE_CODE (*node))
+ {
+ case FUNCTION_DECL:
+ {
+ /* transaction_safe_dynamic goes on the FUNCTION_DECL, but we also
+ want to set transaction_safe on the type. */
+ gcc_assert (is_attribute_p ("transaction_safe_dynamic", name));
+ if (!TYPE_P (DECL_CONTEXT (*node)))
+ error_at (DECL_SOURCE_LOCATION (*node),
+ "%<transaction_safe_dynamic%> may only be specified for "
+ "a virtual function");
+ *no_add_attrs = false;
+ decl_attributes (&TREE_TYPE (*node),
+ build_tree_list (get_identifier ("transaction_safe"),
+ NULL_TREE),
+ 0);
+ break;
+ }
+
+ default:
+ /* If a function is next, pass it on to be tried next. */
+ if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
+ return tree_cons (name, args, NULL);
+ }
+
+ return NULL_TREE;
+}
+
+/* Handle the TM attributes; arguments as in struct attribute_spec.handler.
+ Here we accept only function types, and verify that none of the other
+ function TM attributes are also applied. */
+/* ??? We need to accept class types for C++, but not C. This greatly
+ complicates this function, since we can no longer rely on the extra
+ processing given by function_type_required. */
+
+static tree
+handle_tm_type_attribute (tree *node, tree name, tree args,
int flags, bool *no_add_attrs)
{
/* Only one path adds the attribute; others don't. */
@@ -9253,23 +9302,6 @@ handle_tm_attribute (tree *node, tree name, tree args,
}
break;
- case FUNCTION_DECL:
- {
- /* transaction_safe_dynamic goes on the FUNCTION_DECL, but we also
- want to set transaction_safe on the type. */
- gcc_assert (is_attribute_p ("transaction_safe_dynamic", name));
- if (!TYPE_P (DECL_CONTEXT (*node)))
- error_at (DECL_SOURCE_LOCATION (*node),
- "%<transaction_safe_dynamic%> may only be specified for "
- "a virtual function");
- *no_add_attrs = false;
- decl_attributes (&TREE_TYPE (*node),
- build_tree_list (get_identifier ("transaction_safe"),
- NULL_TREE),
- 0);
- break;
- }
-
case POINTER_TYPE:
{
enum tree_code subcode = TREE_CODE (TREE_TYPE (*node));
diff --git a/gcc/testsuite/g++.dg/plugin/attribute_plugin.c b/gcc/testsuite/g++.dg/plugin/attribute_plugin.c
index 8de5f44cbf8..4f52df73e1e 100644
--- a/gcc/testsuite/g++.dg/plugin/attribute_plugin.c
+++ b/gcc/testsuite/g++.dg/plugin/attribute_plugin.c
@@ -26,7 +26,7 @@ handle_user_attribute (tree *node, tree name, tree args,
/* Attribute definition */
static struct attribute_spec user_attr =
- { "user", 1, 1, false, false, false, handle_user_attribute, false };
+ { "user", 1, 1, false, false, false, handle_user_attribute, NULL, false };
/* Plugin callback called during attribute registration */