Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP2:GA
gcc7
gcc7-pr93246.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File gcc7-pr93246.patch of Package gcc7
commit 20e9d78543493f2f6aeef19af4cea54696247fc8 Author: Richard Biener <rguenther@suse.de> Date: Tue Jan 14 08:43:32 2020 +0100 PR middle-end/93246 - missing alias subsets Starting with the introduction of TYPE_TYPELESS_STORAGE the situation of having a alias-set zero aggregate field became more common which prevents recording alias-sets of fields of said aggregate as subset of the outer aggregate. component_uses_parent_alias_set_from in the past fended off some of the issues with that but the alias oracles use of the alias set of the base of an access path never appropriately handled it. The following makes it so that alias-sets of fields of alias-set zero aggregate fields are still recorded as subset of the container. 2020-01-14 Richard Biener <rguenther@suse.de> PR middle-end/93246 * alias.c (record_component_aliases): Take superset to record into, recurse for alias-set zero fields. (record_component_aliases): New oveerload wrapping around the above. * g++.dg/torture/pr93246.C: New testcase. diff --git a/gcc/alias.c b/gcc/alias.c index b64e3ea264d..053c3494e79 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -1186,15 +1186,14 @@ record_alias_subset (alias_set_type superset, alias_set_type subset) } } -/* 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) @@ -1244,7 +1243,21 @@ record_component_aliases (tree type) == 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; @@ -1260,6 +1273,19 @@ record_component_aliases (tree type) } } +/* 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. */ diff --git a/gcc/testsuite/g++.dg/torture/pr93246.C b/gcc/testsuite/g++.dg/torture/pr93246.C new file mode 100644 index 00000000000..4c523443175 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr93246.C @@ -0,0 +1,31 @@ +// { 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__((noinline,noclone)) foo(Optional<>& x) { __asm__ volatile ("":::"memory"); } + +int main() +{ + Optional<> buf{}; + foo(buf); + Wrapper<Optional<>> wo = {&buf}; + wo->set_present(); + auto x = wo->is_present(); + if (!x) + __builtin_abort (); +}
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor