[PATCH v2] implement -Winfinite-recursion [PR88232]

Jeff Law jeffreyalaw@gmail.com
Tue Nov 23 19:11:10 GMT 2021

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.


More information about the Gcc-patches mailing list