From: Jakub Jelinek <jakub@redhat.com>
To: Jason Merrill <jason@redhat.com>
Cc: gcc-patches@gcc.gnu.org
Subject: [C++ PATCH] Fix constexpr switch handling (PR c++/77467)
Date: Mon, 05 Sep 2016 17:14:00 -0000 [thread overview]
Message-ID: <20160905171119.GU14857@tucnak.redhat.com> (raw)
Hi!
cxx_eval_switch_expr assumes that SWITCH_EXPR's body is always a
STATEMENT_LIST, but that doesn't have to be the case.
As the testcase shows, if there are any variable declarations in the
switch body, it can be also a BIND_EXPR, which cxx_eval_constant_expression
handles properly, and as bar in the testcase shows, it can be also just
a single statement (as try isn't allowed in constexpr functions, I think
we just want to do what cxx_eval_statement_list would do on such a statement
if it was wrapped into a STATEMENT_LIST - ignore it, as the case NNN: or default:
is not present.
Bootstrapped/regtested on x86_64-linux and i686-linux? What about older
branches?
2016-09-05 Jakub Jelinek <jakub@redhat.com>
PR c++/77467
* constexpr.c (cxx_eval_switch_expr): Call cxx_eval_constant_expression
instead of cxx_eval_statement_list, for body other than STATEMENT_LIST
or BIND_EXPR don't evaluate the body at all.
* g++.dg/cpp1y/constexpr-77467.C: New test.
--- gcc/cp/constexpr.c.jj 2016-08-30 08:42:06.000000000 +0200
+++ gcc/cp/constexpr.c 2016-09-05 11:34:30.185518395 +0200
@@ -3572,8 +3572,12 @@ cxx_eval_switch_expr (const constexpr_ct
*jump_target = cond;
tree body = TREE_OPERAND (t, 1);
- cxx_eval_statement_list (ctx, body,
- non_constant_p, overflow_p, jump_target);
+ /* If body is a statement other than STATEMENT_LIST or BIND_EXPR,
+ it should be skipped. E.g. switch (a) b = a; */
+ if (TREE_CODE (body) == STATEMENT_LIST
+ || TREE_CODE (body) == BIND_EXPR)
+ cxx_eval_constant_expression (ctx, body, false,
+ non_constant_p, overflow_p, jump_target);
if (breaks (jump_target) || switches (jump_target))
*jump_target = NULL_TREE;
return NULL_TREE;
--- gcc/testsuite/g++.dg/cpp1y/constexpr-77467.C.jj 2016-09-05 11:19:30.593750642 +0200
+++ gcc/testsuite/g++.dg/cpp1y/constexpr-77467.C 2016-09-05 11:37:11.929477518 +0200
@@ -0,0 +1,33 @@
+// PR c++/77467
+// { dg-do compile { target c++14 } }
+
+constexpr int
+foo (const int x, const unsigned n) noexcept
+{
+ switch (n)
+ {
+ case 0:
+ return 1;
+ case 1:
+ return x;
+ default:
+ const auto m = (n >> 1);
+ const auto y = foo (x, m);
+ return ((m << 1) == n) ? y * y : x * y * y;
+ }
+}
+
+static_assert (foo (3, 2) == 9, "");
+static_assert (foo (2, 3) == 8, "");
+
+constexpr int
+bar (int x)
+{
+ int a = x;
+ switch (x)
+ a = x + 1;
+ return a;
+}
+
+static_assert (bar (0) == 0, "");
+static_assert (bar (1) == 1, "");
Jakub
next reply other threads:[~2016-09-05 17:11 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-09-05 17:14 Jakub Jelinek [this message]
2016-09-16 20:00 ` Jason Merrill
2016-09-16 20:51 ` Jakub Jelinek
2016-09-19 18:49 ` Jason Merrill
2016-09-20 16:29 ` [C++ PATCH] Fix constexpr switch handling (PR c++/77467, take 2) Jakub Jelinek
2016-09-27 21:33 ` Patch ping Jakub Jelinek
2016-09-28 14:42 ` [C++ PATCH] Fix constexpr switch handling (PR c++/77467, take 2) 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=20160905171119.GU14857@tucnak.redhat.com \
--to=jakub@redhat.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).