diff mbox

C++ PATCHes for abi_tag bugs

Message ID 56C6B512.2000503@redhat.com
State New
Headers show

Commit Message

Jason Merrill Feb. 19, 2016, 6:24 a.m. UTC
On 01/31/2016 06:49 AM, Jason Merrill wrote:
> These patches fix a couple of abi_tag bugs that were reported to me
> recently.
>
...
>
> The second is an issue where the multiple-initialization guard for a
> tagged variable was not itself tagged.

That didn't completely fix the issue.  Trying again:
diff mbox

Patch

commit 09ebcab51e037bc236bb804ca5cc5d27a2f1fb9b
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Feb 19 00:51:35 2016 -0500

    	* mangle.c (maybe_check_abi_tags): Add for_decl parm.  Call
    	mangle_decl.
    	(mangle_decl): Call maybe_check_abi_tags for function scope.
    	(mangle_guard_variable): Call maybe_check_abi_tags here.
    	(write_guarded_var_name): Not here.

diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 410c7f4..5d38373 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -223,6 +223,7 @@  static void write_local_name (tree, const tree, const tree);
 static void dump_substitution_candidates (void);
 static tree mangle_decl_string (const tree);
 static int local_class_index (tree);
+static void maybe_check_abi_tags (tree, tree = NULL_TREE);
 
 /* Control functions.  */
 
@@ -3599,6 +3600,9 @@  mangle_decl (const tree decl)
     {
       gcc_assert (TREE_CODE (decl) != TYPE_DECL
 		  || !no_linkage_check (TREE_TYPE (decl), true));
+      if (abi_version_at_least (10))
+	if (tree fn = decl_function_context (decl))
+	  maybe_check_abi_tags (fn, decl);
       id = get_mangled_id (decl);
     }
   SET_DECL_ASSEMBLER_NAME (decl, id);
@@ -3937,26 +3941,39 @@  mangle_conv_op_name_for_type (const tree type)
 
 /* Handle ABI backwards compatibility for past bugs where we didn't call
    check_abi_tags in places where it's needed: call check_abi_tags and warn if
-   it makes a difference.  */
+   it makes a difference.  If FOR_DECL is non-null, it's the declaration
+   that we're actually trying to mangle; if it's null, we're mangling the
+   guard variable for T.  */
 
 static void
-maybe_check_abi_tags (tree t)
+maybe_check_abi_tags (tree t, tree for_decl)
 {
+  if (DECL_ASSEMBLER_NAME_SET_P (t))
+    return;
+
   tree attr = lookup_attribute ("abi_tag", DECL_ATTRIBUTES (t));
   tree oldtags = NULL_TREE;
   if (attr)
     oldtags = TREE_VALUE (attr);
 
-  check_abi_tags (t);
+  mangle_decl (t);
 
   if (!attr)
     attr = lookup_attribute ("abi_tag", DECL_ATTRIBUTES (t));
   if (attr && TREE_VALUE (attr) != oldtags
       && abi_version_crosses (10))
-    warning_at (DECL_SOURCE_LOCATION (t), OPT_Wabi,
-		"the mangled name of the initialization guard variable for"
-		"%qD changes between -fabi-version=%d and -fabi-version=%d",
-		t, flag_abi_version, warn_abi_version);
+    {
+      if (for_decl)
+	warning_at (DECL_SOURCE_LOCATION (for_decl), OPT_Wabi,
+		    "the mangled name of %qD changes between "
+		    "-fabi-version=%d and -fabi-version=%d",
+		    for_decl, flag_abi_version, warn_abi_version);
+      else
+	warning_at (DECL_SOURCE_LOCATION (t), OPT_Wabi,
+		    "the mangled name of the initialization guard variable for"
+		    "%qD changes between -fabi-version=%d and -fabi-version=%d",
+		    t, flag_abi_version, warn_abi_version);
+    }
 }
 
 /* Write out the appropriate string for this variable when generating
@@ -3971,15 +3988,7 @@  write_guarded_var_name (const tree variable)
        to the reference, not the temporary.  */
     write_string (IDENTIFIER_POINTER (DECL_NAME (variable)) + 4);
   else
