public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/105321] New: "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression
@ 2022-04-20 18:47 bekenn at gmail dot com
  2022-04-20 19:10 ` [Bug c++/105321] " mpolacek at gcc dot gnu.org
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: bekenn at gmail dot com @ 2022-04-20 18:47 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105321

            Bug ID: 105321
           Summary: "non-constant condition" issued for function
                    containing a short-circuited unevaluated non-constant
                    expression
           Product: gcc
           Version: 11.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: bekenn at gmail dot com
  Target Milestone: ---

bool handle_error();

constexpr int echo(int value, bool yes = true) noexcept
{
    return (yes || handle_error()), value;
}

static_assert(echo(10) == 10, "");

---

<source>:8:24: error: non-constant condition for static assertion
    8 | static_assert(echo(10) == 10, "");
      |               ~~~~~~~~~^~~~~
<source>:8:19:   in 'constexpr' expansion of 'echo(10, 1)'
<source>:3:36: error: 'yes' is not a constant expression
    3 | constexpr int echo(int value, bool yes = true) noexcept
      |                               ~~~~~^~~~~~~~~~

https://godbolt.org/z/vsd9xdW5c

---

It appears that the || operator isn't short-circuiting correctly during
constant evaluation.  This seems to be very particular; if I replace `yes` with
a more complicated expression (such as `!no`), the problem disappears.

This issue shows up in every version of GCC I've tried, including 11.2 and the
current "trunk" release on Compiler Explorer.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/105321] "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression
  2022-04-20 18:47 [Bug c++/105321] New: "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression bekenn at gmail dot com
@ 2022-04-20 19:10 ` mpolacek at gcc dot gnu.org
  2022-04-20 19:45 ` mpolacek at gcc dot gnu.org
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: mpolacek at gcc dot gnu.org @ 2022-04-20 19:10 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105321

Marek Polacek <mpolacek at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |rejects-valid
   Last reconfirmed|                            |2022-04-20
     Ever confirmed|0                           |1
                 CC|                            |mpolacek at gcc dot gnu.org
             Status|UNCONFIRMED                 |NEW

--- Comment #1 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
Confirmed.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/105321] "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression
  2022-04-20 18:47 [Bug c++/105321] New: "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression bekenn at gmail dot com
  2022-04-20 19:10 ` [Bug c++/105321] " mpolacek at gcc dot gnu.org
@ 2022-04-20 19:45 ` mpolacek at gcc dot gnu.org
  2022-04-20 19:48 ` mpolacek at gcc dot gnu.org
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: mpolacek at gcc dot gnu.org @ 2022-04-20 19:45 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105321

--- Comment #2 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
As you mention, this slightly modified test compiles fine:

bool handle_error();

constexpr int echo(int value, bool yes = false) noexcept
{
    return (!yes || handle_error()), value;
}

static_assert(echo(10) == 10, "");

In the original test we have

<retval> = (void) (VIEW_CONVERT_EXPR<bool>(yes) || handle_error ());,
VIEW_CONVERT_EXPR<int>(value);

which has a COMPOUND_EXPR, so we get to
cxx_eval_constant_expression/COMPOUND_EXPR.  The problem here is that we call 

7044             /* Check that the LHS is constant and then discard it.  */
7045             cxx_eval_constant_expression (ctx, op0,
7046                                           true, non_constant_p,
overflow_p,
7047                                           jump_target);

where lval is always true, so the PARM_DECL 'yes' is not evaluated.

In the working test, we evaluate "!yes" in cxx_eval_unary_expression which
evaluates its operand with

3217   tree arg = cxx_eval_constant_expression (ctx, orig_arg, /*lval*/false,
3218                                            non_constant_p, overflow_p);

where lval is false, so the PARM_DECL is evaluated into a constant.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/105321] "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression
  2022-04-20 18:47 [Bug c++/105321] New: "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression bekenn at gmail dot com
  2022-04-20 19:10 ` [Bug c++/105321] " mpolacek at gcc dot gnu.org
  2022-04-20 19:45 ` mpolacek at gcc dot gnu.org
@ 2022-04-20 19:48 ` mpolacek at gcc dot gnu.org
  2022-04-20 19:55 ` mpolacek at gcc dot gnu.org
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: mpolacek at gcc dot gnu.org @ 2022-04-20 19:48 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105321

--- Comment #3 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
The argument for lval changed from false to true in

commit 12d9ce19034428072b3779eff017c5e129ee4c0e
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Dec 17 15:41:18 2014 -0500

    re PR c++/64333 (C++14 constexpr gives wrong results when a looping
constexpr function is evaluated twice)

            PR c++/64333
            * constexpr.c (cxx_bind_parameters_in_call): non_constant_args
parm.
            (cxx_eval_call_expression): Don't cache calls with non-constant
