https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80074
Martin Sebor <msebor at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Keywords| |diagnostic
Status|UNCONFIRMED |ASSIGNED
Last reconfirmed| |2017-03-16
Assignee|unassigned at gcc dot gnu.org |msebor at gcc dot
gnu.org
Target Milestone|--- |8.0
Ever confirmed|0 |1
--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
The root cause is that the maybe_emit_sprintf_chk_warning function in
builtins.c uses c_strlen() to compute the length of the string argument to the
"%s" directive. The function should instead leave the length computation to
the check_sizes() function which has the smarts to figure out the (minimum)
length even from a non-literal argument.
The following untested patch makes this change and allows the test case to be
diagnosed.
@ -9734,33 +9793,26 @@ maybe_emit_sprintf_chk_warning (tree exp, enum
built_in_function fcode)
if (!init_target_chars ())
return;
+ tree arg;
/* If the format doesn't contain % args or %%, we know its size. */
if (strchr (fmt_str, target_percent) == 0)
- len = build_int_cstu (size_type_node, strlen (fmt_str));
+ arg = build_int_cstu (size_type_node, strlen (fmt_str));
/* If the format is "%s" and first ... argument is a string literal,
we know it too. */
else if (fcode == BUILT_IN_SPRINTF_CHK
&& strcmp (fmt_str, target_percent_s) == 0)
{
- tree arg;
-
if (nargs < 5)
return;
arg = CALL_EXPR_ARG (exp, 4);
if (! POINTER_TYPE_P (TREE_TYPE (arg)))
return;
-
- len = c_strlen (arg, 1);
- if (!len || ! tree_fits_uhwi_p (len))
- return;
}
else
return;
- /* Add one for the terminating nul. */
- len = fold_build2 (PLUS_EXPR, TREE_TYPE (len), len, size_one_node);
check_sizes (OPT_Wstringop_overflow_,
- exp, /*size=*/NULL_TREE, /*maxlen=*/NULL_TREE, len, size);
+ exp, /*size=*/NULL_TREE, /*maxlen=*/NULL_TREE, arg, size);
}
/* Emit warning if a free is called with address of a variable. */