Hi,

Some time ago removal of not instrumented version of funtion with 
'always_inline' was delayed to enable their inlining.  With this change we may 
have situations when we inline into a not instrumented version of a function 
which also has an instrumented version (happens when both of them have 
'always_inline').  It causes ICE in cgraph_node verifier because we clear all 
references before inlining and verifier expects IPA_REF_CHKP reference for all 
functions having instrumented version.  This patch fixes it by rebuilding 
IPA_REF_CHKP reference.

Bootstrapped and tested on x86_64-unknown-linux-gnu.  OK for trunk?

Thanks,
Ilya
--
2015-01-27  Ilya Enkovich  <ilya.enkov...@intel.com>

        PR middle-end/64805
        * ipa-inline.c (early_inliner): Rebuild IPA_REF_CHKP reference
        to avoid error in cgraph node verification.

2015-01-27  Ilya Enkovich  <ilya.enkov...@intel.com>

        PR middle-end/64805
        * gcc.target/i386/pr64805.c: New.


diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index c0ff329..d341619 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -2464,6 +2464,13 @@ early_inliner (function *fun)
 #endif
   node->remove_all_references ();
 
+  /* Rebuild this reference because it dosn't depend on
+     function's body and it's required to pass cgraph_node
+     verification.  */
+  if (node->instrumented_version
+      && !node->instrumentation_clone)
+    node->create_reference (node->instrumented_version, IPA_REF_CHKP, NULL);
+
   /* Even when not optimizing or not inlining inline always-inline
      functions.  */
   inlined = inline_always_inline_functions (node);
diff --git a/gcc/testsuite/gcc.target/i386/pr64805.c 
b/gcc/testsuite/gcc.target/i386/pr64805.c
new file mode 100644
index 0000000..8ba0a97
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr64805.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target mpx } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+#include <stdio.h>
+
+static inline void __attribute ((always_inline)) functionA(void)
+{
+  return;
+}
+
+static inline void __attribute ((always_inline)) functionB(void)
+{
+  functionA();
+}
+
+int test(void)
+{
+  functionB();
+
+  return 0;
+}

Reply via email to