https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79527
Bug ID: 79527 Summary: non-call-exceptions optimize attribute not propagated during inlining Product: gcc Version: 5.4.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: stefan at reservoir dot com Target Milestone: --- Created attachment 40744 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40744&action=edit Output of -fdump-tree-einline-eh without -fnon-call-exceptions command line flag The following program shows that the 'optimize (( "non-call-exceptions" ))' attribute of "inner" is not propagated when this function is inlined into "outer" and hence no exception region and landing pad is generated. When "inner" is declared "inline" but not "always_inline", it is not inlined and the resulting code is ok. It also works when "-fnon-call-exceptions" is specified on the command line. It seems safe to allow this since at the time of inlining the exception landing pads have been generated; and they are correctly copied when the global flag is set. Here is the preprocessed program: # 1 "inline.cpp" # 1 "<built-in>" # 1 "<command-line>" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 1 "<command-line>" 2 # 1 "inline.cpp" [[noreturn]] void my_exception_handler (void) noexcept; inline __attribute__ (( __always_inline__ )) void inner (int* x, int y) __attribute__ (( __optimize__ ( "non-call-exceptions" ) )); inline __attribute__ (( __always_inline__ )) void inner (int* x, int y) { try { *x = y; } catch (...) { my_exception_handler (); } } extern void outer (int* x, int y) { inner (x, y); } Compiled using: g++ -v -save-temps -Wall -Wextra -std=gnu++14 -fdump-tree-einline-eh -fnon-call-exceptions -O -S inline.ii Using built-in specs. COLLECT_GCC=g++ Target: i686-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.4.0-6ubuntu1~16.04.4' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-i386/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-i386 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-i386 --with-arch-directory=i386 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-targets=all --enable-multiarch --disable-werror --with-arch-32=i686 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu Thread model: posix gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4) COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Wall' '-Wextra' '-std=gnu++14' '-fdump-tree-einline-eh' '-fnon-call-exceptions' '-O' '-S' '-shared-libgcc' '-mtune=generic' '-march=i686' /usr/lib/gcc/i686-linux-gnu/5/cc1plus -fpreprocessed inline.ii -quiet -dumpbase inline.ii -mtune=generic -march=i686 -auxbase inline -O -Wall -Wextra -std=gnu++14 -version -fdump-tree-einline-eh -fnon-call-exceptions -o inline.s -fstack-protector-strong -Wformat-security GNU C++14 (Ubuntu 5.4.0-6ubuntu1~16.04.4) version 5.4.0 20160609 (i686-linux-gnu) compiled by GNU C version 5.4.0 20160609, GMP version 6.1.0, MPFR version 3.1.4, MPC version 1.0.3 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 GNU C++14 (Ubuntu 5.4.0-6ubuntu1~16.04.4) version 5.4.0 20160609 (i686-linux-gnu) compiled by GNU C version 5.4.0 20160609, GMP version 6.1.0, MPFR version 3.1.4, MPC version 1.0.3 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: 427d6507e583781294a191f5962a1495 COMPILER_PATH=/usr/lib/gcc/i686-linux-gnu/5/:/usr/lib/gcc/i686-linux-gnu/5/:/usr/lib/gcc/i686-linux-gnu/:/usr/lib/gcc/i686-linux-gnu/5/:/usr/lib/gcc/i686-linux-gnu/ LIBRARY_PATH=/usr/lib/gcc/i686-linux-gnu/5/:/usr/lib/gcc/i686-linux-gnu/5/../../../i386-linux-gnu/:/usr/lib/gcc/i686-linux-gnu/5/../../../../lib/:/lib/i386-linux-gnu/:/lib/../lib/:/usr/lib/i386-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/i686-linux-gnu/5/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Wall' '-Wextra' '-std=gnu++14' '-fdump-tree-einline-eh' '-fnon-call-exceptions' '-O' '-S' '-shared-libgcc' '-mtune=generic' '-march=i686' Here is a possible solution to this problem: diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 70d0102..3cb7f2e 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -4633,6 +4633,8 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id) /* Add local vars in this inlined callee to caller. */ add_local_variables (id->src_cfun, cfun, id); + cfun->can_throw_non_call_exceptions |= + id->src_cfun->can_throw_non_call_exceptions; if (dump_file && (dump_flags & TDF_DETAILS)) {