Patchwork C++ PATCH to avoid false positives with -Wabi-tag

login
register
mail settings
Submitter Jason Merrill
Date June 3, 2013, 10:23 p.m.
Message ID <51AD1745.4030201@redhat.com>
Download mbox | patch
Permalink /patch/248437/
State New
Headers show

Comments

Jason Merrill - June 3, 2013, 10:23 p.m.
It occurred to me that -Wabi-tag would probably warn about a template 
instantiated with a class that has an ABI tag, and indeed it does.  This 
is unnecessary; since the template argument is part of the signature of 
the instantiation, we don't need to worry about the tag being hidden 
when the type is used as a base or member.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit fdeabae097d4140dd56345ee9ca81fb9d6df15b9
Author: Jason Merrill <jason@redhat.com>
Date:   Fri May 31 22:42:48 2013 -0400

    	* class.c (mark_type_abi_tags): New.
    	(check_abi_tags): Use it.

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 64918c6..286164d 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1354,39 +1354,55 @@  find_abi_tags_r (tree *tp, int */*walk_subtrees*/, void *data)
   return NULL_TREE;
 }
 
+/* Set IDENTIFIER_MARKED on all the ABI tags on T and its (transitively
+   complete) template arguments.  */
+
+static void
+mark_type_abi_tags (tree t, bool val)
+{
+  tree attributes = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (t));
+  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) = 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)
 {
-  tree attributes = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (t));
-  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) = true;
-	}
-    }
+  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;