args.
            (cxx_eval_constant_expression) [COMPOUND_EXPR]: Pass true for lval.
            (cxx_eval_unary_expression, cxx_eval_binary_expression)
            (cxx_eval_conditional_expression): Pass false for lval.

    From-SVN: r218832

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/105321] "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression
  2022-04-20 18:47 [Bug c++/105321] New: "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression bekenn at gmail dot com
                   ` (2 preceding siblings ...)
  2022-04-20 19:48 ` mpolacek at gcc dot gnu.org
@ 2022-04-20 19:55 ` mpolacek at gcc dot gnu.org
  2022-04-20 19:59 ` [Bug c++/105321] [9/10/11/12 Regression] " mpolacek at gcc dot gnu.org
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: mpolacek at gcc dot gnu.org @ 2022-04-20 19:55 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105321

Marek Polacek <mpolacek at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Assignee|unassigned at gcc dot gnu.org      |mpolacek at gcc dot gnu.org
             Status|NEW                         |ASSIGNED

--- Comment #4 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
This sort of obvious patch seems to work:

--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -7043,7 +7043,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx,
tree t,
      {
        /* Check that the LHS is constant and then discard it.  */
        cxx_eval_constant_expression (ctx, op0,
-                     true, non_constant_p, overflow_p,
+                     lval, non_constant_p, overflow_p,
                      jump_target);
        if (*non_constant_p)
          return t;

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/105321] [9/10/11/12 Regression] "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression
  2022-04-20 18:47 [Bug c++/105321] New: "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression bekenn at gmail dot com
                   ` (3 preceding siblings ...)
  2022-04-20 19:55 ` mpolacek at gcc dot gnu.org
@ 2022-04-20 19:59 ` mpolacek at gcc dot gnu.org
  2022-04-21 14:18 ` cvs-commit at gcc dot gnu.org
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: mpolacek at gcc dot gnu.org @ 2022-04-20 19:59 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105321

Marek Polacek <mpolacek at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P3                          |P2
            Summary|"non-constant condition"    |[9/10/11/12 Regression]
                   |issued for function         |"non-constant condition"
                   |containing a                |issued for function
                   |short-circuited unevaluated |containing a
                   |non-constant expression     |short-circuited unevaluated
                   |                            |non-constant expression
   Target Milestone|---                         |9.5

--- Comment #5 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
It's a regression, this worked with GCC 4.9.4.  So the fix should be suitable
for GCC 12 still.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/105321] [9/10/11/12 Regression] "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression
  2022-04-20 18:47 [Bug c++/105321] New: "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression bekenn at gmail dot com
                   ` (4 preceding siblings ...)
  2022-04-20 19:59 ` [Bug c++/105321] [9/10/11/12 Regression] " mpolacek at gcc dot gnu.org
@ 2022-04-21 14:18 ` cvs-commit at gcc dot gnu.org
  2022-04-21 15:39 ` [Bug c++/105321] [9/10/11 " mpolacek at gcc dot gnu.org
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2022-04-21 14:18 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105321

--- Comment #6 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>:

https://gcc.gnu.org/g:93b65ed9706e2ceb4be7b28c9ff9be759e68a614

commit r12-8216-g93b65ed9706e2ceb4be7b28c9ff9be759e68a614
Author: Marek Polacek <polacek@redhat.com>
Date:   Wed Apr 20 16:02:52 2022 -0400

    c++: wrong error with constexpr COMPOUND_EXPR [PR105321]

    Here we issue a bogus error for the first assert in the test.  Therein
    we have

    <retval> = (void) (VIEW_CONVERT_EXPR<bool>(yes) || handle_error ());,
VIEW_CONVERT_EXPR<int>(value);

    which has a COMPOUND_EXPR, so we get to cxx_eval_constant_expression
    <case COMPOUND_EXPR>.  The problem here is that we call

    7044             /* Check that the LHS is constant and then discard it.  */
    7045             cxx_eval_constant_expression (ctx, op0,
    7046                                           true, non_constant_p,
overflow_p,
    7047                                           jump_target);

    where lval is always true, so the PARM_DECL 'yes' is not evaluated into
    its value.

    Fixed by always passing false for 'lval' in cxx_eval_logical_expression;
    there's no case where we actually expect an lvalue from a TRUTH_*.

            PR c++/105321

    gcc/cp/ChangeLog:

            * constexpr.cc (cxx_eval_logical_expression): Always pass false for
lval
            to cxx_eval_constant_expression.

    gcc/testsuite/ChangeLog:

            * g++.dg/cpp0x/constexpr-105321.C: New test.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/105321] [9/10/11 Regression] "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression
  2022-04-20 18:47 [Bug c++/105321] New: "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression bekenn at gmail dot com
                   ` (5 preceding siblings ...)
  2022-04-21 14:18 ` cvs-commit at gcc dot gnu.org
@ 2022-04-21 15:39 ` mpolacek at gcc dot gnu.org
  2022-04-21 17:00 ` bekenn at gmail dot com
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: mpolacek at gcc dot gnu.org @ 2022-04-21 15:39 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105321

