diff mbox

Fix sanitizer/63788

Message ID 20141119190921.GF29446@redhat.com
State New
Headers show

Commit Message

Marek Polacek Nov. 19, 2014, 7:09 p.m. UTC
As discussed in the PR, the problem here is that when running gfortran,
the __builtin_object_size decl isn't available, because c-family's
c_define_builtins wasn't called.  One way how to fix this is to build
the __builtin_object_size decl in initialize_sanitizer_builtins, if
needed.  Alternatively we could just bail in instrument_object_size
if builtin_decl_explicit (BUILT_IN_OBJECT_SIZE) returns NULL_TREE...

No test attached since we don't have any Fortran ubsan infrastructure,
I've just tried
./xgcc -B ./ -B ../x86_64-unknown-linux-gnu/libsanitizer/ubsan/.libs/ -Wl,-rpath=../x86_64-unknown-linux-gnu/libsanitizer/ubsan/.libs/ -B ../x86_64-unknown-linux-gnu/libgfortran/.libs/ -O -fsanitize=undefined testcase.f -lgfortran; ./a.out
on the testcase attached in PR - and it doesn't ICE.

Bootstrapped/regtested on ppc64-linux, ok for trunk?

2014-11-19  Marek Polacek  <polacek@redhat.com>

	PR sanitizer/63788
	* asan.c (initialize_sanitizer_builtins): Add BT_FN_SIZE_CONST_PTR_INT
	var.  Conditionally build BUILT_IN_OBJECT_SIZE decl.
	(ATTR_PURE_NOTHROW_LEAF_LIST): Define.


	Marek

Comments

Marek Polacek Nov. 26, 2014, 1:57 p.m. UTC | #1
Ping.

On Wed, Nov 19, 2014 at 08:09:21PM +0100, Marek Polacek wrote:
> As discussed in the PR, the problem here is that when running gfortran,
> the __builtin_object_size decl isn't available, because c-family's
> c_define_builtins wasn't called.  One way how to fix this is to build
> the __builtin_object_size decl in initialize_sanitizer_builtins, if
> needed.  Alternatively we could just bail in instrument_object_size
> if builtin_decl_explicit (BUILT_IN_OBJECT_SIZE) returns NULL_TREE...
> 
> No test attached since we don't have any Fortran ubsan infrastructure,
> I've just tried
> ./xgcc -B ./ -B ../x86_64-unknown-linux-gnu/libsanitizer/ubsan/.libs/ -Wl,-rpath=../x86_64-unknown-linux-gnu/libsanitizer/ubsan/.libs/ -B ../x86_64-unknown-linux-gnu/libgfortran/.libs/ -O -fsanitize=undefined testcase.f -lgfortran; ./a.out
> on the testcase attached in PR - and it doesn't ICE.
> 
> Bootstrapped/regtested on ppc64-linux, ok for trunk?
> 
> 2014-11-19  Marek Polacek  <polacek@redhat.com>
> 
> 	PR sanitizer/63788
> 	* asan.c (initialize_sanitizer_builtins): Add BT_FN_SIZE_CONST_PTR_INT
> 	var.  Conditionally build BUILT_IN_OBJECT_SIZE decl.
> 	(ATTR_PURE_NOTHROW_LEAF_LIST): Define.
> 
> diff --git gcc/asan.c gcc/asan.c
> index ff08f1b..c2ed3d5 100644
> --- gcc/asan.c
> +++ gcc/asan.c
> @@ -2294,6 +2294,9 @@ initialize_sanitizer_builtins (void)
>  				pointer_sized_int_node, NULL_TREE);
>    tree BT_FN_VOID_INT
>      = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
> +  tree BT_FN_SIZE_CONST_PTR_INT
> +    = build_function_type_list (size_type_node, const_ptr_type_node,
> +				integer_type_node, NULL_TREE);
>    tree BT_FN_BOOL_VPTR_PTR_IX_INT_INT[5];
>    tree BT_FN_IX_CONST_VPTR_INT[5];
>    tree BT_FN_IX_VPTR_IX_INT[5];
> @@ -2365,6 +2368,8 @@ initialize_sanitizer_builtins (void)
>  #undef ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST
>  #define ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST \
>    /* ECF_COLD missing */ ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST
> +#undef ATTR_PURE_NOTHROW_LEAF_LIST
> +#define ATTR_PURE_NOTHROW_LEAF_LIST ECF_PURE | ATTR_NOTHROW_LEAF_LIST
>  #undef DEF_SANITIZER_BUILTIN
>  #define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
>    decl = add_builtin_function ("__builtin_" NAME, TYPE, ENUM,		\
> @@ -2374,6 +2379,15 @@ initialize_sanitizer_builtins (void)
>  
>  #include "sanitizer.def"
>  
> +  /* -fsanitize=object-size uses __builtin_object_size, but that might
> +     not be available for e.g. Fortran at this point.  We use
> +     DEF_SANITIZER_BUILTIN here only as a convenience macro.  */
> +  if ((flag_sanitize & SANITIZE_OBJECT_SIZE)
> +      && !builtin_decl_implicit_p (BUILT_IN_OBJECT_SIZE))
> +    DEF_SANITIZER_BUILTIN (BUILT_IN_OBJECT_SIZE, "object_size",
> +			   BT_FN_SIZE_CONST_PTR_INT,
> +			   ATTR_PURE_NOTHROW_LEAF_LIST)
> +
>  #undef DEF_SANITIZER_BUILTIN
>  }
>  
> 
> 	Marek

	Marek
