Re: [PATCH] Implement -fsanitize=null + new sanopt pass
On Mon, Nov 18, 2013 at 6:44 AM, Marek Polacek pola...@redhat.com wrote: On Mon, Nov 18, 2013 at 02:51:41PM +0100, Jakub Jelinek wrote: On Wed, Nov 13, 2013 at 12:13:48AM +0100, Marek Polacek wrote: --- gcc/config/bootstrap-ubsan.mk.mp2013-11-12 13:46:13.345182065 +0100 +++ gcc/config/bootstrap-ubsan.mk 2013-11-12 13:46:49.812314016 +0100 @@ -2,6 +2,6 @@ STAGE2_CFLAGS += -fsanitize=undefined STAGE3_CFLAGS += -fsanitize=undefined -POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread \ +POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread -ldl \ Hopefully with my pending patch you can remove the -lpthread -ldl again, but ok for now. You shouldn't use -ldl directly. Not all OSes have libdl. You should extract the libdl check from gcc/configure.ac and set LIBDL instead by changing gcc/Makefile.in PLUGINLIBS = @pluginlibs@ to LIBDL = @libdl@ PLUGINLIBS = @pluginlibs@ $(LIBD) Then you can use POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread $(LIBDL) \ -- H.J.
Re: [PATCH] Implement -fsanitize=null + new sanopt pass
On Fri, Nov 29, 2013 at 11:22 AM, H.J. Lu hjl.to...@gmail.com wrote: On Mon, Nov 18, 2013 at 6:44 AM, Marek Polacek pola...@redhat.com wrote: On Mon, Nov 18, 2013 at 02:51:41PM +0100, Jakub Jelinek wrote: On Wed, Nov 13, 2013 at 12:13:48AM +0100, Marek Polacek wrote: --- gcc/config/bootstrap-ubsan.mk.mp2013-11-12 13:46:13.345182065 +0100 +++ gcc/config/bootstrap-ubsan.mk 2013-11-12 13:46:49.812314016 +0100 @@ -2,6 +2,6 @@ STAGE2_CFLAGS += -fsanitize=undefined STAGE3_CFLAGS += -fsanitize=undefined -POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread \ +POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread -ldl \ Hopefully with my pending patch you can remove the -lpthread -ldl again, but ok for now. You shouldn't use -ldl directly. Not all OSes have libdl. You should extract the libdl check from gcc/configure.ac and set LIBDL instead by changing gcc/Makefile.in PLUGINLIBS = @pluginlibs@ to LIBDL = @libdl@ PLUGINLIBS = @pluginlibs@ $(LIBD) Then you can use POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread $(LIBDL) \ Something like this. Only tested with normal build. -- H.J. --- diff --git a/config/bootstrap-ubsan.mk b/config/bootstrap-ubsan.mk index 0cd8b17..c298cd1 100644 --- a/config/bootstrap-ubsan.mk +++ b/config/bootstrap-ubsan.mk @@ -2,6 +2,7 @@ STAGE2_CFLAGS += -fsanitize=undefined STAGE3_CFLAGS += -fsanitize=undefined -POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread -ldl \ +POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread \ + $(LIBDL) \ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ubsan/ \ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ubsan/.libs diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 4d683a0..cb64241 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -340,12 +340,15 @@ CLOOGINC = @CLOOGINC@ # Set to 'yes' if the LTO front end is enabled. enable_lto = @enable_lto@ +# Library for dlopen +LIBDL=@libdl@ + # Compiler and flags needed for plugin support PLUGINCC = @CXX@ PLUGINCFLAGS = @CXXFLAGS@ # Libs and linker options needed for plugin support -PLUGINLIBS = @pluginlibs@ +PLUGINLIBS = @pluginlibs@ $(LIBDL) enable_plugin = @enable_plugin@ diff --git a/gcc/configure.ac b/gcc/configure.ac index 91a22d5..80cd248 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -5404,14 +5404,6 @@ if test x$enable_plugin = xyes; then AC_MSG_RESULT([unable to check]) fi - # Check -ldl - saved_LIBS=$LIBS - AC_SEARCH_LIBS([dlopen], [dl]) - if test x$ac_cv_search_dlopen = x-ldl; then -pluginlibs=$pluginlibs -ldl - fi - LIBS=$saved_LIBS - # Check that we can build shared objects with -fPIC -shared saved_LDFLAGS=$LDFLAGS saved_CFLAGS=$CFLAGS @@ -5454,6 +5446,16 @@ if test x$enable_plugin = xyes; then AC_DEFINE(ENABLE_PLUGIN, 1, [Define to enable plugin support.]) fi +# Check -ldl +libdl= +saved_LIBS=$LIBS +AC_SEARCH_LIBS([dlopen], [dl]) +if test x$ac_cv_search_dlopen = x-ldl; then + libdl=-ldl +fi +LIBS=$saved_LIBS +AC_SUBST(libdl) + # Enable --enable-host-shared AC_ARG_ENABLE(host-shared,
Re: [PATCH] Implement -fsanitize=null + new sanopt pass
On Fri, Nov 29, 2013 at 11:22:00AM -0800, H.J. Lu wrote: On Mon, Nov 18, 2013 at 6:44 AM, Marek Polacek pola...@redhat.com wrote: On Mon, Nov 18, 2013 at 02:51:41PM +0100, Jakub Jelinek wrote: On Wed, Nov 13, 2013 at 12:13:48AM +0100, Marek Polacek wrote: --- gcc/config/bootstrap-ubsan.mk.mp2013-11-12 13:46:13.345182065 +0100 +++ gcc/config/bootstrap-ubsan.mk 2013-11-12 13:46:49.812314016 +0100 @@ -2,6 +2,6 @@ STAGE2_CFLAGS += -fsanitize=undefined STAGE3_CFLAGS += -fsanitize=undefined -POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread \ +POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread -ldl \ Hopefully with my pending patch you can remove the -lpthread -ldl again, but ok for now. You shouldn't use -ldl directly. Not all OSes have libdl. You should extract the libdl check from gcc/configure.ac and set LIBDL instead by changing gcc/Makefile.in -static-libubsan should add all the libraries needed of libubsan.a by now, so -lpthread -ldl should be just removed from POSTSTAGE1_LDFLAGS. Jakub
Re: [PATCH] Implement -fsanitize=null + new sanopt pass
On Fri, Nov 29, 2013 at 08:32:34PM +0100, Jakub Jelinek wrote: On Fri, Nov 29, 2013 at 11:22:00AM -0800, H.J. Lu wrote: On Mon, Nov 18, 2013 at 6:44 AM, Marek Polacek pola...@redhat.com wrote: On Mon, Nov 18, 2013 at 02:51:41PM +0100, Jakub Jelinek wrote: On Wed, Nov 13, 2013 at 12:13:48AM +0100, Marek Polacek wrote: --- gcc/config/bootstrap-ubsan.mk.mp2013-11-12 13:46:13.345182065 +0100 +++ gcc/config/bootstrap-ubsan.mk 2013-11-12 13:46:49.812314016 +0100 @@ -2,6 +2,6 @@ STAGE2_CFLAGS += -fsanitize=undefined STAGE3_CFLAGS += -fsanitize=undefined -POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread \ +POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread -ldl \ Hopefully with my pending patch you can remove the -lpthread -ldl again, but ok for now. You shouldn't use -ldl directly. Not all OSes have libdl. You should extract the libdl check from gcc/configure.ac and set LIBDL instead by changing gcc/Makefile.in -static-libubsan should add all the libraries needed of libubsan.a by now, so -lpthread -ldl should be just removed from POSTSTAGE1_LDFLAGS. So ok to install this one? 2013-11-29 Marek Polacek pola...@redhat.com * bootstrap-ubsan.mk (POSTSTAGE1_LDFLAGS): Remove -lpthread -ldl. --- gcc/bootstrap-ubsan.mk.mp3 2013-11-29 20:50:04.788238860 +0100 +++ gcc/bootstrap-ubsan.mk 2013-11-29 20:50:25.870322185 +0100 @@ -2,6 +2,6 @@ STAGE2_CFLAGS += -fsanitize=undefined STAGE3_CFLAGS += -fsanitize=undefined -POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread -ldl \ +POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan \ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ubsan/ \ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ubsan/.libs Marek
Re: [PATCH] Implement -fsanitize=null + new sanopt pass
On Fri, Nov 29, 2013 at 08:55:26PM +0100, Marek Polacek wrote: 2013-11-29 Marek Polacek pola...@redhat.com * bootstrap-ubsan.mk (POSTSTAGE1_LDFLAGS): Remove -lpthread -ldl. --- gcc/bootstrap-ubsan.mk.mp32013-11-29 20:50:04.788238860 +0100 +++ gcc/bootstrap-ubsan.mk2013-11-29 20:50:25.870322185 +0100 @@ -2,6 +2,6 @@ STAGE2_CFLAGS += -fsanitize=undefined STAGE3_CFLAGS += -fsanitize=undefined -POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread -ldl \ +POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan \ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ubsan/ \ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ubsan/.libs Please add -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ too, so that it is able to find libsanitizer.spec. Ok with that change. Jakub
Re: [PATCH] Implement -fsanitize=null + new sanopt pass
On Fri, Nov 29, 2013 at 08:57:23PM +0100, Jakub Jelinek wrote: On Fri, Nov 29, 2013 at 08:55:26PM +0100, Marek Polacek wrote: 2013-11-29 Marek Polacek pola...@redhat.com * bootstrap-ubsan.mk (POSTSTAGE1_LDFLAGS): Remove -lpthread -ldl. --- gcc/bootstrap-ubsan.mk.mp3 2013-11-29 20:50:04.788238860 +0100 +++ gcc/bootstrap-ubsan.mk 2013-11-29 20:50:25.870322185 +0100 @@ -2,6 +2,6 @@ STAGE2_CFLAGS += -fsanitize=undefined STAGE3_CFLAGS += -fsanitize=undefined -POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread -ldl \ +POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan \ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ubsan/ \ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ubsan/.libs Please add -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ too, so that it is able to find libsanitizer.spec. Ok with that change. Thanks, will apply the following then. 2013-11-29 Marek Polacek pola...@redhat.com * bootstrap-ubsan.mk (POSTSTAGE1_LDFLAGS): Remove -lpthread -ldl. Add -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/. --- gcc/bootstrap-ubsan.mk.mp3 2013-11-29 20:50:04.788238860 +0100 +++ gcc/bootstrap-ubsan.mk 2013-11-29 20:58:23.322131822 +0100 @@ -2,6 +2,7 @@ STAGE2_CFLAGS += -fsanitize=undefined STAGE3_CFLAGS += -fsanitize=undefined -POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread -ldl \ +POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan \ + -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ \ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ubsan/ \ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ubsan/.libs Marek
Re: [PATCH] Implement -fsanitize=null + new sanopt pass
On Fri, Nov 29, 2013 at 12:02 PM, Marek Polacek pola...@redhat.com wrote: On Fri, Nov 29, 2013 at 08:57:23PM +0100, Jakub Jelinek wrote: On Fri, Nov 29, 2013 at 08:55:26PM +0100, Marek Polacek wrote: 2013-11-29 Marek Polacek pola...@redhat.com * bootstrap-ubsan.mk (POSTSTAGE1_LDFLAGS): Remove -lpthread -ldl. --- gcc/bootstrap-ubsan.mk.mp3 2013-11-29 20:50:04.788238860 +0100 +++ gcc/bootstrap-ubsan.mk 2013-11-29 20:50:25.870322185 +0100 @@ -2,6 +2,6 @@ STAGE2_CFLAGS += -fsanitize=undefined STAGE3_CFLAGS += -fsanitize=undefined -POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread -ldl \ +POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan \ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ubsan/ \ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ubsan/.libs Please add -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ too, so that it is able to find libsanitizer.spec. Ok with that change. Thanks, will apply the following then. 2013-11-29 Marek Polacek pola...@redhat.com * bootstrap-ubsan.mk (POSTSTAGE1_LDFLAGS): Remove -lpthread -ldl. Add -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/. --- gcc/bootstrap-ubsan.mk.mp3 2013-11-29 20:50:04.788238860 +0100 +++ gcc/bootstrap-ubsan.mk 2013-11-29 20:58:23.322131822 +0100 @@ -2,6 +2,7 @@ STAGE2_CFLAGS += -fsanitize=undefined STAGE3_CFLAGS += -fsanitize=undefined -POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread -ldl \ +POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan \ + -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ \ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ubsan/ \ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ubsan/.libs Marek I pushed it to binutils-gdb. -- H.J.
Re: [PATCH] Implement -fsanitize=null + new sanopt pass
On Wed, Nov 13, 2013 at 12:13:48AM +0100, Marek Polacek wrote: --- gcc/config/bootstrap-ubsan.mk.mp 2013-11-12 13:46:13.345182065 +0100 +++ gcc/config/bootstrap-ubsan.mk 2013-11-12 13:46:49.812314016 +0100 @@ -2,6 +2,6 @@ STAGE2_CFLAGS += -fsanitize=undefined STAGE3_CFLAGS += -fsanitize=undefined -POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread \ +POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread -ldl \ Hopefully with my pending patch you can remove the -lpthread -ldl again, but ok for now. + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (gsi)) + { + gimple stmt = gsi_stmt (gsi); + + if (gimple_code (stmt) != GIMPLE_CALL) if (is_gimple_call (stmt)) Ok with those changes. Jakub
Re: [PATCH] Implement -fsanitize=null + new sanopt pass
On Mon, Nov 18, 2013 at 02:51:41PM +0100, Jakub Jelinek wrote: On Wed, Nov 13, 2013 at 12:13:48AM +0100, Marek Polacek wrote: --- gcc/config/bootstrap-ubsan.mk.mp2013-11-12 13:46:13.345182065 +0100 +++ gcc/config/bootstrap-ubsan.mk 2013-11-12 13:46:49.812314016 +0100 @@ -2,6 +2,6 @@ STAGE2_CFLAGS += -fsanitize=undefined STAGE3_CFLAGS += -fsanitize=undefined -POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread \ +POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread -ldl \ Hopefully with my pending patch you can remove the -lpthread -ldl again, but ok for now. + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (gsi)) + { + gimple stmt = gsi_stmt (gsi); + + if (gimple_code (stmt) != GIMPLE_CALL) if (is_gimple_call (stmt)) Ok with those changes. Oh, one more thing, please update gcc/doc/, the -fsanitize= description is far from up to date there. Jakub
Re: [PATCH] Implement -fsanitize=null + new sanopt pass
On Mon, Nov 18, 2013 at 02:51:41PM +0100, Jakub Jelinek wrote: On Wed, Nov 13, 2013 at 12:13:48AM +0100, Marek Polacek wrote: --- gcc/config/bootstrap-ubsan.mk.mp2013-11-12 13:46:13.345182065 +0100 +++ gcc/config/bootstrap-ubsan.mk 2013-11-12 13:46:49.812314016 +0100 @@ -2,6 +2,6 @@ STAGE2_CFLAGS += -fsanitize=undefined STAGE3_CFLAGS += -fsanitize=undefined -POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread \ +POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread -ldl \ Hopefully with my pending patch you can remove the -lpthread -ldl again, but ok for now. Cool. + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (gsi)) + { + gimple stmt = gsi_stmt (gsi); + + if (gimple_code (stmt) != GIMPLE_CALL) if (is_gimple_call (stmt)) Fixed. Ok with those changes. Thanks. Also I'll have to add some headers after the gimple.h reorg, but that is an obvious change. Marek
Re: [PATCH] Implement -fsanitize=null + new sanopt pass
On Mon, Nov 18, 2013 at 02:52:34PM +0100, Jakub Jelinek wrote: Oh, one more thing, please update gcc/doc/, the -fsanitize= description is far from up to date there. Ok, the following (incremental) hopefully improves the docs. Joseph, would you mind having a look at this? Thanks, 2013-11-18 Marek Polacek pola...@redhat.com * doc/invoke.texi: Extend -fsanitize=undefined documentation. --- gcc/doc/invoke.texi.mp3 2013-11-18 15:57:47.104103101 +0100 +++ gcc/doc/invoke.texi 2013-11-18 17:08:51.305594441 +0100 @@ -5260,9 +5260,45 @@ data race bugs. See @uref{http://code.google.com/p/data-race-test/wiki/ThreadSanitizer} for more details. @item -fsanitize=undefined -Enable UndefinedBehaviorSanitizer, a fast undefined behavior detector +Enable UndefinedBehaviorSanitizer, a fast undefined behavior detector. Various computations will be instrumented to detect undefined behavior -at runtime, e.g.@: division by zero or various overflows. +at runtime. Current suboptions are: + +@itemize @bullet + +@item @option{-fsanitize=shift} + +This option enables checking that the result of a shift operation is +not undefined. Note that what exactly is considered undefined differs +slightly between C and C++, as well as between ANSI C and C99, etc. + +@item @option{-fsanitize=integer-divide-by-zero} + +Detect integer division by zero as well as @code{INT_MIN / -1} division. +Note that the latter is only made undefined from C99 onwards. + +@item @option{-fsanitize=unreachable} + +With this option, the compiler will turn the @code{__builtin_unreachable} +call into a diagnostics message call instead. When reaching the +@code{__builtin_unreachable} call, the behavior is undefined. + +@item @option{-fsanitize=vla-bound} + +This option instructs the compiler to check that the size of a variable +length array is positive. This option does not have any effect in +@option{-std=c++1y} mode, as the standard requires the exception be thrown +instead. + +@item @option{-fsanitize=null} + +This option enables pointer checking. Particularly, the application +built with this option turned on will issue an error message when it +tries to dereference a NULL pointer, or if a reference (possibly an +rvalue reference) is bound to a NULL pointer. + +@end itemize + While @option{-ftrapv} causes traps for signed overflows to be emitted, @option{-fsanitize=undefined} gives a diagnostic message. This currently works only for the C family of languages. Marek
Re: [PATCH] Implement -fsanitize=null + new sanopt pass
On Mon, 18 Nov 2013, Marek Polacek wrote: +@item @option{-fsanitize=shift} + +This option enables checking that the result of a shift operation is +not undefined. Note that what exactly is considered undefined differs +slightly between C and C++, as well as between ANSI C and C99, etc. We generally refer to ISO C90, not ANSI C. +Detect integer division by zero as well as @code{INT_MIN / -1} division. +Note that the latter is only made undefined from C99 onwards. INT_MIN / -1 is unambiguously undefined in C90 - it's a signed arithmetic overflow (result not within the range of its type). It's INT_MIN % -1 where there's more ambiguity, but I consider the wording changes in C11 as a defect correction that should be applied back to C90. (A comment on what the semantics should be, not on whether the documentation accurately reflects the code.) -- Joseph S. Myers jos...@codesourcery.com
Re: [PATCH] Implement -fsanitize=null + new sanopt pass
On Mon, Nov 18, 2013 at 04:58:36PM +, Joseph S. Myers wrote: On Mon, 18 Nov 2013, Marek Polacek wrote: +@item @option{-fsanitize=shift} + +This option enables checking that the result of a shift operation is +not undefined. Note that what exactly is considered undefined differs +slightly between C and C++, as well as between ANSI C and C99, etc. We generally refer to ISO C90, not ANSI C. Fixed. +Detect integer division by zero as well as @code{INT_MIN / -1} division. +Note that the latter is only made undefined from C99 onwards. INT_MIN / -1 is unambiguously undefined in C90 - it's a signed arithmetic overflow (result not within the range of its type). It's INT_MIN % -1 where there's more ambiguity, but I consider the wording changes in C11 as a defect correction that should be applied back to C90. (A comment on what the semantics should be, not on whether the documentation accurately reflects the code.) I removed that sentence to not confuse readers. (We issue runtime error for INT_MIN % -1 for all c90, c99, c11 modes.) Thanks. Ok now? 2013-11-18 Marek Polacek pola...@redhat.com * doc/invoke.texi: Extend -fsanitize=undefined documentation. --- gcc/doc/invoke.texi.mp3 2013-11-18 15:57:47.104103101 +0100 +++ gcc/doc/invoke.texi 2013-11-18 18:55:00.178009402 +0100 @@ -5260,9 +5260,44 @@ data race bugs. See @uref{http://code.google.com/p/data-race-test/wiki/ThreadSanitizer} for more details. @item -fsanitize=undefined -Enable UndefinedBehaviorSanitizer, a fast undefined behavior detector +Enable UndefinedBehaviorSanitizer, a fast undefined behavior detector. Various computations will be instrumented to detect undefined behavior -at runtime, e.g.@: division by zero or various overflows. +at runtime. Current suboptions are: + +@itemize @bullet + +@item @option{-fsanitize=shift} + +This option enables checking that the result of a shift operation is +not undefined. Note that what exactly is considered undefined differs +slightly between C and C++, as well as between ISO C90 and C99, etc. + +@item @option{-fsanitize=integer-divide-by-zero} + +Detect integer division by zero as well as @code{INT_MIN / -1} division. + +@item @option{-fsanitize=unreachable} + +With this option, the compiler will turn the @code{__builtin_unreachable} +call into a diagnostics message call instead. When reaching the +@code{__builtin_unreachable} call, the behavior is undefined. + +@item @option{-fsanitize=vla-bound} + +This option instructs the compiler to check that the size of a variable +length array is positive. This option does not have any effect in +@option{-std=c++1y} mode, as the standard requires the exception be thrown +instead. + +@item @option{-fsanitize=null} + +This option enables pointer checking. Particularly, the application +built with this option turned on will issue an error message when it +tries to dereference a NULL pointer, or if a reference (possibly an +rvalue reference) is bound to a NULL pointer. + +@end itemize + While @option{-ftrapv} causes traps for signed overflows to be emitted, @option{-fsanitize=undefined} gives a diagnostic message. This currently works only for the C family of languages. Marek
Re: [PATCH] Implement -fsanitize=null + new sanopt pass
On Mon, 18 Nov 2013, Marek Polacek wrote: 2013-11-18 Marek Polacek pola...@redhat.com * doc/invoke.texi: Extend -fsanitize=undefined documentation. OK. -- Joseph S. Myers jos...@codesourcery.com
Re: [PATCH] Implement -fsanitize=null + new sanopt pass
On Wed, Nov 13, 2013 at 06:45:06AM +0100, Markus Trippelsdorf wrote: On 2013.11.13 at 00:13 +0100, Marek Polacek wrote: 2) bootstrap-ubsan almost passes, but the bootstrap fails when building all-fixincludes. The problem here is that libiberty.a is built with -fsanitize=undefined, but fixincludes, when linking, don't link libubsan in. My attemps to tweak FIXINC_CFLAGS/LDFLAGS/BOOT_LDFLAGS and whatnot weren't successfull. I'm using the following patch locally as a part to enable slim-lto-bootstrap. Maybe it helps in your case, too? Unfortunately, doesn't seem to help :(. Thanks anyway. Marek
[PATCH] Implement -fsanitize=null + new sanopt pass
Hi! Lately I've been working on the ubsan NULL pointer checking. Its purpose is to detect load from/store to NULL pointer. So, e.g., int *p = NULL; struct S *s = NULL; if (*p) { ... } x = struct s-i; etc. I should explain a bit here about the implementation of it. Firstly, I wanted to implement it in the FEs, but that proved impossible, or at least too hard: there is no sure-fire how to distinguish between loads and stores from/to pointers, while on GIMPLE, walk_gimple_op will compute is_lhs for us. So I've resorted to make use of that. There are two new passes: ubsan and sanopt. The ubsan pass is run very early, and its purpose is merely to insert the UBSAN_NULL internal function calls before load/stores, that is: p_1 = 0B; UBSAN_NULL (p_1, 0); _3 = *p_1; The first argument of the UBSAN_NULL is the pointer itself; the second argument is just a value that says whether it is actually a store, a load, a member access, etc. Now, the second new pass, sanopt, is run very late. This pass is implemented in asan.c and is not designed only for ubsan, we will use it for asan/tsan/whatever_might_crop_up_in_the_future as well. The idea behind the sanopt pass is simple: walk the statements and expand the UBSAN_NULL calls. What we expand this call to is roughly the following: if (p_1 == 0B) goto bb 4; else goto bb 3; bb 4: __builtin___ubsan_handle_type_mismatch (*.Lubsan_data0, 0); bb 3: _2 = *p_1; (With optimizations on this will look slightly different, as CCP does its job, etc.) The fact that we're always splitting the BBs, thus this might be rather expensive on large TUs, is plain to see. But I think the basic idea is sound. The fact that in sanopt pass we're creating a new internal structure proved to be particularly arduous, since on -O0, cgraph stuff refused to actually emit this structure. The problem was that varpool_assemble_decl wasn't properly called when flag_toplevel_reorder wasn't in effect. Hence the cgraphunit.c hunk. Honza, does it look sane to you? There are a few issues that are vying for our/my attention: 1) I'm getting an ICE with -flto in lto_output_edge, it doesn't like the fact that internal call is a leaf function. So, I disabled ubsan tests with lto, since I don't readily see how to solve this. 2) bootstrap-ubsan almost passes, but the bootstrap fails when building all-fixincludes. The problem here is that libiberty.a is built with -fsanitize=undefined, but fixincludes, when linking, don't link libubsan in. My attemps to tweak FIXINC_CFLAGS/LDFLAGS/BOOT_LDFLAGS and whatnot weren't successfull. 3) Member call instrumentation (*) doesn't work with SRA turned on. 4) int r = 0; sanitization is not implemented yet. But this will have to be done in the C++ FE. (*) By this I mean: struct S { int f (void) { return 0; } }; struct S *s = NULL; s-f(); Currently this will not fail, only the 'this' pointer will be bogus. So, how does this look like? Regtested/bootstrapped on x86_64-linux. 2013-11-12 Marek Polacek pola...@redhat.com config/ * bootstrap-ubsan.mk (POSTSTAGE1_LDFLAGS): Add -ldl. gcc/c-family/ * c-ubsan.c (ubsan_instrument_division): Adjust ubsan_create_data call. (ubsan_instrument_shift): Likewise. (ubsan_instrument_vla): Likewise. gcc/ * opts.c (common_handle_option): Add -fsanitize=null option. Turn off -fdelete-null-pointer-checks option when doing the NULL pointer checking. * sanitizer.def (BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH): Add. * tree-pass.h (make_pass_ubsan): Declare. (make_pass_sanopt): Declare. * timevar.def (TV_TREE_UBSAN): New timevar. * passes.def: Add pass_sanopt and pass_ubsan. * ubsan.h (ubsan_null_ckind): New enum. (ubsan_mismatch_data): New struct. (ubsan_expand_null_ifn): Declare. (ubsan_create_data): Adjust declaration. (ubsan_type_descriptor): Likewise. * asan.c: Include ubsan.h. (pass_data_sanopt): New pass. (execute_sanopt): New function. (gate_sanopt): Likewise. (make_pass_sanopt): Likewise. (class pass_sanopt): New class. * ubsan.c: Include tree-pass.h, gimple-ssa.h and cfgloop.h. (PROB_VERY_UNLIKELY): Define. (tree_type_map_hash): New function. (ubsan_type_descriptor): Add new parameter. Improve type name generation. (ubsan_create_data): Add new parameter. Add pointer data into ubsan structure. (ubsan_expand_null_ifn): New function. (instrument_member_call): Likewise. (instrument_mem_ref): Likewise. (instrument_null): Likewise. (ubsan_pass): Likewise. (gate_ubsan): Likewise. (make_pass_ubsan): Likewise. (ubsan_instrument_unreachable): Adjust ubsan_create_data call. (class pass_ubsan): New class. (pass_data_ubsan): New pass. *
Re: [PATCH] Implement -fsanitize=null + new sanopt pass
On 2013.11.13 at 00:13 +0100, Marek Polacek wrote: 2) bootstrap-ubsan almost passes, but the bootstrap fails when building all-fixincludes. The problem here is that libiberty.a is built with -fsanitize=undefined, but fixincludes, when linking, don't link libubsan in. My attemps to tweak FIXINC_CFLAGS/LDFLAGS/BOOT_LDFLAGS and whatnot weren't successfull. I'm using the following patch locally as a part to enable slim-lto-bootstrap. Maybe it helps in your case, too? diff --git a/Makefile.in b/Makefile.in index f9e8e0d5cb79..5db913fa0b8d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -2930,6 +2930,7 @@ configure-build-fixincludes: test ! -f $(BUILD_SUBDIR)/fixincludes/Makefile || exit 0; \ $(SHELL) $(srcdir)/mkinstalldirs $(BUILD_SUBDIR)/fixincludes ; \ $(BUILD_EXPORTS) \ + CFLAGS=$(STAGE_CFLAGS); export CFLAGS; \ echo Configuring in $(BUILD_SUBDIR)/fixincludes; \ cd $(BUILD_SUBDIR)/fixincludes || exit 1; \ case $(srcdir) in \ @@ -2965,6 +2966,7 @@ all-build-fixincludes: configure-build-fixincludes $(BUILD_EXPORTS) \ (cd $(BUILD_SUBDIR)/fixincludes \ $(MAKE) $(BASE_FLAGS_TO_PASS) $(EXTRA_BUILD_FLAGS) \ + CFLAGS=$(STAGE_CFLAGS) \ $(TARGET-build-fixincludes)) @endif build-fixincludes @@ -7813,6 +7815,7 @@ configure-fixincludes: test ! -f $(HOST_SUBDIR)/fixincludes/Makefile || exit 0; \ $(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/fixincludes ; \ $(HOST_EXPORTS) \ + CFLAGS=$(STAGE_CFLAGS); export CFLAGS; \ echo Configuring in $(HOST_SUBDIR)/fixincludes; \ cd $(HOST_SUBDIR)/fixincludes || exit 1; \ case $(srcdir) in \ @@ -7847,6 +7850,7 @@ all-fixincludes: configure-fixincludes $(HOST_EXPORTS) \ (cd $(HOST_SUBDIR)/fixincludes \ $(MAKE) $(BASE_FLAGS_TO_PASS) $(EXTRA_HOST_FLAGS) $(STAGE1_FLAGS_TO_PASS) \ + CFLAGS=$(STAGE_CFLAGS) \ $(TARGET-fixincludes)) @endif fixincludes -- Markus