]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/68049 (template instantiation involving may_alias defines symbol twice)
authorJason Merrill <jason@redhat.com>
Thu, 25 Feb 2016 14:09:18 +0000 (09:09 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 25 Feb 2016 14:09:18 +0000 (09:09 -0500)
PR c++/68049
* tree.c (strip_typedefs): Use DECL_ORIGINAL_TYPE.

From-SVN: r233715

gcc/cp/ChangeLog
gcc/cp/tree.c
gcc/testsuite/g++.dg/ext/attribute-may-alias-3.C [new file with mode: 0644]

index 3ae4daf861253c21db44297e81fcb93228d50e6c..eb5cfe6b5664ee41d6251450deeb611d6164537d 100644 (file)
@@ -1,3 +1,8 @@
+2016-02-25  Jason Merrill  <jason@redhat.com>
+
+       PR c++/68049
+       * tree.c (strip_typedefs): Use DECL_ORIGINAL_TYPE.
+
 2016-02-25  Patrick Palka  <ppalka@gcc.gnu.org>
 
        PR c++/69736
index 0f7287ab0d76eaa7aed2e9e232b26c997e27e901..ac38ce3fe11652b822745b126215d9e0e338c7d9 100644 (file)
@@ -1447,7 +1447,15 @@ strip_typedefs (tree t, bool *remove_attributes)
     }
 
   if (!result)
-      result = TYPE_MAIN_VARIANT (t);
+    {
+      if (typedef_variant_p (t))
+       /* Explicitly get the underlying type, as TYPE_MAIN_VARIANT doesn't
+          strip typedefs with attributes.  */
+       result = TYPE_MAIN_VARIANT (DECL_ORIGINAL_TYPE (TYPE_NAME (t)));
+      else
+       result = TYPE_MAIN_VARIANT (t);
+    }
+  gcc_assert (!typedef_variant_p (result));
   if (TYPE_USER_ALIGN (t) != TYPE_USER_ALIGN (result)
       || TYPE_ALIGN (t) != TYPE_ALIGN (result))
     {
diff --git a/gcc/testsuite/g++.dg/ext/attribute-may-alias-3.C b/gcc/testsuite/g++.dg/ext/attribute-may-alias-3.C
new file mode 100644 (file)
index 0000000..ba6091b
--- /dev/null
@@ -0,0 +1,22 @@
+// PR c++/68049
+// { dg-do compile { target c++11 } }
+
+template <typename T> struct Bar
+{
+    using type = T;
+};
+template <typename T> struct Foo
+{
+    typedef typename Bar<T>::type alias_type [[gnu::may_alias]];
+
+    alias_type operator()() { return {}; }
+};
+
+template <typename T> void print(T) {}
+
+int main()
+{
+    print(Foo<int>()());
+    print(0);
+    return 0;
+}