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" }
next prev parent 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).