IPA ICF + ASAN: do not merge vars with different alignment
authorMartin Liska <mliska@suse.cz>
Tue, 23 Feb 2021 08:01:53 +0000 (09:01 +0100)
committerMartin Liska <mliska@suse.cz>
Tue, 23 Feb 2021 15:03:09 +0000 (16:03 +0100)
gcc/ChangeLog:

PR sanitizer/99168
* ipa-icf.c (sem_variable::merge): Do not merge 2 variables
with different alignment. That leads to an invalid red zone
size allocated in runtime.

gcc/testsuite/ChangeLog:

PR sanitizer/99168
* c-c++-common/asan/pr99168.c: New test.

gcc/ipa-icf.c
gcc/testsuite/c-c++-common/asan/pr99168.c [new file with mode: 0644]

index 687ad8d..5dd33a7 100644 (file)
@@ -88,6 +88,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-vector-builder.h"
 #include "symtab-thunks.h"
 #include "alias.h"
+#include "asan.h"
 
 using namespace ipa_icf_gimple;
 
@@ -2022,6 +2023,18 @@ sem_variable::merge (sem_item *alias_item)
       return false;
     }
 
+  if (DECL_ALIGN (original->decl) != DECL_ALIGN (alias->decl)
+      && (sanitize_flags_p (SANITIZE_ADDRESS, original->decl)
+         || sanitize_flags_p (SANITIZE_ADDRESS, alias->decl)))
+    {
+      if (dump_enabled_p ())
+       dump_printf (MSG_MISSED_OPTIMIZATION,
+                    "Not unifying; "
+                    "ASAN requires equal alignments for original and alias\n");
+
+      return false;
+    }
+
   if (DECL_ALIGN (original->decl) < DECL_ALIGN (alias->decl))
     {
       if (dump_enabled_p ())
diff --git a/gcc/testsuite/c-c++-common/asan/pr99168.c b/gcc/testsuite/c-c++-common/asan/pr99168.c
new file mode 100644 (file)
index 0000000..ed59ffb
--- /dev/null
@@ -0,0 +1,26 @@
+/* PR sanitizer/99168 */
+/* { dg-do run } */
+
+struct my_struct
+{
+  unsigned long volatile x;
+} __attribute__((aligned(128)));
+
+static int variablek[5][6] = {};
+static struct my_struct variables1 = {0UL};
+static struct my_struct variables2 __attribute__((aligned(32))) = {0UL};
+
+int main() {
+  int i, j;
+  for (i = 0; i < 5; i++) {
+    for (j = 0; j < 6; j++) {
+      __builtin_printf("%d ", variablek[i][j]);
+    }
+  }
+  __builtin_printf("\n");
+
+  __builtin_printf("%lu\n", variables1.x);
+  __builtin_printf("%lu\n", variables2.x);
+
+  return 0;
+}