On 3/16/20 3:41 PM, Jeff Law wrote:
On Mon, 2020-03-16 at 11:39 -0600, Martin Sebor via Gcc-patches wrote:
Ping: https://gcc.gnu.org/pipermail/gcc-patches/2020-March/541521.html
I think Jakub indicated the test was incorrect. Please resolve that issue and
repost. I think the core patch is OK, so we just need to fixup the test.
The test is correct as is, it just doesn't exercise the fix when there's
no <alloca.h> that defines alloca as a macro (i.e., in the case that
doesn't matter). It passes either way, but it doesn't pass with Jakub's
suggestion. I didn't look into why.
Anyway, attached is an updated patch with a modified test that does
exercise the fix regardless of whether or not the system does have
an alloca macro in its <alloca.h> header.
Martin
PR middle-end/94004 - missing -Walloca on calls to alloca due to -Wno-system-headers
gcc/testsuite/ChangeLog:
PR middle-end/94004
* gcc.dg/Walloca-larger-than-3.c: New test.
* gcc.dg/Walloca-larger-than-3.h: New test header.
* gcc.dg/Wvla-larger-than-4.c: New test.
gcc/ChangeLog:
PR middle-end/94004
* gimple-ssa-warn-alloca.c (pass_walloca::execute): Issue warnings
even for alloca calls resulting from system macro expansion.
Include inlining context in all warnings.
diff --git a/gcc/gimple-ssa-warn-alloca.c b/gcc/gimple-ssa-warn-alloca.c
index dfe40c9c02a..9e80e5dbbd9 100644
--- a/gcc/gimple-ssa-warn-alloca.c
+++ b/gcc/gimple-ssa-warn-alloca.c
@@ -510,11 +510,12 @@ pass_walloca::execute (function *fun)
gsi_next (&si))
{
gimple *stmt = gsi_stmt (si);
- location_t loc = gimple_location (stmt);
-
if (!gimple_alloca_call_p (stmt))
continue;
+ location_t loc = gimple_nonartificial_location (stmt);
+ loc = expansion_point_location_if_in_system_header (loc);
+
const bool is_vla
= gimple_call_alloca_for_var_p (as_a <gcall *> (stmt));
@@ -528,7 +529,7 @@ pass_walloca::execute (function *fun)
}
else if (warn_alloca)
{
- warning_at (loc, OPT_Walloca, "use of %<alloca%>");
+ warning_at (loc, OPT_Walloca, "%Guse of %<alloca%>", stmt);
continue;
}
else if (warn_alloca_limit < 0)
@@ -564,10 +565,12 @@ pass_walloca::execute (function *fun)
{
auto_diagnostic_group d;
if (warning_at (loc, wcode,
- is_vla ? G_("argument to variable-length "
- "array may be too large")
- : G_("argument to %<alloca%> may be too "
- "large"))
+ (is_vla
+ ? G_("%Gargument to variable-length "
+ "array may be too large")
+ : G_("%Gargument to %<alloca%> may be too "
+ "large")),
+ stmt)
&& t.limit != 0)
{
print_decu (t.limit, buff);
@@ -582,47 +585,57 @@ pass_walloca::execute (function *fun)
{
auto_diagnostic_group d;
if (warning_at (loc, wcode,
- is_vla ? G_("argument to variable-length"
- " array is too large")
- : G_("argument to %<alloca%> is too large"))
+ (is_vla
+ ? G_("%Gargument to variable-length"
+ " array is too large")
+ : G_("%Gargument to %<alloca%> is too large")),
+ stmt)
&& t.limit != 0)
{
print_decu (t.limit, buff);
inform (loc, "limit is %wu bytes, but argument is %s",
- is_vla ? warn_vla_limit : adjusted_alloca_limit,
- buff);
+ is_vla ? warn_vla_limit : adjusted_alloca_limit,
+ buff);
}
}
break;
case ALLOCA_BOUND_UNKNOWN:
warning_at (loc, wcode,
- is_vla ? G_("variable-length array bound is unknown")
- : G_("%<alloca%> bound is unknown"));
+ (is_vla
+ ? G_("%Gvariable-length array bound is unknown")
+ : G_("%G%<alloca%> bound is unknown")),
+ stmt);
break;
case ALLOCA_UNBOUNDED:
warning_at (loc, wcode,
- is_vla ? G_("unbounded use of variable-length array")
- : G_("unbounded use of %<alloca%>"));
+ (is_vla
+ ? G_("%Gunbounded use of variable-length array")
+ : G_("%Gunbounded use of %<alloca%>")),
+ stmt);
break;
case ALLOCA_IN_LOOP:
gcc_assert (!is_vla);
- warning_at (loc, wcode, "use of %<alloca%> within a loop");
+ warning_at (loc, wcode,
+ "%Guse of %<alloca%> within a loop", stmt);
break;
case ALLOCA_CAST_FROM_SIGNED:
gcc_assert (invalid_casted_type != NULL_TREE);
warning_at (loc, wcode,
- is_vla ? G_("argument to variable-length array "
- "may be too large due to "
- "conversion from %qT to %qT")
- : G_("argument to %<alloca%> may be too large "
- "due to conversion from %qT to %qT"),
- invalid_casted_type, size_type_node);
+ (is_vla
+ ? G_("%Gargument to variable-length array "
+ "may be too large due to "
+ "conversion from %qT to %qT")
+ : G_("%Gargument to %<alloca%> may be too large "
+ "due to conversion from %qT to %qT")),
+ stmt, invalid_casted_type, size_type_node);
break;
case ALLOCA_ARG_IS_ZERO:
warning_at (loc, wcode,
- is_vla ? G_("argument to variable-length array "
- "is zero")
- : G_("argument to %<alloca%> is zero"));
+ (is_vla
+ ? G_("%Gargument to variable-length array "
+ "is zero")
+ : G_("%Gargument to %<alloca%> is zero")),
+ stmt);
break;
default:
gcc_unreachable ();
diff --git a/gcc/testsuite/gcc.dg/Walloca-larger-than-3.c b/gcc/testsuite/gcc.dg/Walloca-larger-than-3.c
new file mode 100644
index 00000000000..6f8ede04c7d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloca-larger-than-3.c
@@ -0,0 +1,38 @@
+/* PR middle-end/94004 - missing -Walloca on calls to alloca due
+ to -Wno-system-headers
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Walloca-larger-than=8 -ftrack-macro-expansion=0" }
+ { dg-require-effective-target alloca } */
+
+#include "Walloca-larger-than-3.h"
+
+void sink (void*, ...);
+
+void call_builtin_alloca (int n)
+{
+ if (n < 9)
+ n = 9;
+ void *p = __builtin_alloca (n); // { dg-warning "\\\[-Walloca-larger-than" }
+ sink (p, 0);
+}
+
+void call_alloca_sys_hdr (int n)
+{
+ if (n < 9)
+ n = 9;
+ void *p = alloca (n); // { dg-warning "\\\[-Walloca-larger-than" }
+ sink (p, 1);
+}
+
+static inline void inline_call_alloca (int n)
+{
+ if (n > 9)
+ n = 9;
+ void *p = alloca (n); // { dg-warning "\\\[-Walloca-larger-than" }
+ sink (p, 2);
+}
+
+void make_inlined_call (void)
+{
+ inline_call_alloca (10);
+}
diff --git a/gcc/testsuite/gcc.dg/Walloca-larger-than-3.h b/gcc/testsuite/gcc.dg/Walloca-larger-than-3.h
new file mode 100644
index 00000000000..ca5a84cff4f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walloca-larger-than-3.h
@@ -0,0 +1,9 @@
+#if __has_include (<alloca.h>)
+# include <alloca.h>
+#endif
+
+#ifndef alloca
+ /* Simulate a definition in a system header. */
+# pragma GCC system_header
+# define alloca(n) __builtin_alloca (n)
+#endif
diff --git a/gcc/testsuite/gcc.dg/Wvla-larger-than-4.c b/gcc/testsuite/gcc.dg/Wvla-larger-than-4.c
new file mode 100644
index 00000000000..de99afbe56e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wvla-larger-than-4.c
@@ -0,0 +1,30 @@
+/* PR middle-end/94004 - missing -Walloca on calls to alloca due
+ to -Wno-system-headers
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wvla-larger-than=31 -ftrack-macro-expansion=0" }
+ { dg-require-effective-target alloca } */
+
+void sink (void*, ...);
+
+static inline void inline_use_vla (unsigned n)
+{
+ if (n > 32)
+ n = 32;
+ char a[n]; // { dg-warning "\\\[-Wvla-larger-than" }
+ sink (a, 2);
+}
+
+static inline void use_inlined_vla (unsigned n)
+{
+ inline_use_vla (n); // this call is okay
+ inline_use_vla (n + 1); // this one is not
+}
+
+void call_inline (void)
+{
+ use_inlined_vla (31);
+}
+
+/* Verify that the inlining context is included and that it points
+ to the correct line number in the inlined function:
+ { dg-message "function 'inline_use_vla'..*inlined from 'call_inline' .*:20:" "" { target *-*-* } 0 } */