}
}
-/* Record that component types of TYPE, if any, are part of that type for
+/* Record that component types of TYPE, if any, are part of SUPERSET for
aliasing purposes. For record types, we only record component types
for fields that are not marked non-addressable. For array types, we
only record the component type if it is not marked non-aliased. */
void
-record_component_aliases (tree type)
+record_component_aliases (tree type, alias_set_type superset)
{
- alias_set_type superset = get_alias_set (type);
tree field;
if (superset == 0)
== get_alias_set (TREE_TYPE (field)));
}
- record_alias_subset (superset, get_alias_set (t));
+ alias_set_type set = get_alias_set (t);
+ record_alias_subset (superset, set);
+ /* If the field has alias-set zero make sure to still record
+ any componets of it. This makes sure that for
+ struct A {
+ struct B {
+ int i;
+ char c[4];
+ } b;
+ };
+ in C++ even though 'B' has alias-set zero because
+ TYPE_TYPELESS_STORAGE is set, 'A' has the alias-set of
+ 'int' as subset. */
+ if (set == 0)
+ record_component_aliases (t, superset);
}
}
break;
}
}
+/* Record that component types of TYPE, if any, are part of that type for
+ aliasing purposes. For record types, we only record component types
+ for fields that are not marked non-addressable. For array types, we
+ only record the component type if it is not marked non-aliased. */
+
+void
+record_component_aliases (tree type)
+{
+ alias_set_type superset = get_alias_set (type);
+ record_component_aliases (type, superset);
+}
+
+
/* Allocate an alias set for use in storing and reading from the varargs
spill area. */
--- /dev/null
+// { dg-do run }
+// { dg-additional-options "-fstrict-aliasing" }
+
+template <typename = void> struct Optional {
+ auto is_present() const { const bool &p = inner.present; return p; }
+ auto set_present() { if (not is_present()) inner.present = true; }
+ struct InnerType {
+ bool present = false;
+ char padding[1] = {0};
+ };
+ using inner_t = InnerType;
+ inner_t inner = {};
+};
+
+template <typename WrappedType> struct Wrapper {
+ auto operator-> () { return value; }
+ WrappedType *value;
+};
+
+void __attribute__((noipa)) foo(Optional<>& x) {}
+
+int main()
+{
+ Optional<> buf{};
+ foo(buf);
+ Wrapper<Optional<>> wo = {&buf};
+ wo->set_present();
+ auto x = wo->is_present();
+ if (!x)
+ __builtin_abort ();
+}