-    {
-      /* Before ABI v10 we were failing to call check_abi_tags here.  So if
-	 we're in pre-10 mode, wait until after write_name to call it.  */
-      if (abi_version_at_least (10))
-	maybe_check_abi_tags (variable);
-      write_name (variable, /*ignore_local_scope=*/0);
-      if (!abi_version_at_least (10))
-	maybe_check_abi_tags (variable);
-    }
+    write_name (variable, /*ignore_local_scope=*/0);
 }
 
 /* Return an identifier for the name of an initialization guard
@@ -3988,6 +3997,8 @@  write_guarded_var_name (const tree variable)
 tree
 mangle_guard_variable (const tree variable)
 {
+  if (abi_version_at_least (10))
+    maybe_check_abi_tags (variable);
   start_mangling (variable);
   write_string ("_ZGV");
   write_guarded_var_name (variable);
diff --git a/gcc/testsuite/g++.dg/abi/abi-tag16a.C b/gcc/testsuite/g++.dg/abi/abi-tag16a.C
index b02e856..12fe312 100644
--- a/gcc/testsuite/g++.dg/abi/abi-tag16a.C
+++ b/gcc/testsuite/g++.dg/abi/abi-tag16a.C
@@ -1,4 +1,4 @@ 
-// { dg-options "-fabi-version=9 -Wabi" }
+// { dg-options "-fabi-version=9" }
 // { dg-final { scan-assembler "_ZGVZN1N1FEvE4Name" } }
 namespace std {
   __extension__ inline namespace __cxx11 __attribute__((abi_tag("cxx11"))) {
@@ -10,7 +10,7 @@  namespace std {
 namespace N {
   inline void F() {
     {
-      static std::String Name;	// { dg-warning "mangled name" }
+      static std::String Name;
     }
   }
   void F2() {
diff --git a/gcc/testsuite/g++.dg/abi/abi-tag18.C b/gcc/testsuite/g++.dg/abi/abi-tag18.C
new file mode 100644
index 0000000..89ee737
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/abi-tag18.C
@@ -0,0 +1,20 @@ 
+// { dg-options -Wabi=9 }
+// { dg-final { scan-assembler "_Z1fB7__test1v" } }
+// { dg-final { scan-assembler "_ZZ1fB7__test1vEN1T1gB7__test2Ev" } }
+// { dg-final { scan-assembler "_ZZZ1fB7__test1vEN1T1gB7__test2EvE1x" } }
+// { dg-final { scan-assembler "_ZGVZZ1fB7__test1vEN1T1gB7__test2EvE1x" } }
+
+struct X { ~X(); };
+inline namespace __test1 __attribute__((abi_tag)) { struct A1 { }; }
+inline namespace __test2 __attribute__((abi_tag)) { struct A2 { }; }
+inline A1 f() {
+  struct T {
+    A2 g() {			// { dg-warning "mangled name" }
+      static X x;		// { dg-warning "mangled name" }
+    }
+  };
+  T().g();
+}
+int main() {
+  f();
+}
diff --git a/gcc/testsuite/g++.dg/abi/abi-tag18a.C b/gcc/testsuite/g++.dg/abi/abi-tag18a.C
new file mode 100644
index 0000000..f65f629
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/abi-tag18a.C
@@ -0,0 +1,20 @@ 
+// { dg-options -fabi-version=9 }
+// { dg-final { scan-assembler "_Z1fB7__test1v" } }
+// { dg-final { scan-assembler "_ZZ1fB7__test1vEN1T1gB7__test2Ev" } }
+// { dg-final { scan-assembler "_ZZZ1fB7__test1vEN1T1gEvE1x" } }
+// { dg-final { scan-assembler "_ZGVZZ1fvEN1T1gEvE1x" } }
+
+struct X { ~X(); };
+inline namespace __test1 __attribute__((abi_tag)) { struct A1 { }; }
+inline namespace __test2 __attribute__((abi_tag)) { struct A2 { }; }
+inline A1 f() {
+  struct T {
+    A2 g() {
+      static X x;
+    }
+  };
+  T().g();
+}
+int main() {
+  f();
+}