On 11/11/2021 2:46 PM, Martin Sebor via Gcc-patches wrote:
Attached is a v2 of the solution I posted earlier this week
with a few tweaks made after a more careful consideration of
the problem and possible false negatives and positives.

1) It avoids warning for [apparently infinitely recursive] calls
   in noreturn functions where the recursion may be prevented by
   a call to a noreturn function.
2) It avoids warning for calls where the recursion may be prevented
   by a call to a longjmp or siglongjmp.
3) It warns for recursive calls to built-ins in definitions of
   the corresponding library functions (e.g., for a call to
   __builtin_malloc in malloc).
4) It warns for calls to C++ functions even if they call other
   functions that might throw and so break out of the infinite
   recursion.  (E.g., operator new.)  This is the same as Clang.
5) It doesn't warn for calls to C++ functions with the throw
   expression.

Besides these changes to the warning itself, I've also improved
the code a bit by making the workhorse function a member of
the pass so recursive calls don't need to pass as many arguments
to itself.

Retested on x86_64-linux and by building Glibc and Binutils/GDB.

A possible enhancement is to warn for calls to calloc, malloc,
or realloc from within the definition of one of the other two
functions.  That might be a mistake made in code that tries
naively to replace the allocator with its own implementation.

On 11/9/21 9:28 PM, Martin Sebor wrote:
The attached patch adds support to the middle end for detecting
infinitely recursive calls.  The warning is controlled by the new
-Winfinite-recursion option.  The option name is the same as
Clang's.

I scheduled the warning pass to run after early inlining to
detect mutually recursive calls but before tail recursion which
turns some recursive calls into infinite loops and so makes
the two indistinguishable.

The warning detects a superset of problems detected by Clang
(based on its tests).  It detects the problem in PR88232
(the feature request) as well as the one in PR 87742,
an unrelated problem report that was root-caused to bug due
to infinite recursion.

This initial version doesn't attempt to deal with superimposed
symbols, so those might trigger false positives.  I'm not sure
that's something to worry about.

The tests are very light, but those for the exceptional cases
are exceedingly superficial, so it's possible those might harbor
some false positives and negatives.

Tested on x86_64-linux.

Martin



gcc-88232.diff

Implement -Winfinite-recursion [PR88232].

Resolves:
PR middle-end/88232 - Please implement -Winfinite-recursion

gcc/ChangeLog:

        PR middle-end/88232
        * Makefile.in (OBJS): Add gimple-warn-recursion.o.
        * common.opt: Add -Winfinite-recursion.
        * doc/invoke.texi (-Winfinite-recursion): Document.
        * passes.def (pass_warn_recursion): Schedule a new pass.
        * tree-pass.h (make_pass_warn_recursion): Declare.
        * gimple-warn-recursion.c: New file.

gcc/c-family/ChangeLog:

        PR middle-end/88232
        * c.opt: Add -Winfinite-recursion.

gcc/testsuite/ChangeLog:

        PR middle-end/88232
        * c-c++-common/attr-used-5.c: Suppress valid warning.
        * c-c++-common/attr-used-6.c: Same.
        * c-c++-common/attr-used-9.c: Same.
        * g++.dg/warn/Winfinite-recursion-2.C: New test.
        * g++.dg/warn/Winfinite-recursion-3.C: New test.
        * g++.dg/warn/Winfinite-recursion.C: New test.
        * gcc.dg/Winfinite-recursion-2.c: New test.
        * gcc.dg/Winfinite-recursion.c: New test.
This is OK.  While there may be other improvements that could be made, this looks like a reasonable warning as-is and can be extended/refined as needed.

jeff

Reply via email to