Jakub Jelinek Nov. 26, 2014, 2 p.m. UTC | #2
On Wed, Nov 26, 2014 at 02:57:20PM +0100, Marek Polacek wrote:
> Ping.

Ok, thanks.
> 
> On Wed, Nov 19, 2014 at 08:09:21PM +0100, Marek Polacek wrote:
> > As discussed in the PR, the problem here is that when running gfortran,
> > the __builtin_object_size decl isn't available, because c-family's
> > c_define_builtins wasn't called.  One way how to fix this is to build
> > the __builtin_object_size decl in initialize_sanitizer_builtins, if
> > needed.  Alternatively we could just bail in instrument_object_size
> > if builtin_decl_explicit (BUILT_IN_OBJECT_SIZE) returns NULL_TREE...
> > 
> > No test attached since we don't have any Fortran ubsan infrastructure,
> > I've just tried
> > ./xgcc -B ./ -B ../x86_64-unknown-linux-gnu/libsanitizer/ubsan/.libs/ -Wl,-rpath=../x86_64-unknown-linux-gnu/libsanitizer/ubsan/.libs/ -B ../x86_64-unknown-linux-gnu/libgfortran/.libs/ -O -fsanitize=undefined testcase.f -lgfortran; ./a.out
> > on the testcase attached in PR - and it doesn't ICE.
> > 
> > Bootstrapped/regtested on ppc64-linux, ok for trunk?
> > 
> > 2014-11-19  Marek Polacek  <polacek@redhat.com>
> > 
> > 	PR sanitizer/63788
> > 	* asan.c (initialize_sanitizer_builtins): Add BT_FN_SIZE_CONST_PTR_INT
> > 	var.  Conditionally build BUILT_IN_OBJECT_SIZE decl.
> > 	(ATTR_PURE_NOTHROW_LEAF_LIST): Define.

	Jakub
diff mbox

Patch

diff --git gcc/asan.c gcc/asan.c
index ff08f1b..c2ed3d5 100644
--- gcc/asan.c
+++ gcc/asan.c
@@ -2294,6 +2294,9 @@  initialize_sanitizer_builtins (void)
 				pointer_sized_int_node, NULL_TREE);
   tree BT_FN_VOID_INT
     = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
+  tree BT_FN_SIZE_CONST_PTR_INT
+    = build_function_type_list (size_type_node, const_ptr_type_node,
+				integer_type_node, NULL_TREE);
   tree BT_FN_BOOL_VPTR_PTR_IX_INT_INT[5];
   tree BT_FN_IX_CONST_VPTR_INT[5];
   tree BT_FN_IX_VPTR_IX_INT[5];
@@ -2365,6 +2368,8 @@  initialize_sanitizer_builtins (void)
 #undef ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST
 #define ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST \
   /* ECF_COLD missing */ ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST
+#undef ATTR_PURE_NOTHROW_LEAF_LIST
+#define ATTR_PURE_NOTHROW_LEAF_LIST ECF_PURE | ATTR_NOTHROW_LEAF_LIST
 #undef DEF_SANITIZER_BUILTIN
 #define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
   decl = add_builtin_function ("__builtin_" NAME, TYPE, ENUM,		\
@@ -2374,6 +2379,15 @@  initialize_sanitizer_builtins (void)
 
 #include "sanitizer.def"
 
+  /* -fsanitize=object-size uses __builtin_object_size, but that might
+     not be available for e.g. Fortran at this point.  We use
+     DEF_SANITIZER_BUILTIN here only as a convenience macro.  */
+  if ((flag_sanitize & SANITIZE_OBJECT_SIZE)
+      && !builtin_decl_implicit_p (BUILT_IN_OBJECT_SIZE))
+    DEF_SANITIZER_BUILTIN (BUILT_IN_OBJECT_SIZE, "object_size",
+			   BT_FN_SIZE_CONST_PTR_INT,
+			   ATTR_PURE_NOTHROW_LEAF_LIST)
+
 #undef DEF_SANITIZER_BUILTIN
 }