[Bug tree-optimization/79527] New: non-call-exceptions optimize attribute not propagated during inlining

stefan at reservoir dot com gcc-bugzilla@gcc.gnu.org
Wed Feb 15 10:29:00 GMT 2017


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))
     {


More information about the Gcc-bugs mailing list