public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jason Merrill <jason@redhat.com>
To: Jakub Jelinek <jakub@redhat.com>
Cc: gcc-patches@gcc.gnu.org, Jonathan Wakely <jwakely@redhat.com>
Subject: Re: [PATCH] c++, v4: Implement C++26 P2741R3 - user-generated static_assert messages [PR110348]
Date: Tue, 28 Nov 2023 11:31:48 -0500	[thread overview]
Message-ID: <aafda314-903b-4c12-a421-785eb5df4098@redhat.com> (raw)
In-Reply-To: <ZV8OGMkGJFMG5urh@tucnak>

On 11/23/23 03:32, Jakub Jelinek wrote:
> On Wed, Nov 22, 2023 at 04:53:48PM -0500, Jason Merrill wrote:
>> I agree it's weird to get two of the same error, but maybe instead of
>> duplicating the error, we could look up data only if size succeeded, and
>> then error once if either failed?
> 
> Here is what I've committed after another bootstrap/regtest on x86_64-linux
> and i686-linux.  Besides the above requested change I've tweaked 2 lines
> in the test not to rely on a particular std::size_t exact type because
> otherwise the test failed on i686-linux.  And accepting there only the
> current
> unsigned int
> long unsigned int
> long long unsinged int
> unsigned __int20__ (or how exactly is this one spelled in diagnostics)
> seems fragile.
> 
> --- gcc/cp/semantics.cc.jj	2023-11-22 11:30:08.019325101 +0100
> +++ gcc/cp/semantics.cc	2023-11-22 22:58:25.194480633 +0100
> @@ -11485,9 +11534,89 @@ finish_static_assert (tree condition, tr
>   	  if (processing_template_decl)
>   	    goto defer;
>   
> -	  int sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT
> -				     (TREE_TYPE (TREE_TYPE (message))));
> -	  int len = TREE_STRING_LENGTH (message) / sz - 1;
> +	  int len;
> +	  const char *msg = NULL;
> +	  char *buf = NULL;
> +	  if (message_sz && message_data)
> +	    {
> +	      tree msz = cxx_constant_value (message_sz, NULL_TREE, complain);
> +	      if (!tree_fits_uhwi_p (msz))
> +		{
> +		  error_at (location,
> +			    "%<static_assert%> message %<size()%> "
> +			    "must be a constant expression");
> +		  return;
> +		}
> +	      else if ((unsigned HOST_WIDE_INT) (int) tree_to_uhwi (msz)
> +		       != tree_to_uhwi (msz))
> +		{
> +		  error_at (location,
> +			    "%<static_assert%> message %<size()%> "
> +			    "%qE too large", msz);
> +		  return;
> +		}
> +	      len = tree_to_uhwi (msz);
> +	      tree data = maybe_constant_value (message_data, NULL_TREE,
> +						mce_true);
> +	      if (!reduced_constant_expression_p (data))
> +		data = NULL_TREE;
> +	      if (len)
> +		{
> +		  if (data)
> +		    msg = c_getstr (data);
> +		  if (msg == NULL)
> +		    buf = XNEWVEC (char, len);

Jonathan pointed out elsewhere that this gets leaked if error return 
prevents us from getting to the XDELETEVEC.

> +		  for (int i = 0; i < len; ++i)
> +		    {
> +		      tree t = message_data;
> +		      if (i)
> +			t = build2 (POINTER_PLUS_EXPR,
> +				    TREE_TYPE (message_data), message_data,
> +				    size_int (i));
> +		      t = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
> +		      tree t2 = cxx_constant_value (t, NULL_TREE, complain);
> +		      if (!tree_fits_shwi_p (t2))
> +			{
> +			  error_at (location,
> +				    "%<static_assert%> message %<data()[%d]%> "
> +				    "must be a constant expression", i);
> +			  return;
> +			}
> +		      if (msg == NULL)
> +			buf[i] = tree_to_shwi (t2);
> +		      /* If c_getstr worked, just verify the first and
> +			 last characters using constant evaluation.  */
> +		      else if (len > 2 && i == 0)
> +			i = len - 2;
> +		    }
> +		  if (msg == NULL)
> +		    msg = buf;
> +		}
> +	      else if (!data)
> +		{
> +		  /* We don't have any function to test whether some
> +		     expression is a core constant expression.  So, instead
> +		     test whether (message.data (), 0) is a constant
> +		     expression.  */
> +		  data = build2 (COMPOUND_EXPR, integer_type_node,
> +				 message_data, integer_zero_node);
> +		  tree t = cxx_constant_value (data, NULL_TREE, complain);
> +		  if (!integer_zerop (t))
> +		    {
> +		      error_at (location,
> +				"%<static_assert%> message %<data()%> "
> +				"must be a core constant expression");
> +		      return;
> +		    }
> +		}
> +	    }
> +	  else
> +	    {
> +	      tree eltype = TREE_TYPE (TREE_TYPE (message));
> +	      int sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (eltype));
> +	      msg = TREE_STRING_POINTER (message);
> +	      len = TREE_STRING_LENGTH (message) / sz - 1;
> +	    }
>   
>   	  /* See if we can find which clause was failing (for logical AND).  */
>   	  tree bad = find_failing_clause (NULL, orig_condition);
> @@ -11497,12 +11626,13 @@ finish_static_assert (tree condition, tr
>   
>   	  auto_diagnostic_group d;
>   
> -          /* Report the error. */
> +	  /* Report the error. */
>   	  if (len == 0)
>   	    error_at (cloc, "static assertion failed");
>   	  else
> -	    error_at (cloc, "static assertion failed: %s",
> -		      TREE_STRING_POINTER (message));
> +	    error_at (cloc, "static assertion failed: %.*s", len, msg);
> +
> +	  XDELETEVEC (buf);
>   
>   	  diagnose_failing_condition (bad, cloc, show_expr_p);
>   	}


  reply	other threads:[~2023-11-28 16:31 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-24 14:30 [PATCH] c++: " Jakub Jelinek
2023-09-18 17:21 ` [PATCH] c++, v2: " Jakub Jelinek
2023-10-27  1:21   ` Jason Merrill
2023-11-17 14:18     ` Jason Merrill
2023-11-17 14:22       ` Jakub Jelinek
2023-11-21 17:17     ` [PATCH] c++, v3: " Jakub Jelinek
2023-11-21 17:23       ` Jakub Jelinek
2023-11-21 21:44       ` Jason Merrill
2023-11-21 22:19         ` Jakub Jelinek
2023-11-21 22:51           ` Jakub Jelinek
2023-11-22  3:51             ` Jason Merrill
2023-11-22 10:00               ` [PATCH] c++, v4: " Jakub Jelinek
2023-11-22 21:53                 ` Jason Merrill
2023-11-23  8:32                   ` Jakub Jelinek
2023-11-28 16:31                     ` Jason Merrill [this message]
2023-11-28 17:52                       ` Jakub Jelinek
2023-11-28 21:33                         ` Jason Merrill
2023-11-28 17:08                     ` Fix 'g++.dg/cpp26/static_assert1.C' for '-fno-exceptions' configurations (was: [PATCH] c++, v4: Implement C++26 P2741R3 - user-generated static_assert messages [PR110348]) Thomas Schwinge
2023-11-28 17:11                       ` Fix 'g++.dg/cpp26/static_assert1.C' for '-fno-exceptions' configurations Jason Merrill
2023-11-29 13:19                         ` Thomas Schwinge

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=aafda314-903b-4c12-a421-785eb5df4098@redhat.com \
    --to=jason@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jakub@redhat.com \
    --cc=jwakely@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).