]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix abi-tag16.C.
authorJason Merrill <jason@redhat.com>
Sun, 31 Jan 2016 11:52:56 +0000 (06:52 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 31 Jan 2016 11:52:56 +0000 (06:52 -0500)
* mangle.c (maybe_check_abi_tags): New.
(write_guarded_var_name): Call it.
(mangle_ref_init_variable): Call check_abi_tags.

From-SVN: r233018

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

index b95610451df34c2b4c3ebf882d209dbbf7b118df..0113e5da6ce7e199818856a8ae53cd0ab035f79f 100644 (file)
@@ -1,5 +1,9 @@
 2016-01-31  Jason Merrill  <jason@redhat.com>
 
+       * mangle.c (maybe_check_abi_tags): New.
+       (write_guarded_var_name): Call it.
+       (mangle_ref_init_variable): Call check_abi_tags.
+
        * pt.c (lookup_template_class_1): Don't share TYPE_ATTRIBUTES
        between template and instantiation.
 
index 4f1eea6335c38a5508b05a474c013c6384fc0512..2bb70481d1f15b8fe78e3732811ab79757cd7481 100644 (file)
@@ -3931,6 +3931,30 @@ mangle_conv_op_name_for_type (const tree type)
   return identifier;
 }
 
+/* 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.  */
+
+static void
+maybe_check_abi_tags (tree t)
+{
+  tree attr = lookup_attribute ("abi_tag", DECL_ATTRIBUTES (t));
+  tree oldtags = NULL_TREE;
+  if (attr)
+    oldtags = TREE_VALUE (attr);
+
+  check_abi_tags (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);
+}
+
 /* Write out the appropriate string for this variable when generating
    another mangled name based on this one.  */
 
@@ -3943,7 +3967,15 @@ write_guarded_var_name (const tree variable)
        to the reference, not the temporary.  */
     write_string (IDENTIFIER_POINTER (DECL_NAME (variable)) + 4);
   else
-    write_name (variable, /*ignore_local_scope=*/0);
+    {
+      /* 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);
+    }
 }
 
 /* Return an identifier for the name of an initialization guard
@@ -4007,6 +4039,7 @@ mangle_ref_init_variable (const tree variable)
 {
   start_mangling (variable);
   write_string ("_ZGR");
+  check_abi_tags (variable);
   write_name (variable, /*ignore_local_scope=*/0);
   /* Avoid name clashes with aggregate initialization of multiple
      references at once.  */
diff --git a/gcc/testsuite/g++.dg/abi/abi-tag16.C b/gcc/testsuite/g++.dg/abi/abi-tag16.C
new file mode 100644 (file)
index 0000000..d4fa142
--- /dev/null
@@ -0,0 +1,19 @@
+// { dg-options -Wabi=9 }
+// { dg-final { scan-assembler "_ZGVZN1N1FEvE4NameB5cxx11" } }
+namespace std {
+  __extension__ inline namespace __cxx11 __attribute__((abi_tag("cxx11"))) {
+    struct String {
+      String();
+    };
+  }
+}
+namespace N {
+  inline void F() {
+    {
+      static std::String Name; // { dg-warning "mangled name" }
+    }
+  }
+  void F2() {
+    F();
+  }
+}
diff --git a/gcc/testsuite/g++.dg/abi/abi-tag16a.C b/gcc/testsuite/g++.dg/abi/abi-tag16a.C
new file mode 100644 (file)
index 0000000..b02e856
--- /dev/null
@@ -0,0 +1,19 @@
+// { dg-options "-fabi-version=9 -Wabi" }
+// { dg-final { scan-assembler "_ZGVZN1N1FEvE4Name" } }
+namespace std {
+  __extension__ inline namespace __cxx11 __attribute__((abi_tag("cxx11"))) {
+    struct String {
+      String();
+    };
+  }
+}
+namespace N {
+  inline void F() {
+    {
+      static std::String Name; // { dg-warning "mangled name" }
+    }
+  }
+  void F2() {
+    F();
+  }
+}