public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Nathaniel Shead <nathanieloshead@gmail.com>
To: gcc-patches@gcc.gnu.org
Cc: Jason Merrill <jason@redhat.com>
Subject: [PATCH] c++: Check null pointer deref when calling memfn in constexpr [PR102420]
Date: Mon, 18 Dec 2023 08:51:11 +1100	[thread overview]
Message-ID: <657f6d54.170a0220.7e557.2d05@mx.google.com> (raw)

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.

-- >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)
+	       && 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" }
-- 
2.42.0


             reply	other threads:[~2023-12-17 21:51 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-17 21:51 Nathaniel Shead [this message]
2023-12-18 18:32 ` Jason Merrill
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=657f6d54.170a0220.7e557.2d05@mx.google.com \
    --to=nathanieloshead@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jason@redhat.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).