From: Marek Polacek <polacek@redhat.com>
To: Hans-Peter Nilsson <hp@axis.com>
Cc: gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] c++: Don't ICE for unknown parameter to constexpr'd switch-statement, PR113545
Date: Mon, 22 Jan 2024 14:33:59 -0500 [thread overview]
Message-ID: <Za7DJw-d1gk-HqNU@redhat.com> (raw)
In-Reply-To: <20240122170232.C836A20439@pchp3.se.axis.com>
On Mon, Jan 22, 2024 at 06:02:32PM +0100, Hans-Peter Nilsson wrote:
> I don't really know whether this is the right way to treat
> CONVERT_EXPR as below, but... Regtested native
> x86_64-linux-gnu. Ok to commit?
Thanks for taking a look at this problem.
> brgds, H-P
>
> -- >8 --
> That gcc_unreachable at the default-label seems to be over
> the top. It seems more correct to just say "that's not
> constant" to whatever's not known (to be constant), when
> looking for matches in switch-statements.
Unfortunately this doesn't seem correct to me; I don't think we
should have gotten that far. It appears that we lose track of
the reinterpret_cast, which is not allowed in a constant expression:
<http://eel.is/c++draft/expr.const#5.15>.
cp_convert -> ... -> convert_to_integer_1 gives us a CONVERT_EXPR
but we only set REINTERPRET_CAST_P on NOP_EXPRs:
expr = cp_convert (type, expr, complain);
if (TREE_CODE (expr) == NOP_EXPR)
/* Mark any nop_expr that created as a reintepret_cast. */
REINTERPRET_CAST_P (expr) = true;
so when evaluating baz we get (long unsigned int) &foo, which
passes verify_constant.
I don't have a good suggestion yet, sorry.
> With this patch, the code generated for the (inlined) call to
> ifbar equals that to swbar, except for the comparisons being
> in another order.
>
> gcc/cp:
> PR c++/113545
> * constexpr.cc (label_matches): Replace call to_unreachable with
"to gcc_unreachable"
> return false.
More like with "break" but that's not important.
> gcc/testsuite:
> * g++.dg/expr/pr113545.C: New text.
"test"
> ---
> gcc/cp/constexpr.cc | 3 +-
> gcc/testsuite/g++.dg/expr/pr113545.C | 49 +++++++++++++++++++++++++++++
> 2 files changed, 51 insertions(+), 1 deletion(-)
> create mode 100644 gcc/testsuite/g++.dg/expr/pr113545.C
>
> diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
> index 6350fe154085..30caf3322fff 100644
> --- a/gcc/cp/constexpr.cc
> +++ b/gcc/cp/constexpr.cc
> @@ -6922,7 +6922,8 @@ label_matches (const constexpr_ctx *ctx, tree *jump_target, tree stmt)
> break;
>
> default:
> - gcc_unreachable ();
> + /* Something else, like CONVERT_EXPR. Unknown whether it matches. */
> + break;
> }
> return false;
> }
> diff --git a/gcc/testsuite/g++.dg/expr/pr113545.C b/gcc/testsuite/g++.dg/expr/pr113545.C
> new file mode 100644
> index 000000000000..914ffdeb8e16
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/expr/pr113545.C
The problem seems to be more about conversion so g++.dg/conversion/reinterpret5.C
or g++.dg/cpp0x/constexpr-reinterpret3.C seems more appropriate.
> @@ -0,0 +1,49 @@
Please add
PR c++/113545
> +// { dg-do run { target c++11 } }
> +
> +char foo;
> +
> +// This one caught a call to gcc_unreachable in
> +// cp/constexpr.cc:label_matches, when passed a convert_expr from the
> +// cast in the call.
> +constexpr unsigned char swbar(__UINTPTR_TYPE__ baz)
> +{
> + switch (baz)
> + {
> + case 13:
> + return 11;
> + case 14:
> + return 78;
> + case 2048:
> + return 13;
> + default:
> + return 42;
> + }
> +}
> +
> +// For reference, the equivalent* if-statements.
> +constexpr unsigned char ifbar(__UINTPTR_TYPE__ baz)
> +{
> + if (baz == 13)
> + return 11;
> + else if (baz == 14)
> + return 78;
> + else if (baz == 2048)
> + return 13;
> + else
> + return 42;
> +}
> +
> +__attribute__ ((__noipa__))
> +void xyzzy(int x)
> +{
> + if (x != 42)
> + __builtin_abort ();
> +}
> +
> +int main()
> +{
> + unsigned const char c = swbar(reinterpret_cast<__UINTPTR_TYPE__>(&foo));
> + xyzzy(c);
> + unsigned const char d = ifbar(reinterpret_cast<__UINTPTR_TYPE__>(&foo));
I suppose we should also test a C-style cast (which leads to a reinterpret_cast
in this case).
Maybe check we get an error when c/d are constexpr (that used to ICE).
> + xyzzy(d);
> +}
> --
> 2.30.2
>
Marek
next prev parent reply other threads:[~2024-01-22 19:34 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-22 17:02 Hans-Peter Nilsson
2024-01-22 19:33 ` Marek Polacek [this message]
2024-01-23 0:55 ` Hans-Peter Nilsson
2024-01-23 2:23 ` Hans-Peter Nilsson
2024-01-23 4:55 ` Hans-Peter Nilsson
2024-01-30 5:18 ` Ping PATCH: testcase for "ICE for unknown parameter to constexpr'd switch-statement, PR113545" Hans-Peter Nilsson
2024-02-07 0:04 ` Ping*2 " Hans-Peter Nilsson
2024-02-07 0:23 ` [PATCH] c++: Don't ICE for unknown parameter to constexpr'd switch-statement, PR113545 Hans-Peter Nilsson
2024-02-07 21:32 ` Jason Merrill
2024-02-08 2:11 ` Marek Polacek
2024-02-08 15:40 ` Hans-Peter Nilsson
2024-02-08 15:44 ` Marek Polacek
2024-02-08 16:07 ` Hans-Peter Nilsson
2024-02-08 16:22 ` Marek Polacek
2024-02-08 16:42 ` Hans-Peter Nilsson
2024-02-09 4:02 ` [PATCH v2]: testcases for "ICE for unknown parameter to constexpr'd switch-statement, PR113545" Hans-Peter Nilsson
2024-02-09 15:30 ` [PATCH v3]: " Hans-Peter Nilsson
2024-02-09 16:02 ` [PATCH v4]: " Hans-Peter Nilsson
2024-02-09 18:22 ` Jason Merrill
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=Za7DJw-d1gk-HqNU@redhat.com \
--to=polacek@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=hp@axis.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).