fish-shell is seeing a SIGSEGV under std::call_once with -fipa-pta, which I have reduced to the following: 1. Store a noop void->void function pointer into a local variable 2. Point a global variable at the local 3. Use pthread_once to invoke a trampoline, which in turn dereferences the global to call the noop This crashes with `-O1 -fipa-pta`, and the crash disappears if `fipa-pta` is deleted. Original test case (requires musl): https://gist.github.com/ridiculousfish/0a24a98e7634b78e77a0351501576ee8 Reduced test case (also available at https://gist.github.com/ridiculousfish/3cff64438154a20765e527be11f7cc76): ``` extern "C" void pthread_once(int *, void()); namespace std { extern __thread void (*__once_call)(); extern "C" void __once_proxy(); }; // namespace std static void noop() {} using voidfunc = void (*)(); static voidfunc *vp; static void call_vp() { (*vp)(); } int main() { using namespace std; voidfunc vf = noop; vp = &vf; __once_call = call_vp; int once{0}; pthread_once(&once, __once_proxy); return 0; } ``` To reproduce, on Linux: g++ -O1 -fipa-pta -std=c++11 -lpthread output.cpp ./a.out and it should SIGSEGV under `call_vp` gcc -v: Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/9.3.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: /build/gcc/src/gcc/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-pkgversion='Arch Linux 9.3.0-1' --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++,d --enable-shared --enable-threads=posix --with-system-zlib --with-isl --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --enable-gnu-indirect-function --enable-multilib --disable-werror --enable-checking=release --enable-default-pie --enable-default-ssp --enable-cet=auto gdc_include_dir=/usr/include/dlang/gdc Thread model: posix gcc version 9.3.0 (Arch Linux 9.3.0-1) (Originally reported as https://github.com/fish-shell/fish-shell/issues/6962)
Confirmed, started with r6-5684-g47e5754e17e9ac3b.
Confirmed. It's a little tricky but I think it boils down to extern void abort (); extern void baz (); extern void (*baz_call)(); static int *p; static void foo () { if (*p != 1) abort (); } int main() { int x = 1; p = &x; baz_call = foo; baz (); return 0; } --- void (*baz_call)(); void baz () { baz_call (); } and the issue being that escaping foo at baz_call = foo does not escape foos call uses/clobbers.
In fact this situation doesn't seem to be handled at all - global variables are still an afterthought in IPA-PTA it seems. Needs more work than a simple fix.
(In reply to Richard Biener from comment #3) > In fact this situation doesn't seem to be handled at all - global variables > are still an afterthought in IPA-PTA it seems. Needs more work than a > simple fix. Hum, actually it's a simple bug and the following fixes it. diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 416a26c996c..16a2b53c2b7 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -8187,8 +8187,8 @@ ipa_pta_execute (void) /* For the purpose of IPA PTA unit-local globals are not escape points. */ - bool nonlocal_p = (var->used_from_other_partition - || var->externally_visible + bool nonlocal_p = (var->externally_visible_p () + || var->used_from_other_partition || var->force_output); var->call_for_symbol_and_aliases (refered_from_nonlocal_var, &nonlocal_p, true);
The master branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:f9b5db750bc7fbba69fee93564907f7da1bca35f commit r11-70-gf9b5db750bc7fbba69fee93564907f7da1bca35f Author: Richard Biener <rguenther@suse.de> Date: Tue May 5 13:09:50 2020 +0200 ipa/94947 - fix test for externally visible variables for IPA PTA This fixes lack of an escape point of externally declared variables. 2020-05-05 Richard Biener <rguenther@suse.de> PR ipa/94947 * tree-ssa-structalias.c (ipa_pta_execute): Use varpool_node::externally_visible_p (). (refered_from_nonlocal_var): Likewise. * gcc.dg/torture/pr94947-1.c: New testcase. * gcc.dg/torture/pr94947-2.c: Likewise.
Fixed on trunk sofar.
The master branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:b9250b3cb91b667cd67943e0fac94bf39ac089a8 commit r11-170-gb9250b3cb91b667cd67943e0fac94bf39ac089a8 Author: Richard Biener <rguenther@suse.de> Date: Thu May 7 14:06:02 2020 +0200 ipa/94947 - avoid using externally_visible_p () externally_visible_p wasn't the correct predicate to use (even if it worked), instead we should use DECL_EXTERNAL || TREE_PUBLIC. 2020-05-07 Richard Biener <rguenther@suse.de> PR ipa/94947 * tree-ssa-structalias.c (refered_from_nonlocal_fn): Use DECL_EXTERNAL || TREE_PUBLIC instead of externally_visible. (refered_from_nonlocal_var): Likewise. (ipa_pta_execute): Likewise.
The releases/gcc-10 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:67d00c438285ecf9b8e96c12d1f6b05fd2ea3c21 commit r10-8141-g67d00c438285ecf9b8e96c12d1f6b05fd2ea3c21 Author: Richard Biener <rguenther@suse.de> Date: Tue May 5 13:09:50 2020 +0200 ipa/94947 - fix test for externally visible variables for IPA PTA This fixes lack of an escape point of externally declared variables. 2020-05-05 Richard Biener <rguenther@suse.de> PR ipa/94947 * tree-ssa-structalias.c (ipa_pta_execute): Use varpool_node::externally_visible_p (). (refered_from_nonlocal_var): Likewise. * gcc.dg/torture/pr94947-1.c: New testcase. * gcc.dg/torture/pr94947-2.c: Likewise.
The releases/gcc-10 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:a68d4b47a6b5b23a5d7ab3b358f559f41568512f commit r10-8142-ga68d4b47a6b5b23a5d7ab3b358f559f41568512f Author: Richard Biener <rguenther@suse.de> Date: Thu May 7 14:06:02 2020 +0200 ipa/94947 - avoid using externally_visible_p () externally_visible_p wasn't the correct predicate to use (even if it worked), instead we should use DECL_EXTERNAL || TREE_PUBLIC. 2020-05-07 Richard Biener <rguenther@suse.de> PR ipa/94947 * tree-ssa-structalias.c (refered_from_nonlocal_fn): Use DECL_EXTERNAL || TREE_PUBLIC instead of externally_visible. (refered_from_nonlocal_var): Likewise. (ipa_pta_execute): Likewise.
The releases/gcc-9 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:0bcf016768f32799d4dabc82a29440b2ab1d717b commit r9-8865-g0bcf016768f32799d4dabc82a29440b2ab1d717b Author: Richard Biener <rguenther@suse.de> Date: Tue May 5 13:09:50 2020 +0200 ipa/94947 - fix test for externally visible variables for IPA PTA This fixes lack of an escape point of externally declared variables. 2020-05-05 Richard Biener <rguenther@suse.de> PR ipa/94947 * tree-ssa-structalias.c (ipa_pta_execute): Use varpool_node::externally_visible_p (). (refered_from_nonlocal_var): Likewise. * gcc.dg/torture/pr94947-1.c: New testcase. * gcc.dg/torture/pr94947-2.c: Likewise. (cherry picked from commit f9b5db750bc7fbba69fee93564907f7da1bca35f)
The releases/gcc-9 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:7cfb86a2a18c9d54d1fd43f17affcd184477ecb3 commit r9-8866-g7cfb86a2a18c9d54d1fd43f17affcd184477ecb3 Author: Richard Biener <rguenther@suse.de> Date: Thu May 7 14:06:02 2020 +0200 ipa/94947 - avoid using externally_visible_p () externally_visible_p wasn't the correct predicate to use (even if it worked), instead we should use DECL_EXTERNAL || TREE_PUBLIC. 2020-05-07 Richard Biener <rguenther@suse.de> PR ipa/94947 * tree-ssa-structalias.c (refered_from_nonlocal_fn): Use DECL_EXTERNAL || TREE_PUBLIC instead of externally_visible. (refered_from_nonlocal_var): Likewise. (ipa_pta_execute): Likewise. (cherry picked from commit b9250b3cb91b667cd67943e0fac94bf39ac089a8)
The releases/gcc-8 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:1cd95acac5a521937b205ace0db3f1a042561dd8 commit r8-10661-g1cd95acac5a521937b205ace0db3f1a042561dd8 Author: Richard Biener <rguenther@suse.de> Date: Tue May 5 13:09:50 2020 +0200 ipa/94947 - fix test for externally visible variables for IPA PTA This fixes lack of an escape point of externally declared variables. 2020-05-05 Richard Biener <rguenther@suse.de> PR ipa/94947 * tree-ssa-structalias.c (ipa_pta_execute): Use varpool_node::externally_visible_p (). (refered_from_nonlocal_var): Likewise. * gcc.dg/torture/pr94947-1.c: New testcase. * gcc.dg/torture/pr94947-2.c: Likewise. (cherry picked from commit f9b5db750bc7fbba69fee93564907f7da1bca35f)
The releases/gcc-8 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:3114be1ceb750f323a13dad0a419a7622bd71fbe commit r8-10662-g3114be1ceb750f323a13dad0a419a7622bd71fbe Author: Richard Biener <rguenther@suse.de> Date: Thu May 7 14:06:02 2020 +0200 ipa/94947 - avoid using externally_visible_p () externally_visible_p wasn't the correct predicate to use (even if it worked), instead we should use DECL_EXTERNAL || TREE_PUBLIC. 2020-05-07 Richard Biener <rguenther@suse.de> PR ipa/94947 * tree-ssa-structalias.c (refered_from_nonlocal_fn): Use DECL_EXTERNAL || TREE_PUBLIC instead of externally_visible. (refered_from_nonlocal_var): Likewise. (ipa_pta_execute): Likewise. (cherry picked from commit b9250b3cb91b667cd67943e0fac94bf39ac089a8)
Fixed.