On Mon, May 19, 2025 at 11:23:34AM -0700, Kees Cook wrote:
> On Fri, May 16, 2025 at 01:34:14PM +0000, Qing Zhao wrote:
> > Adding -fdiagnotics-details into GCC to provide more hints to the
> > end users on how the warnings come from, in order to help the user
> > to locate the exact location in source code on the specific warnings
> > due to compiler optimizations.
>
> I just needed to examine an unexpected -Wrestrict warning, and
> discovered that this patch didn't help with it, but in looking at the
> implementation details, it turned out to be trivial to expand coverage
> to include -Wrestrict, which worked for me, and got me the
> diagnostics I needed[1].
I found another case[1] where I didn't get detailed diagnostics, so I
tried to instrument that too, but it didn't do anything. Here's the patch
(trying to get more coverage for stringop-overflow), but I don't know
what I did wrong:
diff --git a/gcc/tree-ssa-strlen.cc b/gcc/tree-ssa-strlen.cc
index c4d64132e538..6342231afba2 100644
--- a/gcc/tree-ssa-strlen.cc
+++ b/gcc/tree-ssa-strlen.cc
@@ -59,6 +59,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-loop.h"
#include "tree-scalar-evolution.h"
#include "vr-values.h"
+#include "move-history-rich-location.h"
#include "gimple-range.h"
#include "tree-ssa.h"
@@ -2113,6 +2114,8 @@ strlen_pass::maybe_warn_overflow (gimple *stmt, bool
call_lhs, tree len,
return;
location_t loc = gimple_or_expr_nonartificial_location (stmt, dest);
+ rich_location_with_details richloc (loc, stmt);
+
bool warned = false;
if (wi::leu_p (lenrng[0], spcrng[1]))
{
@@ -2121,11 +2124,11 @@ strlen_pass::maybe_warn_overflow (gimple *stmt, bool
call_lhs, tree len,
return;
warned = (writefn
- ? warning_at (loc, OPT_Wstringop_overflow_,
+ ? warning_at (&richloc, OPT_Wstringop_overflow_,
"%qD writing one too many bytes into a region "
"of a size that depends on %<strlen%>",
writefn)
- : warning_at (loc, OPT_Wstringop_overflow_,
+ : warning_at (&richloc, OPT_Wstringop_overflow_,
"writing one too many bytes into a region "
"of a size that depends on %<strlen%>"));
}
@@ -2133,7 +2136,7 @@ strlen_pass::maybe_warn_overflow (gimple *stmt, bool
call_lhs, tree len,
{
if (spcrng[0] == spcrng[1])
warned = (writefn
- ? warning_n (loc, OPT_Wstringop_overflow_,
+ ? warning_n (&richloc, OPT_Wstringop_overflow_,
lenrng[0].to_uhwi (),
"%qD writing %wu byte into a region "
"of size %wu",
@@ -2141,7 +2144,7 @@ strlen_pass::maybe_warn_overflow (gimple *stmt, bool
call_lhs, tree len,
"of size %wu",
writefn, lenrng[0].to_uhwi (),
spcrng[0].to_uhwi ())
- : warning_n (loc, OPT_Wstringop_overflow_,
+ : warning_n (&richloc, OPT_Wstringop_overflow_,
lenrng[0].to_uhwi (),
"writing %wu byte into a region "
"of size %wu",
@@ -2151,7 +2154,7 @@ strlen_pass::maybe_warn_overflow (gimple *stmt, bool
call_lhs, tree len,
spcrng[0].to_uhwi ()));
else
warned = (writefn
- ? warning_n (loc, OPT_Wstringop_overflow_,
+ ? warning_n (&richloc, OPT_Wstringop_overflow_,
lenrng[0].to_uhwi (),
"%qD writing %wu byte into a region "
"of size between %wu and %wu",
@@ -2159,7 +2162,7 @@ strlen_pass::maybe_warn_overflow (gimple *stmt, bool
call_lhs, tree len,
"of size between %wu and %wu",
writefn, lenrng[0].to_uhwi (),
spcrng[0].to_uhwi (), spcrng[1].to_uhwi ())
- : warning_n (loc, OPT_Wstringop_overflow_,
+ : warning_n (&richloc, OPT_Wstringop_overflow_,
lenrng[0].to_uhwi (),
"writing %wu byte into a region "
"of size between %wu and %wu",
@@ -2170,13 +2173,13 @@ strlen_pass::maybe_warn_overflow (gimple *stmt, bool
call_lhs, tree len,
}
else if (spcrng[0] == spcrng[1])
warned = (writefn
- ? warning_at (loc, OPT_Wstringop_overflow_,
+ ? warning_at (&richloc, OPT_Wstringop_overflow_,
"%qD writing between %wu and %wu bytes "
"into a region of size %wu",
writefn, lenrng[0].to_uhwi (),
lenrng[1].to_uhwi (),
spcrng[0].to_uhwi ())
- : warning_at (loc, OPT_Wstringop_overflow_,
+ : warning_at (&richloc, OPT_Wstringop_overflow_,
"writing between %wu and %wu bytes "
"into a region of size %wu",
lenrng[0].to_uhwi (),
@@ -2184,13 +2187,13 @@ strlen_pass::maybe_warn_overflow (gimple *stmt, bool
call_lhs, tree len,
spcrng[0].to_uhwi ()));
else
warned = (writefn
- ? warning_at (loc, OPT_Wstringop_overflow_,
+ ? warning_at (&richloc, OPT_Wstringop_overflow_,
"%qD writing between %wu and %wu bytes "
"into a region of size between %wu and %wu",
writefn, lenrng[0].to_uhwi (),
lenrng[1].to_uhwi (),
spcrng[0].to_uhwi (), spcrng[1].to_uhwi ())
- : warning_at (loc, OPT_Wstringop_overflow_,
+ : warning_at (&richloc, OPT_Wstringop_overflow_,
"writing between %wu and %wu bytes "
"into a region of size between %wu and %wu",
lenrng[0].to_uhwi (),
Any idea? Thanks!
-Kees
[1] https://github.com/KSPP/linux/issues/311
--
Kees Cook