public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/114462] New: [C++26] P2809R3 - Trivial infinite loops are not undefined behavior
@ 2024-03-25 11:16 jakub at gcc dot gnu.org
  2024-03-25 11:40 ` [Bug c++/114462] " rguenth at gcc dot gnu.org
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: jakub at gcc dot gnu.org @ 2024-03-25 11:16 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 114462
           Summary: [C++26] P2809R3 - Trivial infinite loops are not
                    undefined behavior
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jakub at gcc dot gnu.org
  Target Milestone: ---

See <https://wg21.link/P2809R3>.

DR.

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

* [Bug c++/114462] [C++26] P2809R3 - Trivial infinite loops are not undefined behavior
  2024-03-25 11:16 [Bug c++/114462] New: [C++26] P2809R3 - Trivial infinite loops are not undefined behavior jakub at gcc dot gnu.org
@ 2024-03-25 11:40 ` rguenth at gcc dot gnu.org
  2024-03-25 11:52 ` jakub at gcc dot gnu.org
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: rguenth at gcc dot gnu.org @ 2024-03-25 11:40 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
Apart from marking via -ffinite-loops GCC considers loops without an exit as
not required to make "forward progress".  That's more than just a constant
controlling expression but should allow optimizing most relevant cases.

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

* [Bug c++/114462] [C++26] P2809R3 - Trivial infinite loops are not undefined behavior
  2024-03-25 11:16 [Bug c++/114462] New: [C++26] P2809R3 - Trivial infinite loops are not undefined behavior jakub at gcc dot gnu.org
  2024-03-25 11:40 ` [Bug c++/114462] " rguenth at gcc dot gnu.org
@ 2024-03-25 11:52 ` jakub at gcc dot gnu.org
  2024-03-25 11:55 ` jakub at gcc dot gnu.org
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: jakub at gcc dot gnu.org @ 2024-03-25 11:52 UTC (permalink / raw)
  To: gcc-bugs

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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jason at gcc dot gnu.org

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I know, but I think this will need changes in the C++ FE.
I was asking recently Jason what the "when interpreted as a
constant-expression"
in the paper actually means, whether such expression should be evaluated as
manifestly constant evaluation or not.
If yes, it seems like an incompatible change in a DR, because say
#include <type_traits>
void
foo ()
{
  while (std::is_constant_evaluated ())
    ;
}
changing behavior from previous doing nothing to an infinite loop.
If it is not manifestly constant evaluation, still, the FE would need to (at
least for the cases listed in the paper) try to silently constant evaluate the
condition (with
mce_false such that std::is_constant_evaluated () is folded to false in there;
but perhaps only during cp_fold_function?) and if that evaluates to non-zero
replace the condition with true, such that the middle-end would then really
consider it as infinite loop regardless of -ffinite-loops.
Because if one has
constexpr bool
bar ()
{
  return true;
}
void
baz ()
{
  while (bar ())
    ;
}
we want middle-end to see while (true) ; rather than while (bar ()) ; because
the latter would be under -ffinite-loops decision.

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

* [Bug c++/114462] [C++26] P2809R3 - Trivial infinite loops are not undefined behavior
  2024-03-25 11:16 [Bug c++/114462] New: [C++26] P2809R3 - Trivial infinite loops are not undefined behavior jakub at gcc dot gnu.org
  2024-03-25 11:40 ` [Bug c++/114462] " rguenth at gcc dot gnu.org
  2024-03-25 11:52 ` jakub at gcc dot gnu.org
@ 2024-03-25 11:55 ` jakub at gcc dot gnu.org
  2024-03-25 17:55 ` jakub at gcc dot gnu.org
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: jakub at gcc dot gnu.org @ 2024-03-25 11:55 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
And another case to watch for is:
void
qux ()
{
  while (const bool b = bar ())
    ;
}

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

* [Bug c++/114462] [C++26] P2809R3 - Trivial infinite loops are not undefined behavior
  2024-03-25 11:16 [Bug c++/114462] New: [C++26] P2809R3 - Trivial infinite loops are not undefined behavior jakub at gcc dot gnu.org
                   ` (2 preceding siblings ...)
  2024-03-25 11:55 ` jakub at gcc dot gnu.org
