* mangle.c (maybe_check_abi_tags): Add for_decl parm. Call
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 Feb 2016 06:25:05 +0000 (06:25 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 Feb 2016 06:25:05 +0000 (06:25 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@233544 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/mangle.c
gcc/testsuite/g++.dg/abi/abi-tag16a.C
gcc/testsuite/g++.dg/abi/abi-tag18.C [new file with mode: 0644]
gcc/testsuite/g++.dg/abi/abi-tag18a.C [new file with mode: 0644]

index 18f8072..96150be 100644 (file)
@@ -1,3 +1,11 @@
+2016-02-18  Jason Merrill  <jason@redhat.com>
+
+       * 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.
+
 2016-02-17  Jason Merrill  <jason@redhat.com>
 
        PR c++/65985
index 410c7f4..5d38373 100644 (file)
@@ -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);
index b02e856..12fe312 100644 (file)
@@ -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 (file)
index 0000000..89ee737
--- /dev/null
@@ -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 (file)
index 0000000..f65f629
--- /dev/null
@@ -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();
+}