diff mbox

C++ PATCH for c++/67941 (UBsan error with empty lambda)

Message ID 56560489.8040904@redhat.com
State New
Headers show

Commit Message

Jason Merrill Nov. 25, 2015, 6:57 p.m. UTC
The _FUN function returned by the lambda conversion operator calls the 
op() with a null object argument, which would be undefined behavior for 
user code, but we can get away with it internally since it isn't 
observable.  Tell UBsan to ignore it.

Tested x86_64-pc-linux-gnu, applying to trunk and 5.

Comments

Jakub Jelinek Nov. 25, 2015, 7:21 p.m. UTC | #1
On Wed, Nov 25, 2015 at 01:57:13PM -0500, Jason Merrill wrote:
> The _FUN function returned by the lambda conversion operator calls the op()
> with a null object argument, which would be undefined behavior for user
> code, but we can get away with it internally since it isn't observable.
> Tell UBsan to ignore it.
> 
> Tested x86_64-pc-linux-gnu, applying to trunk and 5.

Thanks.  Though, perhaps we could guard those new two stmts with
  if (flag_sanitize & SANITIZE_UNDEFINED)
? No need to generate a useless attribute in the common case.

> commit 003d84b026a4785cbbb2b1cfc7fda9a31792d7a4
> Author: Jason Merrill <jason@redhat.com>
> Date:   Wed Nov 25 12:37:39 2015 -0500
> 
>     	PR c++/67941
>     	* lambda.c (maybe_add_lambda_conv_op): Mark _FUN as
>     	no_sanitize_undefined.
> 
> diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
> index 5fe3473..f9b686b 100644
> --- a/gcc/cp/lambda.c
> +++ b/gcc/cp/lambda.c
> @@ -1053,6 +1053,12 @@ maybe_add_lambda_conv_op (tree type)
>    if (generic_lambda_p)
>      fn = add_inherited_template_parms (fn, DECL_TI_TEMPLATE (callop));
>  
> +  /* Don't UBsan this function; we're deliberately calling op() with a null
> +     object argument.  */
> +  tree attrs = build_tree_list (get_identifier ("no_sanitize_undefined"),
> +				NULL_TREE);
> +  cplus_decl_attributes (&fn, attrs, 0);
> +
>    add_method (type, fn, NULL_TREE);
>  
>    if (nested)
> diff --git a/gcc/testsuite/g++.dg/ubsan/null-6.C b/gcc/testsuite/g++.dg/ubsan/null-6.C
> new file mode 100644
> index 0000000..2efe5c2
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/ubsan/null-6.C
> @@ -0,0 +1,5 @@
> +// PR c++/67941
> +// { dg-do run { target c++11 } }
> +// { dg-options -fsanitize=null }
> +
> +int main(){ (+[](){})(); }

	Jakub
diff mbox

Patch

commit 003d84b026a4785cbbb2b1cfc7fda9a31792d7a4
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Nov 25 12:37:39 2015 -0500

    	PR c++/67941
    	* lambda.c (maybe_add_lambda_conv_op): Mark _FUN as
    	no_sanitize_undefined.

diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index 5fe3473..f9b686b 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -1053,6 +1053,12 @@  maybe_add_lambda_conv_op (tree type)
   if (generic_lambda_p)
     fn = add_inherited_template_parms (fn, DECL_TI_TEMPLATE (callop));
 
+  /* Don't UBsan this function; we're deliberately calling op() with a null
+     object argument.  */
+  tree attrs = build_tree_list (get_identifier ("no_sanitize_undefined"),
+				NULL_TREE);
+  cplus_decl_attributes (&fn, attrs, 0);
+
   add_method (type, fn, NULL_TREE);
 
   if (nested)
diff --git a/gcc/testsuite/g++.dg/ubsan/null-6.C b/gcc/testsuite/g++.dg/ubsan/null-6.C
new file mode 100644
index 0000000..2efe5c2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ubsan/null-6.C
@@ -0,0 +1,5 @@ 
+// PR c++/67941
+// { dg-do run { target c++11 } }
+// { dg-options -fsanitize=null }
+
+int main(){ (+[](){})(); }