diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-06-03 23:13:10 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-06-03 23:13:10 +0000 |
commit | 9181c3d9ceed054efd8488eaea91d89353bb8d21 (patch) | |
tree | 13ba1c4610ca51396feea7cbd848364f442a6dd7 | |
parent | cc92dddcc1ccf36b35e2533f1b0a0fe418c67144 (diff) | |
download | gcc-9181c3d9ceed054efd8488eaea91d89353bb8d21.tar.gz |
* class.c (mark_type_abi_tags): New.
(check_abi_tags): Use it.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@199629 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/class.c | 44 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/abi-tag5.C | 6 |
3 files changed, 41 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a30a7d63476..76c401e089b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2013-05-31 Jason Merrill <jason@redhat.com> + + * class.c (mark_type_abi_tags): New. + (check_abi_tags): Use it. + 2013-06-03 Paolo Carlini <paolo.carlini@oracle.com> PR c++/57419 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 22cdf90f735..40e6d3eed73 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1354,11 +1354,11 @@ find_abi_tags_r (tree *tp, int */*walk_subtrees*/, void *data) return NULL_TREE; } -/* Check that class T has all the abi tags that subobject SUBOB has, or - warn if not. */ +/* Set IDENTIFIER_MARKED on all the ABI tags on T and its (transitively + complete) template arguments. */ static void -check_abi_tags (tree t, tree subob) +mark_type_abi_tags (tree t, bool val) { tree attributes = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (t)); if (attributes) @@ -1368,25 +1368,41 @@ check_abi_tags (tree t, tree subob) { tree tag = TREE_VALUE (list); tree id = get_identifier (TREE_STRING_POINTER (tag)); - IDENTIFIER_MARKED (id) = true; + IDENTIFIER_MARKED (id) = val; + } + } + + /* Also mark ABI tags from template arguments. */ + if (CLASSTYPE_TEMPLATE_INFO (t)) + { + tree args = CLASSTYPE_TI_ARGS (t); + for (int i = 0; i < TMPL_ARGS_DEPTH (args); ++i) + { + tree level = TMPL_ARGS_LEVEL (args, i+1); + for (int j = 0; j < TREE_VEC_LENGTH (level); ++j) + { + tree arg = TREE_VEC_ELT (level, j); + if (CLASS_TYPE_P (arg)) + mark_type_abi_tags (arg, val); + } } } +} + +/* Check that class T has all the abi tags that subobject SUBOB has, or + warn if not. */ + +static void +check_abi_tags (tree t, tree subob) +{ + mark_type_abi_tags (t, true); tree subtype = TYPE_P (subob) ? subob : TREE_TYPE (subob); struct abi_tag_data data = { t, subob }; cp_walk_tree_without_duplicates (&subtype, find_abi_tags_r, &data); - if (attributes) - { - for (tree list = TREE_VALUE (attributes); list; - list = TREE_CHAIN (list)) - { - tree tag = TREE_VALUE (list); - tree id = get_identifier (TREE_STRING_POINTER (tag)); - IDENTIFIER_MARKED (id) = false; - } - } + mark_type_abi_tags (t, false); } /* Run through the base classes of T, updating CANT_HAVE_CONST_CTOR_P, diff --git a/gcc/testsuite/g++.dg/abi/abi-tag5.C b/gcc/testsuite/g++.dg/abi/abi-tag5.C new file mode 100644 index 00000000000..de5580239dd --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/abi-tag5.C @@ -0,0 +1,6 @@ +// { dg-options -Wabi-tag } + +struct __attribute__ ((abi_tag ("foo"))) A { }; +template <class T> struct B: T { }; + +B<A> b; |