In general, TYPE_CANONICAL of a type strips all attributes. An
exception to this seems to be that TYPE_REF_CAN_ALIAS_ALL remains set on
the TYPE_CANONICAL of a pointer/reference type even though its TREE_TYPE
no longer has the may_alias attribute, and is inconsistent with
"affects_type_identity" being false for may_alias. This seems to have
been a mistake in the patch that first introduced TYPE_CANONICAL, rather
than a deliberate choice.
I'm also planning to fix 50800 in the front end, but this patch still
seems like an improvement.
Tested x86-64-pc-linux-gnu, OK for trunk?
commit 724a66ba837560ba233b00cddf5d5d93ec5888f4
Author: Jason Merrill <ja...@redhat.com>
Date: Thu Apr 16 13:57:11 2015 -0400
PR c++/50800
gcc/
* tree.c (build_reference_type_for_mode): Don't pass can_alias_all
down when building TYPE_CANONICAL.
(build_pointer_type_for_mode): Likewise.
gcc/cp/
* typeck.c (structural_comptypes): Don't check TYPE_REF_CAN_ALIAS_ALL.
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index e9d4cae..7646225 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1310,7 +1310,6 @@ structural_comptypes (tree t1, tree t2, int strict)
case POINTER_TYPE:
if (TYPE_MODE (t1) != TYPE_MODE (t2)
- || TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2)
|| !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
return false;
break;
diff --git a/gcc/testsuite/g++.dg/ext/alias-canon2.C b/gcc/testsuite/g++.dg/ext/alias-canon2.C
index 4833db8..3806cb4 100644
--- a/gcc/testsuite/g++.dg/ext/alias-canon2.C
+++ b/gcc/testsuite/g++.dg/ext/alias-canon2.C
@@ -31,6 +31,3 @@ out_long (ui64 longVal)
}
}
}
-
-void f(ui32 *) { }
-void f(ui32a *) { }
diff --git a/gcc/testsuite/g++.dg/ext/attrib50.C b/gcc/testsuite/g++.dg/ext/attrib50.C
new file mode 100644
index 0000000..a46c9f7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/attrib50.C
@@ -0,0 +1,11 @@
+// PR c++/50800
+
+template <typename T> struct B;
+template <typename T> struct B<T &> {
+ typedef T type;
+};
+struct A {
+ typedef int TA __attribute__((__may_alias__));
+};
+void d() { B<int &> b; }
+int main() { B<A::TA &> b; }
diff --git a/gcc/tree.c b/gcc/tree.c
index 151e3e2..43c4a36 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -7704,7 +7704,7 @@ build_pointer_type_for_mode (tree to_type, machine_mode mode,
else if (TYPE_CANONICAL (to_type) != to_type)
TYPE_CANONICAL (t)
= build_pointer_type_for_mode (TYPE_CANONICAL (to_type),
- mode, can_alias_all);
+ mode, false);
/* Lay out the type. This function has many callers that are concerned
with expression-construction, and this simplifies them all. */
@@ -7771,7 +7771,7 @@ build_reference_type_for_mode (tree to_type, machine_mode mode,
else if (TYPE_CANONICAL (to_type) != to_type)
TYPE_CANONICAL (t)
= build_reference_type_for_mode (TYPE_CANONICAL (to_type),
- mode, can_alias_all);
+ mode, false);
layout_type (t);