Marek Polacek <mpolacek at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|[9/10/11/12 Regression]     |[9/10/11 Regression]
                   |"non-constant condition"    |"non-constant condition"
                   |issued for function         |issued for function
                   |containing a                |containing a
                   |short-circuited unevaluated |short-circuited unevaluated
                   |non-constant expression     |non-constant expression

--- Comment #7 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
Fixed on trunk so far.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/105321] [9/10/11 Regression] "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression
  2022-04-20 18:47 [Bug c++/105321] New: "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression bekenn at gmail dot com
                   ` (6 preceding siblings ...)
  2022-04-21 15:39 ` [Bug c++/105321] [9/10/11 " mpolacek at gcc dot gnu.org
@ 2022-04-21 17:00 ` bekenn at gmail dot com
  2022-04-22 21:01 ` cvs-commit at gcc dot gnu.org
  2022-04-22 21:01 ` mpolacek at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: bekenn at gmail dot com @ 2022-04-21 17:00 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105321

--- Comment #8 from James Touton <bekenn at gmail dot com> ---
Thanks for the quick action on this!

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/105321] [9/10/11 Regression] "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression
  2022-04-20 18:47 [Bug c++/105321] New: "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression bekenn at gmail dot com
                   ` (7 preceding siblings ...)
  2022-04-21 17:00 ` bekenn at gmail dot com
@ 2022-04-22 21:01 ` cvs-commit at gcc dot gnu.org
  2022-04-22 21:01 ` mpolacek at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2022-04-22 21:01 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105321

--- Comment #9 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-11 branch has been updated by Marek Polacek
<mpolacek@gcc.gnu.org>:

https://gcc.gnu.org/g:afec66b054a7603ef394dc712ccbba37ae645fd9

commit r11-9930-gafec66b054a7603ef394dc712ccbba37ae645fd9
Author: Marek Polacek <polacek@redhat.com>
Date:   Wed Apr 20 16:02:52 2022 -0400

    c++: wrong error with constexpr COMPOUND_EXPR [PR105321]

    Here we issue a bogus error for the first assert in the test.  Therein
    we have

    <retval> = (void) (VIEW_CONVERT_EXPR<bool>(yes) || handle_error ());,
VIEW_CONVERT_EXPR<int>(value);

    which has a COMPOUND_EXPR, so we get to cxx_eval_constant_expression
    <case COMPOUND_EXPR>.  The problem here is that we call

    7044             /* Check that the LHS is constant and then discard it.  */
    7045             cxx_eval_constant_expression (ctx, op0,
    7046                                           true, non_constant_p,
overflow_p,
    7047                                           jump_target);

    where lval is always true, so the PARM_DECL 'yes' is not evaluated into
    its value.

    Fixed by always passing false for 'lval' in cxx_eval_logical_expression;
    there's no case where we actually expect an lvalue from a TRUTH_*.

            PR c++/105321

    gcc/cp/ChangeLog:

            * constexpr.c (cxx_eval_logical_expression): Always pass false for
lval
            to cxx_eval_constant_expression.

    gcc/testsuite/ChangeLog:

            * g++.dg/cpp0x/constexpr-105321.C: New test.

    (cherry picked from commit 93b65ed9706e2ceb4be7b28c9ff9be759e68a614)

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/105321] [9/10/11 Regression] "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression
  2022-04-20 18:47 [Bug c++/105321] New: "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression bekenn at gmail dot com
                   ` (8 preceding siblings ...)
  2022-04-22 21:01 ` cvs-commit at gcc dot gnu.org
@ 2022-04-22 21:01 ` mpolacek at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: mpolacek at gcc dot gnu.org @ 2022-04-22 21:01 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105321

Marek Polacek <mpolacek at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |RESOLVED
         Resolution|---                         |FIXED

--- Comment #10 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
Fixed in GCC 11.3 too.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2022-04-22 21:01 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-20 18:47 [Bug c++/105321] New: "non-constant condition" issued for function containing a short-circuited unevaluated non-constant expression bekenn at gmail dot com
2022-04-20 19:10 ` [Bug c++/105321] " mpolacek at gcc dot gnu.org
2022-04-20 19:45 ` mpolacek at gcc dot gnu.org
2022-04-20 19:48 ` mpolacek at gcc dot gnu.org
2022-04-20 19:55 ` mpolacek at gcc dot gnu.org
2022-04-20 19:59 ` [Bug c++/105321] [9/10/11/12 Regression] " mpolacek at gcc dot gnu.org
2022-04-21 14:18 ` cvs-commit at gcc dot gnu.org
2022-04-21 15:39 ` [Bug c++/105321] [9/10/11 " mpolacek at gcc dot gnu.org
2022-04-21 17:00 ` bekenn at gmail dot com
2022-04-22 21:01 ` cvs-commit at gcc dot gnu.org
2022-04-22 21:01 ` mpolacek at gcc dot gnu.org

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).