Hi, This patch sets local.can_change_signature to false for instrumentation thunk callees. We have two reasons for that: - We don't support modification of instrumentation thunks - We don't actually emit instrumentation thunk and therefore its signature should be in sync with callee
This patch should prevent incorrect IPA optimizations on instrumneted functions. Bootstrapped and tested on x86_64-unknown-linux-gnu. I'm going to apply it to trunk and gcc-6-btanch. @Honza, do you think this a valid fix to prevent invalid code modifications? Thanks, Ilya -- gcc/ 2016-06-27 Ilya Enkovich <ilya.enkov...@intel.com> * ipa-inline-analysis.c (compute_inline_parameters): Set local.can_change_signature to false for intrumentation thunk callees. gcc/testsuite/ 2016-06-27 Ilya Enkovich <ilya.enkov...@intel.com> * g++.dg/pr71624.C: New test. diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index 5d67218..da29d22 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -3017,6 +3017,16 @@ compute_inline_parameters (struct cgraph_node *node, bool early) node->local.can_change_signature = !e; } } + /* Functions called by instrumentation thunk can't change signature + because instrumentation thunk modification is not supported. */ + if (node->local.can_change_signature) + for (e = node->callers; e; e = e->next_caller) + if (e->caller->thunk.thunk_p + && e->caller->thunk.add_pointer_bounds_args) + { + node->local.can_change_signature = false; + break; + } estimate_function_body_sizes (node, early); pop_cfun (); } diff --git a/gcc/testsuite/g++.dg/pr71624.C b/gcc/testsuite/g++.dg/pr71624.C new file mode 100644 index 0000000..94a75cd --- /dev/null +++ b/gcc/testsuite/g++.dg/pr71624.C @@ -0,0 +1,35 @@ +/* PR71624 */ +// { dg-do compile { target i?86-*-* x86_64-*-* } } +/* { dg-options "-fcheck-pointer-bounds -mmpx -O2" } */ + +class c1 +{ +public: + virtual int fn1 () const; + int fn2 (const int *) const; +}; + +class c2 +{ + int fn1 (); + c1 obj; +}; + +int +c1::fn1 () const +{ + return 0; +} + +int +c1::fn2 (const int *) const +{ + return this->fn1 (); +} + +int +c2::fn1 () +{ + return obj.fn2 (0); +} +