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. */