@ 2024-03-25 17:55 ` jakub at gcc dot gnu.org
  2024-03-25 17:55 ` jakub at gcc dot gnu.org
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: jakub at gcc dot gnu.org @ 2024-03-25 17:55 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Ah, if there is a declaration in the condition, then it is not a valid trivial
empty iteration statement.

Anyway, I'd say cp_fold should for WHILE_STMT, DO_STMT and FOR_STMT if the body
is
a STATEMENT_LIST with no statements at all or an empty statement (do we have
predicate for NOP_EXPR to void_type_node of integer_zero_node?) and in case of
FOR_STMT empty increment expression argument try to evaluate the condition as
mce_false constant expression and if it evaluates to constant non-zero, replace
the condition with boolean_true_node.

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

* [Bug c++/114462] [C++26] P2809R3 - Trivial infinite loops are not undefined behavior
  2024-03-25 11:16 [Bug c++/114462] New: [C++26] P2809R3 - Trivial infinite loops are not undefined behavior jakub at gcc dot gnu.org
                   ` (3 preceding siblings ...)
  2024-03-25 17:55 ` jakub at gcc dot gnu.org
@ 2024-03-25 17:55 ` jakub at gcc dot gnu.org
  2024-03-25 18:06 ` pinskia at gcc dot gnu.org
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: jakub at gcc dot gnu.org @ 2024-03-25 17:55 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
constexpr bool foo () { return true; }
volatile int v;

void
bar (int x)
{
  switch (x)
    {
    case 0:
      while (foo ()) ;
      break;
    case 1:
      while (foo ()) {}
      break;
    case 2:
      do ; while (foo ());
      break;
    case 3:
      do {} while (foo ());
      break;
    case 4:
      do {} while (foo ());
      break;
    case 5:
      for (v = 42; foo (); ) ;
      break;
    case 6:
      for (v = 42; foo (); ) {}
      break;
    case 7:
      for (int w = 42; foo (); ) ;
      break;
    case 8:
      for (int w = 42; foo (); ) {}
      break;
    default:
      break;
    }
}

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

* [Bug c++/114462] [C++26] P2809R3 - Trivial infinite loops are not undefined behavior
  2024-03-25 11:16 [Bug c++/114462] New: [C++26] P2809R3 - Trivial infinite loops are not undefined behavior jakub at gcc dot gnu.org
                   ` (4 preceding siblings ...)
  2024-03-25 17:55 ` jakub at gcc dot gnu.org
@ 2024-03-25 18:06 ` pinskia at gcc dot gnu.org
  2024-04-02 10:43 ` jakub at gcc dot gnu.org
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-03-25 18:06 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2024-03-25
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW

--- Comment #6 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
.

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

* [Bug c++/114462] [C++26] P2809R3 - Trivial infinite loops are not undefined behavior
  2024-03-25 11:16 [Bug c++/114462] New: [C++26] P2809R3 - Trivial infinite loops are not undefined behavior jakub at gcc dot gnu.org
                   ` (5 preceding siblings ...)
  2024-03-25 18:06 ` pinskia at gcc dot gnu.org
