]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR middle-end/93246 - missing alias subsets
authorRichard Biener <rguenther@suse.de>
Tue, 14 Jan 2020 07:43:32 +0000 (08:43 +0100)
committerRichard Biener <rguenther@suse.de>
Mon, 20 Jan 2020 11:57:04 +0000 (12:57 +0100)
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.

gcc/ChangeLog
gcc/alias.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr93246.C [new file with mode: 0644]

index 47c1876dc9c203e08c5d53bebc0210c5d969eeac..d31312299a89c724c6d33570065a9af05c1e66cc 100644 (file)
@@ -1,3 +1,11 @@
+2020-01-20  Richard Biener  <rguenther@suse.de>
+
+       Backport from mainline
+       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.
+
 2020-01-19  Eric S. Raymond <esr@thyrsus.com>
            Sandra Loosemore  <sandra@codesourcery.com>
 
index b64e3ea264d6d9a917ba3558ce252f34ff61d3b6..053c3494e7969cede2d610a803f97225a7a78396 100644 (file)
@@ -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.  */
 
index 6203349acb6f6fc7b8ed8a2eb3b5dd5dd52d379a..47dd30618ec4d0161523f97ac323ea4ca56dbf1a 100644 (file)
@@ -1,3 +1,9 @@
+2020-01-20  Richard Biener  <rguenther@suse.de>
+
+       Backport from mainline
+       PR middle-end/93246
+       * g++.dg/torture/pr93246.C: New testcase.
+
 2020-01-17  Mark Eggleston  <mark.eggleston@codethink.com>
 
        Backport from mainline
diff --git a/gcc/testsuite/g++.dg/torture/pr93246.C b/gcc/testsuite/g++.dg/torture/pr93246.C
new file mode 100644 (file)
index 0000000..4c52344
--- /dev/null
@@ -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__((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 ();
+}