https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90053
Bug ID: 90053 Summary: [GCOV] A statement in while loop is wrongly marked as not executed when they are within the if(setjmp()) statement Product: gcc Version: 8.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: gcov-profile Assignee: unassigned at gcc dot gnu.org Reporter: yangyibiao at nju dot edu.cn 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/8/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 8.2.0-1ubuntu2~18.04' --with-bugurl=file:///usr/share/doc/gcc-8/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-8 --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 --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 --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 8.2.0 (Ubuntu 8.2.0-1ubuntu2~18.04) $ cat small.c #include <setjmp.h> #include <signal.h> #include <stdlib.h> static jmp_buf segv_jmpbuf; static void segv_handler(int seg) { __builtin_longjmp(segv_jmpbuf, 1); } static int is_addressable(void *p, size_t size) { volatile char * volatile cp = (volatile char *)p; volatile int ret; struct sigaction sa, origsa; sigset_t mask; sa.sa_handler = segv_handler; sa.sa_flags = 0; sigfillset(&sa.sa_mask); sigaction(SIGSEGV, &sa, &origsa); sigprocmask(SIG_SETMASK, NULL, &mask); if (__builtin_setjmp(segv_jmpbuf) == 0) { printf("size: %d\n", size); while(size--) { *cp++; } ret = 1; } else { ret = 0; } sigaction(SIGSEGV, &origsa, NULL); sigprocmask(SIG_SETMASK, &mask, NULL); return ret; } int main(int argc, char **argv) { is_addressable(0x0, 1); return 0; } $ gcc -w -O0 --coverage small.c; ./a.out; gcov-8 small.c; cat small.c.gcov size: 1 File 'small.c' Lines executed:95.00% of 20 Creating 'small.c.gcov' -: 0:Source:small.c -: 0:Graph:small.gcno -: 0:Data:small.gcda -: 0:Runs:1 -: 0:Programs:1 -: 1:#include <setjmp.h> -: 2:#include <signal.h> -: 3:#include <stdlib.h> -: 4: -: 5:static jmp_buf segv_jmpbuf; 1: 6:static void segv_handler(int seg) { __builtin_longjmp(segv_jmpbuf, 1); } -: 7: 1: 8:static int is_addressable(void *p, size_t size) -: 9:{ 1: 10: volatile char * volatile cp = (volatile char *)p; -: 11: volatile int ret; -: 12: struct sigaction sa, origsa; -: 13: sigset_t mask; -: 14: 1: 15: sa.sa_handler = segv_handler; 1: 16: sa.sa_flags = 0; 1: 17: sigfillset(&sa.sa_mask); 1: 18: sigaction(SIGSEGV, &sa, &origsa); 1: 19: sigprocmask(SIG_SETMASK, NULL, &mask); -: 20: 2: 21: if (__builtin_setjmp(segv_jmpbuf) == 0) { 1: 22: printf("size: %d\n", size); 1: 23: while(size--) #####: 24: { *cp++; } 1: 25: ret = 1; -: 26: } else { 1: 27: ret = 0; -: 28: } -: 29: 2: 30: sigaction(SIGSEGV, &origsa, NULL); 1: 31: sigprocmask(SIG_SETMASK, &mask, NULL); -: 32: 1: 33: return ret; -: 34:} -: 35: 1: 36:int main(int argc, char **argv) -: 37:{ 1: 38: is_addressable(0x0, 1); 1: 39: return 0; -: 40:} Line #24 is wrongly marked as not executed. The value of variable #size# is 1 before executing the while statement. Thus, Line #24 should be executed.