File gcc7-pr93246.patch of Package cross-avr-gcc7
129
1
commit 20e9d78543493f2f6aeef19af4cea54696247fc8
2
Author: Richard Biener <rguenther@suse.de>
3
Date: Tue Jan 14 08:43:32 2020 +0100
4
5
PR middle-end/93246 - missing alias subsets
6
7
Starting with the introduction of TYPE_TYPELESS_STORAGE the situation
8
of having a alias-set zero aggregate field became more common which
9
prevents recording alias-sets of fields of said aggregate as subset
10
of the outer aggregate. component_uses_parent_alias_set_from in the
11
past fended off some of the issues with that but the alias oracles
12
use of the alias set of the base of an access path never appropriately
13
handled it.
14
15
The following makes it so that alias-sets of fields of alias-set zero
16
aggregate fields are still recorded as subset of the container.
17
18
2020-01-14 Richard Biener <rguenther@suse.de>
19
20
PR middle-end/93246
21
* alias.c (record_component_aliases): Take superset to record
22
into, recurse for alias-set zero fields.
23
(record_component_aliases): New oveerload wrapping around the above.
24
25
* g++.dg/torture/pr93246.C: New testcase.
26
27
diff --git a/gcc/alias.c b/gcc/alias.c
28
index b64e3ea264d..053c3494e79 100644
29
--- a/gcc/alias.c
30
+++ b/gcc/alias.c
31
32
}
33
}
34
35
-/* Record that component types of TYPE, if any, are part of that type for
36
+/* Record that component types of TYPE, if any, are part of SUPERSET for
37
aliasing purposes. For record types, we only record component types
38
for fields that are not marked non-addressable. For array types, we
39
only record the component type if it is not marked non-aliased. */
40
41
void
42
-record_component_aliases (tree type)
43
+record_component_aliases (tree type, alias_set_type superset)
44
{
45
- alias_set_type superset = get_alias_set (type);
46
tree field;
47
48
if (superset == 0)
49
50
== get_alias_set (TREE_TYPE (field)));
51
}
52
53
- record_alias_subset (superset, get_alias_set (t));
54
+ alias_set_type set = get_alias_set (t);
55
+ record_alias_subset (superset, set);
56
+ /* If the field has alias-set zero make sure to still record
57
+ any componets of it. This makes sure that for
58
+ struct A {
59
+ struct B {
60
+ int i;
61
+ char c[4];
62
+ } b;
63
+ };
64
+ in C++ even though 'B' has alias-set zero because
65
+ TYPE_TYPELESS_STORAGE is set, 'A' has the alias-set of
66
+ 'int' as subset. */
67
+ if (set == 0)
68
+ record_component_aliases (t, superset);
69
}
70
break;
71
72
73
}
74
}
75
76
+/* Record that component types of TYPE, if any, are part of that type for
77
+ aliasing purposes. For record types, we only record component types
78
+ for fields that are not marked non-addressable. For array types, we
79
+ only record the component type if it is not marked non-aliased. */
80
+
81
+void
82
+record_component_aliases (tree type)
83
+{
84
+ alias_set_type superset = get_alias_set (type);
85
+ record_component_aliases (type, superset);
86
+}
87
+
88
+
89
/* Allocate an alias set for use in storing and reading from the varargs
90
spill area. */
91
92
diff --git a/gcc/testsuite/g++.dg/torture/pr93246.C b/gcc/testsuite/g++.dg/torture/pr93246.C
93
new file mode 100644
94
index 00000000000..4c523443175
95
--- /dev/null
96
+++ b/gcc/testsuite/g++.dg/torture/pr93246.C
97
98
+// { dg-do run }
99
+// { dg-additional-options "-fstrict-aliasing" }
100
+
101
+template <typename = void> struct Optional {
102
+ auto is_present() const { const bool &p = inner.present; return p; }
103
+ auto set_present() { if (not is_present()) inner.present = true; }
104
+ struct InnerType {
105
+ bool present = false;
106
+ char padding[1] = {0};
107
+ };
108
+ using inner_t = InnerType;
109
+ inner_t inner = {};
110
+};
111
+
112
+template <typename WrappedType> struct Wrapper {
113
+ auto operator-> () { return value; }
114
+ WrappedType *value;
115
+};
116
+
117
+void __attribute__((noinline,noclone)) foo(Optional<>& x) { __asm__ volatile ("":::"memory"); }
118
+
119
+int main()
120
+{
121
+ Optional<> buf{};
122
+ foo(buf);
123
+ Wrapper<Optional<>> wo = {&buf};
124
+ wo->set_present();
125
+ auto x = wo->is_present();
126
+ if (!x)
127
+ __builtin_abort ();
128
+}
129