public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jason Merrill <jason@redhat.com>
To: Nathaniel Shead <nathanieloshead@gmail.com>, gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] c++: Check null pointer deref when calling memfn in constexpr [PR102420]
Date: Mon, 18 Dec 2023 13:32:58 -0500	[thread overview]
Message-ID: <4201c638-a4a8-42cc-9b91-321545c1b972@redhat.com> (raw)
In-Reply-To: <657f6d54.170a0220.7e557.2d05@mx.google.com>

On 12/17/23 16:51, Nathaniel Shead wrote:
> Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?
> 
> An alternative approach for the lambda issue would be to modify
> 'maybe_add_lambda_conv_op' to not pass a null pointer, but I wasn't sure
> what the best approach for that would be.

I don't see a way to do that.  Better IMO would have been for the C++ 
committee to make the op() static in this case when we introduced static 
lambdas, but that didn't happen, so we're left with this kludge.

> -- >8 --
> 
> Calling a non-static member function on a null pointer is undefined
> behaviour (see [expr.ref] p8) and should error in constant evaluation,
> even if the 'this' pointer is never actually accessed within that
> function.
> 
> One catch is that currently, the function pointer conversion operator
> for lambda passes a null pointer as the 'this' pointer to the underlying
> 'operator()', so for now we ignore such calls.
> 
> 	PR c++/102420
> 
> gcc/cp/ChangeLog:
> 
> 	* constexpr.cc (cxx_bind_parameters_in_call): Check for calling
> 	non-static member functions with a null pointer.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/cpp0x/constexpr-memfn2.C: New test.
> 
> Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
> ---
>   gcc/cp/constexpr.cc                           | 17 +++++++++++++++++
>   gcc/testsuite/g++.dg/cpp0x/constexpr-memfn2.C | 10 ++++++++++
>   2 files changed, 27 insertions(+)
>   create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-memfn2.C
> 
> diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
> index 051f73fb73f..9c18538b302 100644
> --- a/gcc/cp/constexpr.cc
> +++ b/gcc/cp/constexpr.cc
> @@ -1884,6 +1884,23 @@ cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, tree fun,
>   	 TARGET_EXPR, and use its CONSTRUCTOR as the value of the parm.  */
>         arg = cxx_eval_constant_expression (ctx, x, vc_prvalue,
>   					  non_constant_p, overflow_p);
> +      /* Check we aren't dereferencing a null pointer when calling a non-static
> +	 member function, which is undefined behaviour.  */
> +      if (i == 0 && DECL_NONSTATIC_MEMBER_FUNCTION_P (fun)
> +	  && integer_zerop (arg)
> +	  /* But ignore calls from within the lambda function pointer
> +	     conversion thunk, since this currently passes a null pointer.  */
> +	  && !(TREE_CODE (t) == CALL_EXPR
> +	       && CALL_FROM_THUNK_P (t)

We might just stop here, since any CALL_FROM_THUNK_P is compiler 
internals, and we should have already complained (if appropriate) about 
calling the thunk.  OK either way.

> +	       && ctx->call
> +	       && ctx->call->fundef
> +	       && lambda_static_thunk_p (ctx->call->fundef->decl)))
> +	{
> +	  if (!ctx->quiet)
> +	    error_at (cp_expr_loc_or_input_loc (x),
> +		      "dereferencing a null pointer");
> +	  *non_constant_p = true;
> +	}
>         /* Don't VERIFY_CONSTANT here.  */
>         if (*non_constant_p && ctx->quiet)
>   	break;
> diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-memfn2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-memfn2.C
> new file mode 100644
> index 00000000000..4749190a1f0
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-memfn2.C
> @@ -0,0 +1,10 @@
> +// PR c++/102420
> +// { dg-do compile { target c++11 } }
> +
> +struct X {
> +  constexpr int f() { return 0; }
> +};
> +constexpr int g(X* x) {
> +    return x->f();  // { dg-error "dereferencing a null pointer" }
> +}
> +constexpr int t = g(nullptr);  // { dg-message "in .constexpr. expansion" }


  reply	other threads:[~2023-12-18 18:33 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-17 21:51 Nathaniel Shead
2023-12-18 18:32 ` Jason Merrill [this message]
2023-12-19 11:03   ` Nathaniel Shead

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4201c638-a4a8-42cc-9b91-321545c1b972@redhat.com \
    --to=jason@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=nathanieloshead@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).