@ 2024-04-02 10:43 ` jakub at gcc dot gnu.org
  2024-04-10  8:19 ` cvs-commit at gcc dot gnu.org
  2024-04-10  8:20 ` jakub at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: jakub at gcc dot gnu.org @ 2024-04-02 10:43 UTC (permalink / raw)
  To: gcc-bugs

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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

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

--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Created attachment 57847
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=57847&action=edit
gcc14-pr114462.patch

Untested fix.

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

* [Bug c++/114462] [C++26] P2809R3 - Trivial infinite loops are not undefined behavior
  2024-03-25 11:16 [Bug c++/114462] New: [C++26] P2809R3 - Trivial infinite loops are not undefined behavior jakub at gcc dot gnu.org
                   ` (6 preceding siblings ...)
  2024-04-02 10:43 ` jakub at gcc dot gnu.org
@ 2024-04-10  8:19 ` cvs-commit at gcc dot gnu.org
  2024-04-10  8:20 ` jakub at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2024-04-10  8:19 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #8 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:4be1cc5f50578fafcdcbd09160235066d76a3f86

commit r14-9887-g4be1cc5f50578fafcdcbd09160235066d76a3f86
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Wed Apr 10 10:08:12 2024 +0200

    c++: Implement C++26 P2809R3 - Trivial infinite loops are not Undefined
Behavior

    The following patch attempts to implement P2809R3, which has been voted
    in as a DR.

    The middle-end has its behavior documented:
    '-ffinite-loops'
         Assume that a loop with an exit will eventually take the exit and
         not loop indefinitely.  This allows the compiler to remove loops
         that otherwise have no side-effects, not considering eventual
         endless looping as such.

         This option is enabled by default at '-O2' for C++ with -std=c++11
         or higher.

    So, the following patch attempts to detect trivial infinite loops by
detecting
    trivially empty loops, if their condition is not INTEGER_CST (that case is
    handled by the middle-end right already) trying to constant evaluate with
    mce=true their condition and if it evaluates to true (and -ffinite-loops
and
    not processing_template_decl) wraps the condition into an ANNOTATE_EXPR
which
    tells the middle-end that the loop shouldn't be loop->finite_p despite
    -ffinite-loops).

    Furthermore, the patch adds -Wtautological-compare warnings for loop
    conditions containing std::is_constant_evaluated(), either if those
    always evaluate to true, or always evaluate to false, or will evaluate
    to true just when checking if it is trivial infinite loop (and if in
non-constexpr
    function also say that it will evaluate to false otherwise).
    The user is doing something weird in all those cases.

    2024-04-10  Jakub Jelinek  <jakub@redhat.com>

            PR c++/114462
    gcc/
            * tree-core.h (enum annot_expr_kind): Add
            annot_expr_maybe_infinite_kind enumerator.
            * gimplify.cc (gimple_boolify): Handle
annot_expr_maybe_infinite_kind.
            * tree-cfg.cc (replace_loop_annotate_in_block): Likewise.
            (replace_loop_annotate): Likewise.  Move loop->finite_p
initialization
            before the replace_loop_annotate_in_block calls.
            * tree-pretty-print.cc (dump_generic_node): Handle
            annot_expr_maybe_infinite_kind.
    gcc/cp/
            * semantics.cc: Implement C++26 P2809R3 - Trivial infinite
            loops are not Undefined Behavior.
            (maybe_warn_for_constant_evaluated): Add trivial_infinite argument
            and emit special diagnostics for that case.
            (finish_if_stmt_cond): Adjust caller.
            (finish_loop_cond): New function.
            (finish_while_stmt): Use it.
            (finish_do_stmt): Likewise.
            (finish_for_stmt): Likewise.
    gcc/testsuite/
            * g++.dg/cpp26/trivial-infinite-loop1.C: New test.
            * g++.dg/cpp26/trivial-infinite-loop2.C: New test.
            * g++.dg/cpp26/trivial-infinite-loop3.C: New test.

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

* [Bug c++/114462] [C++26] P2809R3 - Trivial infinite loops are not undefined behavior
  2024-03-25 11:16 [Bug c++/114462] New: [C++26] P2809R3 - Trivial infinite loops are not undefined behavior jakub at gcc dot gnu.org
                   ` (7 preceding siblings ...)
  2024-04-10  8:19 ` cvs-commit at gcc dot gnu.org
@ 2024-04-10  8:20 ` jakub at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: jakub at gcc dot gnu.org @ 2024-04-10  8:20 UTC (permalink / raw)
  To: gcc-bugs

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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

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

--- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Implemented for GCC 14.1.

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

end of thread, other threads:[~2024-04-10  8:20 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-25 11:16 [Bug c++/114462] New: [C++26] P2809R3 - Trivial infinite loops are not undefined behavior jakub at gcc dot gnu.org
2024-03-25 11:40 ` [Bug c++/114462] " rguenth at gcc dot gnu.org
2024-03-25 11:52 ` jakub at gcc dot gnu.org
2024-03-25 11:55 ` jakub at gcc dot gnu.org
2024-03-25 17:55 ` jakub at gcc dot gnu.org
2024-03-25 17:55 ` jakub at gcc dot gnu.org
2024-03-25 18:06 ` pinskia at gcc dot gnu.org
2024-04-02 10:43 ` jakub at gcc dot gnu.org
2024-04-10  8:19 ` cvs-commit at gcc dot gnu.org
2024-04-10  8:20 ` jakub 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).