Hi.

Following patch adds checking of noreturn attribute when we merge DECLs in LTO.
Note that proper fix is probably 
https://gcc.gnu.org/bugzilla/attachment.cgi?id=43884&action=diff
but that would be applicable after MPX is removed. Thus in next stage1.

Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

Ready to be installed?
Martin

gcc/lto/ChangeLog:

2018-04-06  Richard Biener  <rguent...@suse.de>
            Martin Liska  <mli...@suse.cz>

        PR lto/85248
        * lto-symtab.c (lto_symtab_merge_p): Handle noreturn attribute.

gcc/testsuite/ChangeLog:

2018-04-06  Jakub Jelinek  <ja...@redhat.com>

        PR lto/85248
        * gcc.dg/lto/pr85248_0.c: New test.
        * gcc.dg/lto/pr85248_1.c: New test.
---
 gcc/lto/lto-symtab.c                 | 17 ++++++++++++++
 gcc/testsuite/gcc.dg/lto/pr85248_0.c | 45 ++++++++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/lto/pr85248_1.c |  9 ++++++++
 3 files changed, 71 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/lto/pr85248_0.c
 create mode 100644 gcc/testsuite/gcc.dg/lto/pr85248_1.c


diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c
index 4f186aed059..fbad96c0707 100644
--- a/gcc/lto/lto-symtab.c
+++ b/gcc/lto/lto-symtab.c
@@ -572,6 +572,9 @@ lto_symtab_merge_p (tree prevailing, tree decl)
 	  return false;
 	}
     }
+
+  /* FIXME: after MPX is removed, use flags_from_decl_or_type
+     function instead.  PR lto/85248.  */
   if (DECL_ATTRIBUTES (prevailing) != DECL_ATTRIBUTES (decl))
     {
       tree prev_attr = lookup_attribute ("error", DECL_ATTRIBUTES (prevailing));
@@ -599,6 +602,20 @@ lto_symtab_merge_p (tree prevailing, tree decl)
 		     "warning attribute mismatch\n");
 	  return false;
 	}
+
+      prev_attr = lookup_attribute ("noreturn", DECL_ATTRIBUTES (prevailing));
+      attr = lookup_attribute ("noreturn", DECL_ATTRIBUTES (decl));
+      if ((prev_attr == NULL) != (attr == NULL)
+	  || (prev_attr
+	      && TREE_VALUE (TREE_VALUE (prev_attr))
+		 != TREE_VALUE (TREE_VALUE (attr))))
+	{
+          if (symtab->dump_file)
+	    fprintf (symtab->dump_file, "Not merging decls; "
+		     "noreturn attribute mismatch\n");
+	  return false;
+	}
+
     }
   return true;
 }
diff --git a/gcc/testsuite/gcc.dg/lto/pr85248_0.c b/gcc/testsuite/gcc.dg/lto/pr85248_0.c
new file mode 100644
index 00000000000..df61ac976a5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr85248_0.c
@@ -0,0 +1,45 @@
+/* PR lto/85248 */
+/* { dg-lto-do run } */
+/* { dg-lto-options { { -flto -O2 } } } */
+
+extern void test_alias (int s, int e) __asm__ (__USER_LABEL_PREFIX__ "test");
+extern void test_noreturn (int s, int e) __asm__ (__USER_LABEL_PREFIX__ "test")
+  __attribute__ ((__noreturn__));
+
+extern inline __attribute__ ((__always_inline__, __gnu_inline__)) void
+test (int s, int e)
+{
+  if (__builtin_constant_p (s) && s != 0)
+    test_noreturn (s, e);
+  else
+    test_alias (s, e);
+}
+
+int
+foo (void)
+{
+  static volatile int a;
+  return a;
+}
+
+static void
+bar (void)
+{
+  test (0, 1);
+  __builtin_exit (0);
+}
+
+static void
+baz ()
+{
+  test (1, 0);
+}
+
+int
+main ()
+{
+  if (foo ())
+    baz ();
+  bar ();
+  __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/lto/pr85248_1.c b/gcc/testsuite/gcc.dg/lto/pr85248_1.c
new file mode 100644
index 00000000000..418c0697028
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr85248_1.c
@@ -0,0 +1,9 @@
+/* { dg-options "-fno-lto" } */
+
+__attribute__((__noipa__)) void
+test (int s, int e)
+{
+  asm volatile ("" : "+g" (s), "+g" (e) : : "memory");
+  if (s)
+    __builtin_abort ();
+}

Reply via email to