aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2013-06-03 19:13:10 -0400
committerJason Merrill <jason@gcc.gnu.org>2013-06-03 19:13:10 -0400
commit3aaaa103d7be29175917b4c85412d2791e63224d (patch)
tree13ba1c4610ca51396feea7cbd848364f442a6dd7 /gcc
parent25c229379aa6c0bc8cadd913e014dd9be62453f3 (diff)
downloadgcc-3aaaa103d7be29175917b4c85412d2791e63224d.zip
gcc-3aaaa103d7be29175917b4c85412d2791e63224d.tar.gz
gcc-3aaaa103d7be29175917b4c85412d2791e63224d.tar.bz2
class.c (mark_type_abi_tags): New.
* class.c (mark_type_abi_tags): New. (check_abi_tags): Use it. From-SVN: r199629
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/class.c44
-rw-r--r--gcc/testsuite/g++.dg/abi/abi-tag5.C6
3 files changed, 41 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a30a7d6..76c401e 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 22cdf90..40e6d3e 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 0000000..de55802
--- /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;