https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107537
Bug ID: 107537 Summary: gcov skips throw/fallthrough annotations for 'never executed' branches Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: gcov-profile Assignee: unassigned at gcc dot gnu.org Reporter: grregd at gmail dot com CC: marxin at gcc dot gnu.org Target Milestone: --- $ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 11.3.0-1ubuntu1~22.04' --with-bugurl=file:///usr/share/doc/gcc-11/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-11 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-11-xKiWfi/gcc-11-11.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-11-xKiWfi/gcc-11-11.3.0/debian/tmp-gcn/usr --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2 Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 11.3.0 (Ubuntu 11.3.0-1ubuntu1~22.04) $ gcov -v gcov (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0 $ cat prog.cpp #include <iostream> void foo1() { try { std::cout << "here\n"; } catch (...) {} } void foo2() { try { std::cout << "there\n"; } catch (...) {} } int main() { foo1(); } $ g++ --coverage prog.cpp -o prog && ./prog && gcov -b -o . prog && cat prog.cpp.gcov here File 'prog.cpp' Lines executed:54.55% of 11 Branches executed:50.00% of 4 Taken at least once:25.00% of 4 Calls executed:40.00% of 5 Creating 'prog.cpp.gcov' File '/usr/include/c++/11/iostream' No executable lines No branches No calls Removing 'iostream.gcov' Lines executed:54.55% of 11 -: 0:Source:prog.cpp -: 0:Graph:./prog.gcno -: 0:Data:./prog.gcda -: 0:Runs:1 -: 1:#include <iostream> -: 2: function _Z4foo1v called 1 returned 100% blocks executed 60% 1: 3:void foo1() -: 4:{ -: 5: try { 1: 6: std::cout << "here\n"; call 0 returned 100% branch 1 taken 100% (fallthrough) branch 2 taken 0% (throw) -: 7: } =====: 8: catch (...) {} call 0 never executed 1: 9:} -: 10: function _Z4foo2v called 0 returned 0% blocks executed 0% #####: 11:void foo2() -: 12:{ -: 13: try { #####: 14: std::cout << "there\n"; call 0 never executed branch 1 never executed branch 2 never executed -: 15: } =====: 16: catch (...) {} call 0 never executed #####: 17:} -: 18: function main called 1 returned 100% blocks executed 100% 1: 19:int main() -: 20:{ 1: 21: foo1(); call 0 returned 100% 1: 22:} Both functions foo1 and foo2 are essentially the same. foo1 is called once, foo2 is never called. foo1 contains 2 branches in line 6, both branches labeled with annotations (fallthrough/throw). The same code in foo2 in line 14 also has 2 branches, however these are not labeled with annotations. Accoding to the source code of gcov it always skips throw/fallthrough annotations for 'never executed' branches (https://github.com/gcc-mirror/gcc/blob/50bc9185c2821350f0b785d6e23a6e9dcde58466/gcc/gcov.c#L2861) Is there any reason why gcov skips throw/fallthrough annotations for branches which were never executed? According to my investigation, those flags are there and after modifying gcov to print annotations always, it produces output with annotations for those never executed branches. But perhaps those flags are invalid in this case and can't be used? In some specific conditions, those annotations would be very helpful for tools like lcov or gcovr. Problem that occurrs in gcovr is described here - https://github.com/gcovr/gcovr/issues/677#issuecomment-1282355159