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