PR tree-optimization/83431 - -Wformat-truncation may incorrectly report truncation

gcc/ChangeLog:

	PR c++/83431
	* gimple-ssa-sprintf.c (pass_data_sprintf_length): Remove object.
	(sprintf_dom_walker): Remove class.
	(get_int_range): Make argument const.
	(directive::fmtfunc, directive::set_precision): Same.
	(format_none): Same.
	(build_intmax_type_nodes): Same.
	(adjust_range_for_overflow): Same.
	(format_floating): Same.
	(format_character): Same.
	(format_string): Same.
	(format_plain): Same.
	(get_int_range): Cast away constness.
	(format_integer): Same.
	(get_string_length): Call get_range_strlen_dynamic.  Handle
	null lendata.maxbound.
	(should_warn_p): Adjust argument scope qualifier.
	(maybe_warn): Same.
	(format_directive): Same.
	(parse_directive): Same.
	(is_call_safe): Same.
	(try_substitute_return_value): Same.
	(sprintf_dom_walker::handle_printf_call): Rename...
	(handle_printf_call): ...to this.  Initialize target to host charmap
	here instead of in pass_sprintf_length::execute.
	(struct call_info): Make global.
	(sprintf_dom_walker::compute_format_length): Make global.
	(sprintf_dom_walker::handle_gimple_call): Same.
	* passes.def (pass_sprintf_length): Replace with pass_strlen.
	* print-rtl.c (print_pattern): Reduce the number of spaces to
	avoid -Wformat-truncation.
	* tree-pass.h (make_pass_warn_printf): New function.
	* tree-ssa-strlen.c (strlen_optimize): New variable.
	(get_string_length): Add comments.
	(get_range_strlen_dynamic): New function.
	(check_and_optimize_call): New function.
	(handle_integral_assign): New function.
	(strlen_check_and_optimize_stmt): Factor code out into
	strlen_check_and_optimize_call and handle_integral_assign.
	(strlen_dom_walker::evrp): New member.
	(strlen_dom_walker::before_dom_children): Use evrp member.
	(strlen_dom_walker::after_dom_children): Use evrp member.
	(printf_strlen_execute): New function.
	(pass_strlen::gate): Update to handle printf calls.
	(dump_strlen_info): New function.
	(pass_data_warn_printf): New variable.
	(pass_warn_printf): New class.
	* tree-ssa-strlen.h (get_range_strlen_dynamic): Declare.
	(handle_printf_call): Same.
	* tree-vrp.c (value_range_base::type): Adjust assertion.
	* vr-values.c (vr_values::update_value_range): Use type of the first
	argument rather than the second.

gcc/testsuite/ChangeLog:

	PR c++/83431
	* gcc.dg/strlenopt-63.c: New test.
	* gcc.dg/pr79538.c: Adjust text of expected warning.
	* gcc.dg/pr81292-1.c: Adjust pass name.
	* gcc.dg/pr81292-2.c: Same.
	* gcc.dg/pr81703.c: Same.
	* gcc.dg/strcmpopt_2.c: Same.
	* gcc.dg/strcmpopt_3.c: Same.
	* gcc.dg/strcmpopt_4.c: Same.
	* gcc.dg/strlenopt-1.c: Same.
	* gcc.dg/strlenopt-10.c: Same.
	* gcc.dg/strlenopt-11.c: Same.
	* gcc.dg/strlenopt-13.c: Same.
	* gcc.dg/strlenopt-14g.c: Same.
	* gcc.dg/strlenopt-14gf.c: Same.
	* gcc.dg/strlenopt-15.c: Same.
	* gcc.dg/strlenopt-16g.c: Same.
	* gcc.dg/strlenopt-17g.c: Same.
	* gcc.dg/strlenopt-18g.c: Same.
	* gcc.dg/strlenopt-19.c: Same.
	* gcc.dg/strlenopt-1f.c: Same.
	* gcc.dg/strlenopt-2.c: Same.
	* gcc.dg/strlenopt-20.c: Same.
	* gcc.dg/strlenopt-21.c: Same.
	* gcc.dg/strlenopt-22.c: Same.
	* gcc.dg/strlenopt-22g.c: Same.
	* gcc.dg/strlenopt-24.c: Same.
	* gcc.dg/strlenopt-25.c: Same.
	* gcc.dg/strlenopt-26.c: Same.
	* gcc.dg/strlenopt-27.c: Same.
	* gcc.dg/strlenopt-28.c: Same.
	* gcc.dg/strlenopt-29.c: Same.
	* gcc.dg/strlenopt-2f.c: Same.
	* gcc.dg/strlenopt-3.c: Same.
	* gcc.dg/strlenopt-30.c: Same.
	* gcc.dg/strlenopt-31g.c: Same.
	* gcc.dg/strlenopt-32.c: Same.
	* gcc.dg/strlenopt-33.c: Same.
	* gcc.dg/strlenopt-33g.c: Same.
	* gcc.dg/strlenopt-34.c: Same.
	* gcc.dg/strlenopt-35.c: Same.
	* gcc.dg/strlenopt-4.c: Same.
	* gcc.dg/strlenopt-48.c: Same.
	* gcc.dg/strlenopt-49.c: Same.
	* gcc.dg/strlenopt-4g.c: Same.
	* gcc.dg/strlenopt-4gf.c: Same.
	* gcc.dg/strlenopt-5.c: Same.
	* gcc.dg/strlenopt-50.c: Same.
	* gcc.dg/strlenopt-51.c: Same.
	* gcc.dg/strlenopt-52.c: Same.
	* gcc.dg/strlenopt-53.c: Same.
	* gcc.dg/strlenopt-54.c: Same.
	* gcc.dg/strlenopt-55.c: Same.
	* gcc.dg/strlenopt-56.c: Same.
	* gcc.dg/strlenopt-6.c: Same.
	* gcc.dg/strlenopt-61.c: Same.
	* gcc.dg/strlenopt-7.c: Same.
	* gcc.dg/strlenopt-8.c: Same.
	* gcc.dg/strlenopt-9.c: Same.
	* gcc.dg/strlenopt.h (snprintf, snprintf): Declare.
	* gcc.dg/tree-ssa/builtin-snprintf-6.c: New test.
	* gcc.dg/tree-ssa/builtin-snprintf-7.c: New test.
	* gcc.dg/tree-ssa/builtin-snprintf-8.c: New test.
	* gcc.dg/tree-ssa/builtin-snprintf-9.c: New test.
	* gcc.dg/tree-ssa/builtin-sprintf-warn-21.c: New test.
	* gcc.dg/tree-ssa/dump-4.c: New test.
	* gcc.dg/tree-ssa/pr83501.c: Adjust pass name.

From-SVN: r274933
This commit is contained in:
Martin Sebor 2019-08-26 18:29:45 +00:00 committed by Martin Sebor
parent 59bce4ad03
commit 22fca489ea
77 changed files with 2264 additions and 631 deletions

View File

@ -1,3 +1,58 @@
2019-08-23 Martin Sebor <msebor@redhat.com>
PR c++/83431
* gimple-ssa-sprintf.c (pass_data_sprintf_length): Remove object.
(sprintf_dom_walker): Remove class.
(get_int_range): Make argument const.
(directive::fmtfunc, directive::set_precision): Same.
(format_none): Same.
(build_intmax_type_nodes): Same.
(adjust_range_for_overflow): Same.
(format_floating): Same.
(format_character): Same.
(format_string): Same.
(format_plain): Same.
(get_int_range): Cast away constness.
(format_integer): Same.
(get_string_length): Call get_range_strlen_dynamic. Handle
null lendata.maxbound.
(should_warn_p): Adjust argument scope qualifier.
(maybe_warn): Same.
(format_directive): Same.
(parse_directive): Same.
(is_call_safe): Same.
(try_substitute_return_value): Same.
(sprintf_dom_walker::handle_printf_call): Rename...
(handle_printf_call): ...to this. Initialize target to host charmap
here instead of in pass_sprintf_length::execute.
(struct call_info): Make global.
(sprintf_dom_walker::compute_format_length): Make global.
(sprintf_dom_walker::handle_gimple_call): Same.
* passes.def (pass_sprintf_length): Replace with pass_strlen.
* print-rtl.c (print_pattern): Reduce the number of spaces to
avoid -Wformat-truncation.
* tree-pass.h (make_pass_warn_printf): New function.
* tree-ssa-strlen.c (strlen_optimize): New variable.
(get_string_length): Add comments.
(get_range_strlen_dynamic): New function.
(check_and_optimize_call): New function.
(handle_integral_assign): New function.
(strlen_check_and_optimize_stmt): Factor code out into
strlen_check_and_optimize_call and handle_integral_assign.
(strlen_dom_walker::evrp): New member.
(strlen_dom_walker::before_dom_children): Use evrp member.
(strlen_dom_walker::after_dom_children): Use evrp member.
(printf_strlen_execute): New function.
(pass_strlen::gate): Update to handle printf calls.
(dump_strlen_info): New function.
(pass_data_warn_printf): New variable.
(pass_warn_printf): New class.
* tree-ssa-strlen.h (get_range_strlen_dynamic): Declare.
(handle_printf_call): Same.
* tree-vrp.c (value_range_base::type): Adjust assertion.
* vr-values.c (vr_values::update_value_range): Use type of the first
argument rather than the second.
2019-08-26 Richard Biener <rguenther@suse.de>
* config/i386/i386-features.c (general_remove_non_convertible_regs):

View File

@ -85,7 +85,7 @@ along with GCC; see the file COPYING3. If not see
#include "domwalk.h"
#include "alloc-pool.h"
#include "vr-values.h"
#include "gimple-ssa-evrp-analyze.h"
#include "tree-ssa-strlen.h"
/* The likely worst case value of MB_LEN_MAX for the target, large enough
for UTF-8. Ideally, this would be obtained by a target hook if it were
@ -100,80 +100,15 @@ along with GCC; see the file COPYING3. If not see
namespace {
const pass_data pass_data_sprintf_length = {
GIMPLE_PASS, // pass type
"printf-return-value", // pass name
OPTGROUP_NONE, // optinfo_flags
TV_NONE, // tv_id
PROP_cfg, // properties_required
0, // properties_provided
0, // properties_destroyed
0, // properties_start
0, // properties_finish
};
/* Set to the warning level for the current function which is equal
either to warn_format_trunc for bounded functions or to
warn_format_overflow otherwise. */
static int warn_level;
struct call_info;
struct format_result;
class sprintf_dom_walker : public dom_walker
{
public:
sprintf_dom_walker ()
: dom_walker (CDI_DOMINATORS),
evrp_range_analyzer (false) {}
~sprintf_dom_walker () {}
edge before_dom_children (basic_block) FINAL OVERRIDE;
void after_dom_children (basic_block) FINAL OVERRIDE;
bool handle_gimple_call (gimple_stmt_iterator *);
struct call_info;
bool compute_format_length (call_info &, format_result *);
class evrp_range_analyzer evrp_range_analyzer;
};
class pass_sprintf_length : public gimple_opt_pass
{
bool fold_return_value;
public:
pass_sprintf_length (gcc::context *ctxt)
: gimple_opt_pass (pass_data_sprintf_length, ctxt),
fold_return_value (false)
{ }
opt_pass * clone () { return new pass_sprintf_length (m_ctxt); }
virtual bool gate (function *);
virtual unsigned int execute (function *);
void set_pass_param (unsigned int n, bool param)
{
gcc_assert (n == 0);
fold_return_value = param;
}
};
bool
pass_sprintf_length::gate (function *)
{
/* Run the pass iff -Warn-format-overflow or -Warn-format-truncation
is specified and either not optimizing and the pass is being invoked
early, or when optimizing and the pass is being invoked during
optimization (i.e., "late"). */
return ((warn_format_overflow > 0
|| warn_format_trunc > 0
|| flag_printf_return_value)
&& (optimize > 0) == fold_return_value);
}
/* The minimum, maximum, likely, and unlikely maximum number of bytes
of output either a formatting function or an individual directive
can result in. */
@ -684,7 +619,7 @@ fmtresult::type_max_digits (tree type, int base)
static bool
get_int_range (tree, HOST_WIDE_INT *, HOST_WIDE_INT *, bool, HOST_WIDE_INT,
class vr_values *vr_values);
const vr_values *);
/* Description of a format directive. A directive is either a plain
string or a conversion specification that starts with '%'. */
@ -719,7 +654,7 @@ struct directive
/* Format conversion function that given a directive and an argument
returns the formatting result. */
fmtresult (*fmtfunc) (const directive &, tree, vr_values *);
fmtresult (*fmtfunc) (const directive &, tree, const vr_values *);
/* Return True when a the format flag CHR has been used. */
bool get_flag (char chr) const
@ -756,9 +691,9 @@ struct directive
or 0, whichever is greater. For a non-constant ARG in some range
set width to its range adjusting each bound to -1 if it's less.
For an indeterminate ARG set width to [0, INT_MAX]. */
void set_width (tree arg, vr_values *vr_values)
void set_width (tree arg, const vr_values *vr)
{
get_int_range (arg, width, width + 1, true, 0, vr_values);
get_int_range (arg, width, width + 1, true, 0, vr);
}
/* Set both bounds of the precision range to VAL. */
@ -772,9 +707,9 @@ struct directive
or -1 whichever is greater. For a non-constant ARG in some range
set precision to its range adjusting each bound to -1 if it's less.
For an indeterminate ARG set precision to [-1, INT_MAX]. */
void set_precision (tree arg, vr_values *vr_values)
void set_precision (tree arg, const vr_values *vr)
{
get_int_range (arg, prec, prec + 1, false, -1, vr_values);
get_int_range (arg, prec, prec + 1, false, -1, vr);
}
/* Return true if both width and precision are known to be
@ -904,7 +839,7 @@ bytes_remaining (unsigned HOST_WIDE_INT navail, const format_result &res)
/* Description of a call to a formatted function. */
struct sprintf_dom_walker::call_info
struct call_info
{
/* Function call statement. */
gimple *callstmt;
@ -978,7 +913,7 @@ struct sprintf_dom_walker::call_info
/* Return the result of formatting a no-op directive (such as '%n'). */
static fmtresult
format_none (const directive &, tree, vr_values *)
format_none (const directive &, tree, const vr_values *)
{
fmtresult res (0);
return res;
@ -987,7 +922,7 @@ format_none (const directive &, tree, vr_values *)
/* Return the result of formatting the '%%' directive. */
static fmtresult
format_percent (const directive &, tree, vr_values *)
format_percent (const directive &, tree, const vr_values *)
{
fmtresult res (1);
return res;
@ -1047,7 +982,7 @@ build_intmax_type_nodes (tree *pintmax, tree *puintmax)
static bool
get_int_range (tree arg, HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax,
bool absolute, HOST_WIDE_INT negbound,
class vr_values *vr_values)
const class vr_values *vr_values)
{
/* The type of the result. */
const_tree type = integer_type_node;
@ -1086,7 +1021,9 @@ get_int_range (tree arg, HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax,
&& TYPE_PRECISION (argtype) <= TYPE_PRECISION (type))
{
/* Try to determine the range of values of the integer argument. */
const value_range *vr = vr_values->get_value_range (arg);
const value_range *vr
= CONST_CAST (class vr_values *, vr_values)->get_value_range (arg);
if (range_int_cst_p (vr))
{
HOST_WIDE_INT type_min
@ -1203,7 +1140,7 @@ adjust_range_for_overflow (tree dirtype, tree *argmin, tree *argmax)
used when the directive argument or its value isn't known. */
static fmtresult
format_integer (const directive &dir, tree arg, vr_values *vr_values)
format_integer (const directive &dir, tree arg, const vr_values *vr_values)
{
tree intmax_type_node;
tree uintmax_type_node;
@ -1386,7 +1323,9 @@ format_integer (const directive &dir, tree arg, vr_values *vr_values)
{
/* Try to determine the range of values of the integer argument
(range information is not available for pointers). */
const value_range *vr = vr_values->get_value_range (arg);
const value_range *vr
= CONST_CAST (class vr_values *, vr_values)->get_value_range (arg);
if (range_int_cst_p (vr))
{
argmin = vr->min ();
@ -1836,7 +1775,7 @@ format_floating (const directive &dir, const HOST_WIDE_INT prec[2])
ARG. */
static fmtresult
format_floating (const directive &dir, tree arg, vr_values *)
format_floating (const directive &dir, tree arg, const vr_values *)
{
HOST_WIDE_INT prec[] = { dir.prec[0], dir.prec[1] };
tree type = (dir.modifier == FMT_LEN_L || dir.modifier == FMT_LEN_ll
@ -2030,21 +1969,33 @@ format_floating (const directive &dir, tree arg, vr_values *)
Used by the format_string function below. */
static fmtresult
get_string_length (tree str, unsigned eltsize)
get_string_length (tree str, unsigned eltsize, const vr_values *vr)
{
if (!str)
return fmtresult ();
/* Determine the length of the shortest and longest string referenced
by STR. Strings of unknown lengths are bounded by the sizes of
arrays that subexpressions of STR may refer to. Pointers that
aren't known to point any such arrays result in LENDATA.MAXLEN
set to SIZE_MAX. */
/* Try to determine the dynamic string length first. */
c_strlen_data lendata = { };
get_range_strlen (str, &lendata, eltsize);
if (eltsize == 1)
get_range_strlen_dynamic (str, &lendata, vr);
else
{
/* Determine the length of the shortest and longest string referenced
by STR. Strings of unknown lengths are bounded by the sizes of
arrays that subexpressions of STR may refer to. Pointers that
aren't known to point any such arrays result in LENDATA.MAXLEN
set to SIZE_MAX. */
get_range_strlen (str, &lendata, eltsize);
}
/* Return the default result when nothing is known about the string. */
if (integer_all_onesp (lendata.maxbound)
/* LENDATA.MAXBOUND is null when LENDATA.MIN corresponds to the shortest
string referenced by STR. Otherwise, if it's not equal to .MINLEN it
corresponds to the bound of the largest array STR refers to, if known,
or it's SIZE_MAX otherwise. */
/* Return the default result when nothing is known about the string. */
if (lendata.maxbound
&& integer_all_onesp (lendata.maxbound)
&& integer_all_onesp (lendata.maxlen))
return fmtresult ();
@ -2054,7 +2005,7 @@ get_string_length (tree str, unsigned eltsize)
: 0);
HOST_WIDE_INT max
= (tree_fits_uhwi_p (lendata.maxbound)
= (lendata.maxbound && tree_fits_uhwi_p (lendata.maxbound)
? tree_to_uhwi (lendata.maxbound)
: HOST_WIDE_INT_M1U);
@ -2093,10 +2044,11 @@ get_string_length (tree str, unsigned eltsize)
else
{
/* When the upper bound is unknown (it can be zero or excessive)
set the likely length to the greater of 1 and the length of
the shortest string and reset the lower bound to zero. */
set the likely length to the greater of 1. If MAXBOUND is
set, also reset the length of the lower bound to zero. */
res.range.likely = res.range.min ? res.range.min : warn_level > 1;
res.range.min = 0;
if (lendata.maxbound)
res.range.min = 0;
}
res.range.unlikely = unbounded ? HOST_WIDE_INT_MAX : res.range.max;
@ -2110,7 +2062,7 @@ get_string_length (tree str, unsigned eltsize)
vsprinf). */
static fmtresult
format_character (const directive &dir, tree arg, vr_values *vr_values)
format_character (const directive &dir, tree arg, const vr_values *vr_values)
{
fmtresult res;
@ -2186,7 +2138,7 @@ format_character (const directive &dir, tree arg, vr_values *vr_values)
vsprinf). */
static fmtresult
format_string (const directive &dir, tree arg, vr_values *)
format_string (const directive &dir, tree arg, const vr_values *vr_values)
{
fmtresult res;
@ -2204,7 +2156,7 @@ format_string (const directive &dir, tree arg, vr_values *)
gcc_checking_assert (count_by == 2 || count_by == 4);
}
fmtresult slen = get_string_length (arg, count_by);
fmtresult slen = get_string_length (arg, count_by, vr_values);
if (slen.range.min == slen.range.max
&& slen.range.min < HOST_WIDE_INT_MAX)
{
@ -2376,7 +2328,7 @@ format_string (const directive &dir, tree arg, vr_values *)
/* Format plain string (part of the format string itself). */
static fmtresult
format_plain (const directive &dir, tree, vr_values *)
format_plain (const directive &dir, tree, const vr_values *)
{
fmtresult res (dir.len);
return res;
@ -2386,7 +2338,7 @@ format_plain (const directive &dir, tree, vr_values *)
should be diagnosed given the AVAILable space in the destination. */
static bool
should_warn_p (const sprintf_dom_walker::call_info &info,
should_warn_p (const call_info &info,
const result_range &avail, const result_range &result)
{
if (result.max <= avail.min)
@ -2457,7 +2409,7 @@ should_warn_p (const sprintf_dom_walker::call_info &info,
static bool
maybe_warn (substring_loc &dirloc, location_t argloc,
const sprintf_dom_walker::call_info &info,
const call_info &info,
const result_range &avail_range, const result_range &res,
const directive &dir)
{
@ -2737,9 +2689,9 @@ maybe_warn (substring_loc &dirloc, location_t argloc,
in *RES. Return true if the directive has been handled. */
static bool
format_directive (const sprintf_dom_walker::call_info &info,
format_directive (const call_info &info,
format_result *res, const directive &dir,
class vr_values *vr_values)
const class vr_values *vr_values)
{
/* Offset of the beginning of the directive from the beginning
of the format string. */
@ -3086,10 +3038,10 @@ format_directive (const sprintf_dom_walker::call_info &info,
the directive. */
static size_t
parse_directive (sprintf_dom_walker::call_info &info,
parse_directive (call_info &info,
directive &dir, format_result *res,
const char *str, unsigned *argno,
vr_values *vr_values)
const vr_values *vr_values)
{
const char *pcnt = strchr (str, target_percent);
dir.beg = str;
@ -3526,9 +3478,8 @@ parse_directive (sprintf_dom_walker::call_info &info,
on, false otherwise (e.g., when a unknown or unhandled directive was seen
that caused the processing to be terminated early). */
bool
sprintf_dom_walker::compute_format_length (call_info &info,
format_result *res)
static bool
compute_format_length (call_info &info, format_result *res, const vr_values *vr)
{
if (dump_file)
{
@ -3564,12 +3515,10 @@ sprintf_dom_walker::compute_format_length (call_info &info,
directive dir = directive ();
dir.dirno = dirno;
size_t n = parse_directive (info, dir, res, pf, &argno,
evrp_range_analyzer.get_vr_values ());
size_t n = parse_directive (info, dir, res, pf, &argno, vr);
/* Return failure if the format function fails. */
if (!format_directive (info, res, dir,
evrp_range_analyzer.get_vr_values ()))
if (!format_directive (info, res, dir, vr))
return false;
/* Return success the directive is zero bytes long and it's
@ -3617,7 +3566,7 @@ get_destination_size (tree dest)
of its return values. */
static bool
is_call_safe (const sprintf_dom_walker::call_info &info,
is_call_safe (const call_info &info,
const format_result &res, bool under4k,
unsigned HOST_WIDE_INT retval[2])
{
@ -3676,7 +3625,7 @@ is_call_safe (const sprintf_dom_walker::call_info &info,
static bool
try_substitute_return_value (gimple_stmt_iterator *gsi,
const sprintf_dom_walker::call_info &info,
const call_info &info,
const format_result &res)
{
tree lhs = gimple_get_lhs (info.callstmt);
@ -3794,7 +3743,7 @@ try_substitute_return_value (gimple_stmt_iterator *gsi,
static bool
try_simplify_call (gimple_stmt_iterator *gsi,
const sprintf_dom_walker::call_info &info,
const call_info &info,
const format_result &res)
{
unsigned HOST_WIDE_INT dummy[2];
@ -3847,13 +3796,17 @@ get_user_idx_format (tree fndecl, unsigned *idx_args)
return tree_to_uhwi (fmtarg) - 1;
}
/* Determine if a GIMPLE CALL is to one of the sprintf-like built-in
functions and if so, handle it. Return true if the call is removed
and gsi_next should not be performed in the caller. */
} /* Unnamed namespace. */
/* Determine if a GIMPLE call at *GSI is to one of the sprintf-like built-in
functions and if so, handle it. Return true if the call is removed and
gsi_next should not be performed in the caller. */
bool
sprintf_dom_walker::handle_gimple_call (gimple_stmt_iterator *gsi)
handle_printf_call (gimple_stmt_iterator *gsi, const vr_values *vr_values)
{
init_target_to_host_charmap ();
call_info info = call_info ();
info.callstmt = gsi_stmt (*gsi);
@ -4119,7 +4072,9 @@ sprintf_dom_walker::handle_gimple_call (gimple_stmt_iterator *gsi)
/* Try to determine the range of values of the argument
and use the greater of the two at level 1 and the smaller
of them at level 2. */
const value_range *vr = evrp_range_analyzer.get_value_range (size);
const value_range *vr
= CONST_CAST (class vr_values *, vr_values)->get_value_range (size);
if (range_int_cst_p (vr))
{
unsigned HOST_WIDE_INT minsize = TREE_INT_CST_LOW (vr->min ());
@ -4230,7 +4185,7 @@ sprintf_dom_walker::handle_gimple_call (gimple_stmt_iterator *gsi)
never set to true again). */
res.posunder4k = posunder4k && dstptr;
bool success = compute_format_length (info, &res);
bool success = compute_format_length (info, &res, vr_values);
if (res.warned)
gimple_set_no_warning (info.callstmt, true);
@ -4256,71 +4211,3 @@ sprintf_dom_walker::handle_gimple_call (gimple_stmt_iterator *gsi)
return call_removed;
}
edge
sprintf_dom_walker::before_dom_children (basic_block bb)
{
evrp_range_analyzer.enter (bb);
for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si); )
{
/* Iterate over statements, looking for function calls. */
gimple *stmt = gsi_stmt (si);
/* First record ranges generated by this statement. */
evrp_range_analyzer.record_ranges_from_stmt (stmt, false);
if (is_gimple_call (stmt) && handle_gimple_call (&si))
/* If handle_gimple_call returns true, the iterator is
already pointing to the next statement. */
continue;
gsi_next (&si);
}
return NULL;
}
void
sprintf_dom_walker::after_dom_children (basic_block bb)
{
evrp_range_analyzer.leave (bb);
}
/* Execute the pass for function FUN. */
unsigned int
pass_sprintf_length::execute (function *fun)
{
init_target_to_host_charmap ();
calculate_dominance_info (CDI_DOMINATORS);
bool use_scev = optimize > 0 && flag_printf_return_value;
if (use_scev)
{
loop_optimizer_init (LOOPS_NORMAL);
scev_initialize ();
}
sprintf_dom_walker sprintf_dom_walker;
sprintf_dom_walker.walk (ENTRY_BLOCK_PTR_FOR_FN (fun));
if (use_scev)
{
scev_finalize ();
loop_optimizer_finalize ();
}
/* Clean up object size info. */
fini_object_sizes ();
return 0;
}
} /* Unnamed namespace. */
/* Return a pointer to a pass object newly constructed from the context
CTXT. */
gimple_opt_pass *
make_pass_sprintf_length (gcc::context *ctxt)
{
return new pass_sprintf_length (ctxt);
}

View File

@ -42,7 +42,7 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_build_cfg);
NEXT_PASS (pass_warn_function_return);
NEXT_PASS (pass_expand_omp);
NEXT_PASS (pass_sprintf_length, false);
NEXT_PASS (pass_warn_printf);
NEXT_PASS (pass_walloca, /*strict_mode_p=*/true);
NEXT_PASS (pass_build_cgraph_edges);
TERMINATE_PASS_LIST (all_lowering_passes)
@ -307,7 +307,6 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_lower_vector_ssa);
NEXT_PASS (pass_lower_switch);
NEXT_PASS (pass_cse_reciprocals);
NEXT_PASS (pass_sprintf_length, true);
NEXT_PASS (pass_reassoc, false /* insert_powi_p */);
NEXT_PASS (pass_strength_reduction);
NEXT_PASS (pass_split_paths);
@ -358,7 +357,7 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_object_sizes);
/* Fold remaining builtins. */
NEXT_PASS (pass_fold_builtins);
NEXT_PASS (pass_sprintf_length, true);
NEXT_PASS (pass_strlen);
/* Copy propagation also copy-propagates constants, this is necessary
to forward object-size and builtin folding results properly. */
NEXT_PASS (pass_copy_prop);

View File

@ -1815,7 +1815,7 @@ print_pattern (pretty_printer *pp, const_rtx x, int verbose)
gcc_assert (strlen (print_rtx_head) < sizeof (indented_print_rtx_head) - 4);
snprintf (indented_print_rtx_head,
sizeof (indented_print_rtx_head),
"%s ", print_rtx_head);
"%s ", print_rtx_head);
print_rtx_head = indented_print_rtx_head;
for (int i = 0; i < seq->len (); i++)
print_insn_with_notes (pp, seq->insn (i));

View File

@ -77,6 +77,76 @@
* gcc.target/mips/get-fcsr-3.c: New test.
2019-08-23 Martin Sebor <msebor@redhat.com>
PR c++/83431
* gcc.dg/strlenopt-63.c: New test.
* gcc.dg/pr79538.c: Adjust text of expected warning.
* gcc.dg/pr81292-1.c: Adjust pass name.
* gcc.dg/pr81292-2.c: Same.
* gcc.dg/pr81703.c: Same.
* gcc.dg/strcmpopt_2.c: Same.
* gcc.dg/strcmpopt_3.c: Same.
* gcc.dg/strcmpopt_4.c: Same.
* gcc.dg/strlenopt-1.c: Same.
* gcc.dg/strlenopt-10.c: Same.
* gcc.dg/strlenopt-11.c: Same.
* gcc.dg/strlenopt-13.c: Same.
* gcc.dg/strlenopt-14g.c: Same.
* gcc.dg/strlenopt-14gf.c: Same.
* gcc.dg/strlenopt-15.c: Same.
* gcc.dg/strlenopt-16g.c: Same.
* gcc.dg/strlenopt-17g.c: Same.
* gcc.dg/strlenopt-18g.c: Same.
* gcc.dg/strlenopt-19.c: Same.
* gcc.dg/strlenopt-1f.c: Same.
* gcc.dg/strlenopt-2.c: Same.
* gcc.dg/strlenopt-20.c: Same.
* gcc.dg/strlenopt-21.c: Same.
* gcc.dg/strlenopt-22.c: Same.
* gcc.dg/strlenopt-22g.c: Same.
* gcc.dg/strlenopt-24.c: Same.
* gcc.dg/strlenopt-25.c: Same.
* gcc.dg/strlenopt-26.c: Same.
* gcc.dg/strlenopt-27.c: Same.
* gcc.dg/strlenopt-28.c: Same.
* gcc.dg/strlenopt-29.c: Same.
* gcc.dg/strlenopt-2f.c: Same.
* gcc.dg/strlenopt-3.c: Same.
* gcc.dg/strlenopt-30.c: Same.
* gcc.dg/strlenopt-31g.c: Same.
* gcc.dg/strlenopt-32.c: Same.
* gcc.dg/strlenopt-33.c: Same.
* gcc.dg/strlenopt-33g.c: Same.
* gcc.dg/strlenopt-34.c: Same.
* gcc.dg/strlenopt-35.c: Same.
* gcc.dg/strlenopt-4.c: Same.
* gcc.dg/strlenopt-48.c: Same.
* gcc.dg/strlenopt-49.c: Same.
* gcc.dg/strlenopt-4g.c: Same.
* gcc.dg/strlenopt-4gf.c: Same.
* gcc.dg/strlenopt-5.c: Same.
* gcc.dg/strlenopt-50.c: Same.
* gcc.dg/strlenopt-51.c: Same.
* gcc.dg/strlenopt-52.c: Same.
* gcc.dg/strlenopt-53.c: Same.
* gcc.dg/strlenopt-54.c: Same.
* gcc.dg/strlenopt-55.c: Same.
* gcc.dg/strlenopt-56.c: Same.
* gcc.dg/strlenopt-6.c: Same.
* gcc.dg/strlenopt-61.c: Same.
* gcc.dg/strlenopt-7.c: Same.
* gcc.dg/strlenopt-8.c: Same.
* gcc.dg/strlenopt-9.c: Same.
* gcc.dg/strlenopt.h (snprintf, snprintf): Declare.
* gcc.dg/tree-ssa/builtin-snprintf-6.c: New test.
* gcc.dg/tree-ssa/builtin-snprintf-7.c: New test.
* gcc.dg/tree-ssa/builtin-snprintf-8.c: New test.
* gcc.dg/tree-ssa/builtin-snprintf-9.c: New test.
* gcc.dg/tree-ssa/builtin-sprintf-warn-21.c: New test.
* gcc.dg/tree-ssa/dump-4.c: New test.
* gcc.dg/tree-ssa/pr83501.c: Adjust pass name.
2019-08-23 Martin Sebor <msebor@redhat.com>
* gcc.dg/Warray-bounds-36.c: Make functions static to avoid failures

View File

@ -17,6 +17,6 @@ void f ()
{
char des[3];
char src[] = "abcd";
__builtin_sprintf (des, "%s", src); /* { dg-warning "directive writing up to 4 bytes into a region of size 3" } */
__builtin_sprintf (des, "%s", src); /* { dg-warning "directive writing 4 bytes into a region of size 3" } */
return;
}

View File

@ -32,4 +32,4 @@ main (void)
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */

View File

@ -32,4 +32,4 @@ main (void)
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 6 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 6 "strlen1" } } */

View File

@ -9,4 +9,4 @@ unsigned g (void)
return __builtin_strlen (d);
}
/* { dg-final { scan-tree-dump-not "__builtin_strlen" "strlen" } } */
/* { dg-final { scan-tree-dump-not "__builtin_strlen" "strlen1" } } */

View File

@ -64,4 +64,4 @@ int main (void)
return 0;
}
/* { dg-final { scan-tree-dump-times "cmp_eq \\(" 8 "strlen" } } */
/* { dg-final { scan-tree-dump-times "cmp_eq \\(" 8 "strlen1" } } */

View File

@ -28,4 +28,4 @@ int main (void)
return 0;
}
/* { dg-final { scan-tree-dump-times "strcmp" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcmp" 0 "strlen1" } } */

View File

@ -13,4 +13,4 @@ f1 (S * s)
return result;
}
/* { dg-final { scan-tree-dump-times "cmp_eq \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "cmp_eq \\(" 1 "strlen1" } } */

View File

@ -36,9 +36,9 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */

View File

@ -69,14 +69,14 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* avr has BIGGEST_ALIGNMENT 8, allowing fold_builtin_memory_op
to expand the memcpy call at the end of fn2. */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 8 "strlen" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen" { target { avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "\\*q_\[0-9\]* = 32;" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(\[^\n\r\]*, 1\\)" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 8 "strlen1" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen1" { target { avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "\\*q_\[0-9\]* = 32;" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(\[^\n\r\]*, 1\\)" 1 "strlen1" } } */

View File

@ -58,18 +58,18 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen1" } } */
/* avr has BIGGEST_ALIGNMENT 8, allowing fold_builtin_memory_op
to expand the memcpy call at the end of fn1. */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen" { target { avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen1" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen1" { target { avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
/* Where the memcpy is expanded, the assignemts to elements of l are
propagated. */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.9. = " 1 "strlen" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;" 3 "strlen" { target { avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen1" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen1" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.9. = " 1 "strlen1" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;" 3 "strlen1" { target { avr-*-* } } } } */

View File

@ -55,19 +55,19 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen1" } } */
/* avr has BIGGEST_ALIGNMENT 8, allowing fold_builtin_memory_op
to expand the memcpy call at the end of fn1. */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen" { target { avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen1" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen1" { target { avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
/* Where the memcpy is expanded, the assignemts to elements of l are
propagated. */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.1. = " 1 "strlen" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.5. = " 1 "strlen" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;" 4 "strlen" { target { avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen1" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.1. = " 1 "strlen1" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.5. = " 1 "strlen1" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen1" { target { ! avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;" 4 "strlen1" { target { avr-*-* } } } } */

View File

@ -107,10 +107,10 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "mempcpy \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "mempcpy \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen1" } } */

View File

@ -11,15 +11,15 @@
/* Compared to strlenopt-14gf.c, strcpy_chk with string literal as
second argument isn't being optimized by builtins.c into
memcpy. */
/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__mempcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "mempcpy \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__mempcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "mempcpy \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen1" } } */

View File

@ -51,9 +51,9 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */

View File

@ -24,10 +24,10 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "mempcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "mempcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen1" } } */

View File

@ -47,10 +47,10 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 3 "strlen" } } */
/* { dg-final { scan-tree-dump-times "mempcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 3 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "mempcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen1" } } */

View File

@ -73,9 +73,9 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen1" } } */

View File

@ -72,9 +72,9 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */

View File

@ -5,13 +5,13 @@
#define FORTIFY_SOURCE 2
#include "strlenopt-1.c"
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */

View File

@ -40,9 +40,9 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 5 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 5 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */

View File

@ -86,9 +86,9 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */

View File

@ -57,9 +57,9 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 3 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 3 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */

View File

@ -31,9 +31,9 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */

View File

@ -5,9 +5,9 @@
#define USE_GNU
#include "strlenopt-22.c"
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen1" } } */

View File

@ -13,4 +13,4 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */

View File

@ -14,4 +14,4 @@ main ()
return len - len2;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */

View File

@ -20,5 +20,5 @@ main (void)
return fn1 (p, q);
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */

View File

@ -19,4 +19,4 @@ main (void)
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */

View File

@ -56,4 +56,4 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */

View File

@ -24,4 +24,4 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */

View File

@ -5,13 +5,13 @@
#define FORTIFY_SOURCE 2
#include "strlenopt-2.c"
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 5 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 5 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */

View File

@ -53,12 +53,12 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "return 0" 3 "optimized" } } */
/* { dg-final { scan-tree-dump-times "return 4" 1 "optimized" } } */
/* { dg-final { scan-tree-dump-times "return 3" 1 "optimized" } } */

View File

@ -60,4 +60,4 @@ _Bool f7(char *s)
return (t1 == s);
}
/* { dg-final { scan-tree-dump-times "__builtin_strncmp" 5 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__builtin_strncmp" 5 "strlen1" } } */

View File

@ -4,6 +4,6 @@
#define USE_GNU
#include "strlenopt-31.c"
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-not "strlen \\(" "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-not "strlen \\(" "strlen1" } } */

View File

@ -190,4 +190,4 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */

View File

@ -39,4 +39,4 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */

View File

@ -40,5 +40,5 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen1" } } */

View File

@ -35,4 +35,4 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */

View File

@ -28,4 +28,4 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen1" } } */

View File

@ -66,9 +66,9 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 3 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 3 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 3 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 3 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */

View File

@ -31,5 +31,5 @@ void h (void)
abort();
}
/* { dg-final { scan-tree-dump-times "strlen" 0 "optimized" } }
/* { dg-final { scan-tree-dump-times "strlen1" 0 "optimized" } }
{ dg-final { scan-tree-dump-times "abort" 0 "optimized" } } */

View File

@ -45,7 +45,7 @@ int cmp88 (void)
return cmp88;
}
/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } }
/* { dg-final { scan-tree-dump-times "strlen1" 0 "gimple" } }
{ dg-final { scan-tree-dump-times "len0 = 0;" 1 "gimple" } }
{ dg-final { scan-tree-dump-times "len = 18;" 1 "gimple" } }
{ dg-final { scan-tree-dump-times "lenx = 8;" 1 "gimple" } }

View File

@ -5,9 +5,9 @@
#define USE_GNU
#include "strlenopt-4.c"
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 5 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 5 "strlen1" } } */

View File

@ -6,13 +6,13 @@
#define FORTIFY_SOURCE 2
#include "strlenopt-4.c"
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 5 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 5 "strlen1" } } */

View File

@ -48,9 +48,9 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */

View File

@ -112,5 +112,5 @@ void test_array_ref (void)
T (&b[16], 0); T (&b[17], 0); T (&b[18], 0); T (&b[19], 0);
}
/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } }
/* { dg-final { scan-tree-dump-times "strlen1" 0 "gimple" } }
{ dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "ccp1" } } */

View File

@ -84,4 +84,4 @@ void test_elim_a9_9 (unsigned i)
T (0); T (1); T (2); T (3); T (4); T (5); T (6); T (7); T (8);
}
/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } */
/* { dg-final { scan-tree-dump-times "strlen1" 0 "gimple" } } */

View File

@ -284,5 +284,5 @@ void test_global_struct_struct_array (void)
T (ssa[5].sa9[3].a6, 3);
}
/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } }
/* { dg-final { scan-tree-dump-times "strlen1" 0 "gimple" } }
{ dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "ccp1" } } */

View File

@ -112,5 +112,5 @@ void test_array_ref (void)
T (&b[16], 0); T (&b[17], 0); T (&b[18], 0); T (&b[19], 0);
}
/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } }
/* { dg-final { scan-tree-dump-times "strlen1" 0 "gimple" } }
{ dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "ccp1" } } */

View File

@ -105,5 +105,5 @@ void elim_after_init_memcpy (void)
T ("AB\000CD", 0, "ab\000c", 4, 2);
}
/* { dg-final { scan-tree-dump-times "strlen" 0 "optimized" } }
/* { dg-final { scan-tree-dump-times "strlen1" 0 "optimized" } }
{ dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "optimized" } } */

View File

@ -224,7 +224,7 @@ const void test_large_string_size (void)
}
/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } }
/* { dg-final { scan-tree-dump-times "strlen1" 0 "gimple" } }
{ dg-final { scan-tree-dump-times "memcmp" 0 "gimple" } }
{ dg-final { scan-tree-dump-times "strcmp" 0 "gimple" } }
{ dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "optimized" } } */

View File

@ -45,6 +45,6 @@ void test_contents (void)
}
/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } }
/* { dg-final { scan-tree-dump-times "strlen1" 0 "gimple" } }
{ dg-final { scan-tree-dump-times "strcmp" 0 "gimple" } }
{ dg-final { scan-tree-dump-times "abort" 0 "optimized" } } */

View File

@ -77,9 +77,9 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */

View File

@ -215,4 +215,4 @@ void test_ta2 (void)
}
/* { dg-final { scan-tree-dump-not "failure" "optimized" } }
{ dg-final { scan-tree-dump-not "strlen" "gimple" } } */
{ dg-final { scan-tree-dump-not "strlen1" "gimple" } } */

View File

@ -0,0 +1,382 @@
/* PR tree-optimization/83431 - Verify that snprintf (0, 0, "%s",
with an argument that's a conditional expression evaluates to
the expected result regardless of the order of the expression
operands.
{ dg-do run }
{ dg-options "-O2 -Wall" } */
#include "strlenopt.h"
#define A(expr) \
((expr) \
? (void)0 \
: (__builtin_printf ("assertion failed on line %i: %s\n", \
__LINE__, #expr), \
__builtin_abort ()))
const char gs0[] = "";
const char gs3[] = "123";
char gc;
char ga5[7];
struct S { char n, ma7[7], max[]; };
__attribute__ ((noclone, noinline, noipa)) void
equal_4_gs0_gs3_ga5_m1 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? gs0 : 0 < i ? gs3 : ga5;
A (snprintf (0, 0, "%s", p) == 0);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_gs0_gs3_ga5_0 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? gs0 : 0 < i ? gs3 : ga5;
A (snprintf (0, 0, "%s", p) == 4);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_gs0_gs3_ga5_p1 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? gs0 : 0 < i ? gs3 : ga5;
A (snprintf (0, 0, "%s", p) == 3);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_gs0_ga5_gs3_m1 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? gs0 : 0 < i ? ga5 : gs3;
A (snprintf (0, 0, "%s", p) == 0);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_gs0_ga5_gs3_0 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? gs0 : 0 < i ? ga5 : gs3;
A (snprintf (0, 0, "%s", p) == 3);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_gs0_ga5_gs3_p1 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? gs0 : 0 < i ? ga5 : gs3;
A (snprintf (0, 0, "%s", p) == 4);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_ga5_gs0_gs3_m1 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? ga5 : 0 < i ? gs0 : gs3;
A (snprintf (0, 0, "%s", p) == 4);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_ga5_gs0_gs3_0 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? ga5 : 0 < i ? gs0 : gs3;
A (snprintf (0, 0, "%s", p) == 3);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_ga5_gs0_gs3_p1 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? ga5 : 0 < i ? gs0 : gs3;
A (snprintf (0, 0, "%s", p) == 0);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_ga5_gs3_gs0_m1 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? ga5 : 0 < i ? gs3 : gs0;
A (snprintf (0, 0, "%s", p) == 4);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_ga5_gs3_gs0_0 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? ga5 : 0 < i ? gs3 : gs0;
A (snprintf (0, 0, "%s", p) == 0);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_ga5_gs3_gs0_p1 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? ga5 : 0 < i ? gs3 : gs0;
A (snprintf (0, 0, "%s", p) == 3);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_gs3_gs0_ga5_m1 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? gs3 : 0 < i ? gs0 : ga5;
A (snprintf (0, 0, "%s", p) == 3);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_gs3_gs0_ga5_0 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? gs3 : 0 < i ? gs0 : ga5;
A (snprintf (0, 0, "%s", p) == 4);
}
__attribute__ ((noclone, noinline, noipa)) void
equal_4_gs3_gs0_ga5_p1 (int i)
{
strcpy (ga5, "1234");
const char *p = i < 0 ? gs3 : 0 < i ? gs0 : ga5;
A (snprintf (0, 0, "%s", p) == 0);
}
/* Similar to the above but with memcpy creating a string at least
four characters long, and the address of the NUL character. */
__attribute__ ((noclone, noinline, noipa)) void
min_4_gc_gs3_ga5_m1 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? &gc : 0 < i ? gs3 : ga5;
A (snprintf (0, 0, "%s", p) == 0);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_gc_gs3_ga5_0 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? &gc : 0 < i ? gs3 : ga5;
A (snprintf (0, 0, "%s", p) == 4);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_gc_gs3_ga5_p1 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? &gc : 0 < i ? gs3 : ga5;
A (snprintf (0, 0, "%s", p) == 3);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_gc_ga5_gs3_m1 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? &gc : 0 < i ? ga5 : gs3;
A (snprintf (0, 0, "%s", p) == 0);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_gc_ga5_gs3_0 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? &gc : 0 < i ? ga5 : gs3;
A (snprintf (0, 0, "%s", p) == 3);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_gc_ga5_gs3_p1 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? &gc : 0 < i ? ga5 : gs3;
A (snprintf (0, 0, "%s", p) == 4);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_ga5_gc_gs3_m1 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? ga5 : 0 < i ? &gc : gs3;
A (snprintf (0, 0, "%s", p) == 4);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_ga5_gc_gs3_0 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? ga5 : 0 < i ? &gc : gs3;
A (snprintf (0, 0, "%s", p) == 3);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_ga5_gc_gs3_p1 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? ga5 : 0 < i ? &gc : gs3;
A (snprintf (0, 0, "%s", p) == 0);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_ga5_gs3_gc_m1 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? ga5 : 0 < i ? gs3 : &gc;
A (snprintf (0, 0, "%s", p) == 4);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_ga5_gs3_gc_0 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? ga5 : 0 < i ? gs3 : &gc;
A (snprintf (0, 0, "%s", p) == 0);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_ga5_gs3_gc_p1 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? ga5 : 0 < i ? gs3 : &gc;
A (snprintf (0, 0, "%s", p) == 3);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_gs3_gc_ga5_m1 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? gs3 : 0 < i ? &gc : ga5;
A (snprintf (0, 0, "%s", p) == 3);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_gs3_gc_ga5_0 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? gs3 : 0 < i ? &gc : ga5;
A (snprintf (0, 0, "%s", p) == 4);
}
__attribute__ ((noclone, noinline, noipa)) void
min_4_gs3_gc_ga5_p1 (int i)
{
gc = 0;
memcpy (ga5, "1234", 4);
const char *p = i < 0 ? gs3 : 0 < i ? &gc : ga5;
A (snprintf (0, 0, "%s", p) == 0);
}
int main (void)
{
equal_4_gs0_gs3_ga5_m1 (-1);
equal_4_gs0_gs3_ga5_0 ( 0);
equal_4_gs0_gs3_ga5_p1 (+1);
equal_4_gs0_ga5_gs3_m1 (-1);
equal_4_gs0_ga5_gs3_0 ( 0);
equal_4_gs0_ga5_gs3_p1 (+1);
equal_4_ga5_gs0_gs3_m1 (-1);
equal_4_ga5_gs0_gs3_0 ( 0);
equal_4_ga5_gs0_gs3_p1 (+1);
equal_4_ga5_gs3_gs0_m1 (-1);
equal_4_ga5_gs3_gs0_0 ( 0);
equal_4_ga5_gs3_gs0_p1 (+1);
equal_4_gs3_gs0_ga5_m1 (-1);
equal_4_gs3_gs0_ga5_0 ( 0);
equal_4_gs3_gs0_ga5_p1 (+1);
/* Same as aabove but with memcpy creating a string at least four
characters long. */
memset (ga5, 0, sizeof ga5);
min_4_gc_gs3_ga5_m1 (-1);
memset (ga5, 0, sizeof ga5);
min_4_gc_gs3_ga5_0 ( 0);
memset (ga5, 0, sizeof ga5);
min_4_gc_gs3_ga5_p1 (+1);
memset (ga5, 0, sizeof ga5);
min_4_gc_ga5_gs3_m1 (-1);
memset (ga5, 0, sizeof ga5);
min_4_gc_ga5_gs3_0 ( 0);
memset (ga5, 0, sizeof ga5);
min_4_gc_ga5_gs3_p1 (+1);
memset (ga5, 0, sizeof ga5);
min_4_ga5_gc_gs3_m1 (-1);
memset (ga5, 0, sizeof ga5);
min_4_ga5_gc_gs3_0 ( 0);
memset (ga5, 0, sizeof ga5);
min_4_ga5_gc_gs3_p1 (+1);
memset (ga5, 0, sizeof ga5);
min_4_ga5_gs3_gc_m1 (-1);
memset (ga5, 0, sizeof ga5);
min_4_ga5_gs3_gc_0 ( 0);
memset (ga5, 0, sizeof ga5);
min_4_ga5_gs3_gc_p1 (+1);
memset (ga5, 0, sizeof ga5);
min_4_gs3_gc_ga5_m1 (-1);
memset (ga5, 0, sizeof ga5);
min_4_gs3_gc_ga5_0 ( 0);
memset (ga5, 0, sizeof ga5);
min_4_gs3_gc_ga5_p1 (+1);
}

View File

@ -40,12 +40,12 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "\\*r_\[0-9\]* = 0;" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "\\*r_\[0-9\]* = 0;" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "return 3;" 1 "optimized" } } */
/* { dg-final { scan-tree-dump-times "return 0;" 2 "optimized" } } */

View File

@ -98,10 +98,10 @@ main ()
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 5 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen \\(" 5 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "return 4;" 1 "optimized" } } */

View File

@ -1,4 +1,4 @@
/* This is a replacement of needed parts from stdlib.h and string.h
/* This is a replacement of needed parts from <stdlib.h> and <string.h>
for -foptimize-strlen testing, to ensure we are testing the builtins
rather than whatever the OS has in its headers. */
@ -25,6 +25,9 @@ void *mempcpy (void *__restrict, const void *__restrict, size_t);
char *stpcpy (char *__restrict, const char *__restrict);
#endif
int sprintf (char * __restrict, const char *__restrict, ...);
int snprintf (char * __restrict, size_t, const char *__restrict, ...);
#if defined(FORTIFY_SOURCE) && FORTIFY_SOURCE > 0 && __OPTIMIZE__
# define bos(ptr) __builtin_object_size (ptr, FORTIFY_SOURCE > 0)
# define bos0(ptr) __builtin_object_size (ptr, 0)

View File

@ -0,0 +1,139 @@
/* Test to verify that snprintf can determine the length of a dynamically
constructed string argument and fold the result into a constant.
{ dg-do compile }
{ dg-options "-O2 -Wall -fdump-tree-optimized" } */
typedef __SIZE_TYPE__ size_t;
char* strcpy (char * restrict, const char * restrict);
int sprintf (char * restrict, const char *restrict, ...);
int snprintf (char * restrict, size_t, const char *restrict, ...);
#define CONCAT(x, y) x ## y
#define CAT(x, y) CONCAT (x, y)
#define FAILNAME(name, counter) \
CAT (CAT (CAT (call_ ## name ##_on_line_, __LINE__), _), counter)
#define FAIL(name, counter) do { \
extern void FAILNAME (name, counter) (void); \
FAILNAME (name, counter)(); \
} while (0)
/* Macro to emit a call to funcation named
call_in_true_branch_not_eliminated_on_line_NNN()
for each call that's expected to be eliminated. The dg-final
scan-tree-dump-time directive at the bottom of the test verifies
that no such call appears in output. */
#define ELIM(expr) \
if (!(expr)) FAIL (in_true_branch_not_eliminated, __COUNTER__); else (void)0
#define ARGS(...) __VA_ARGS__
#define T(expect, init, fmt, ...) \
do { \
char a[] = init; \
ELIM (expect == snprintf (0, 0, fmt, __VA_ARGS__)); \
} while (0)
/* Exercise a non-const local char array initialized by a string literal. */
void test_assign_string (void)
{
T (0, "", "%s", a);
T (1, "1", "%s", a);
T (4, "1234", "%s", a);
T (5, "123", "s=%s", a);
T (5, "1234", "s=%s", a + 1);
T (2, "1234", "s=%s", a + 4);
T (5, "12345", "s=%s", &a[2]);
T (5, "123456", "s=%.*s", 3, &a[2]);
}
/* Exercise a non-const local char array initialized by an initializer
list. */
void test_assign_init_list (void)
{
T (0, ARGS ({ 0 }), "%s", a);
T (1, ARGS ({ 1, 0 }), "%s", a);
T (3, ARGS ({ [3] = 0, [1] = 2, [0] = 1, [2] = 3 }), "%s", a);
T (3, ARGS ({ [3] = 0, [1] = 2, [0] = 1, [2] = 3, [4] = 0 }), "%s", a);
T (4, ARGS ({ 1, 2, 3, 4, 0 }), "%s", a);
T (5, ARGS ({ 1, 2, 3, 0 }), "s=%s", a);
T (5, ARGS ({ 1, 2, 3, 4, 0 }), "s=%s", a + 1);
T (2, ARGS ({ 1, 2, 3, 4, 0 }), "s=%s", a + 4);
T (5, ARGS ({ 1, 2, 3, 4, 5, 0 }), "s=%s", &a[2]);
T (5, ARGS ({ 1, 2, 3, 4, 5, 6, 0 }), "s=%.*s", 3, &a[2]);
}
#undef T
#define T(expect, init, fmt, ...) \
do { \
struct { int n; char a[sizeof init]; } \
s = { sizeof init, init }; \
ELIM (expect == snprintf (0, 0, fmt, __VA_ARGS__)); \
} while (0)
/* Exercise a non-const local struct initialized by an initializer
list. */
void test_assign_aggregate (void)
{
T (0, "", "%s", s.a);
T (1, "1", "%s", s.a);
T (4, "1234", "%s", s.a);
T (5, "123", "s=%s", s.a);
T (5, "1234", "s=%s", s.a + 1);
T (2, "1234", "s=%s", s.a + 4);
T (5, "12345", "s=%s", &s.a[2]);
T (5, "123456", "s=%.*s", 3, &s.a[2]);
}
#undef T
#define T(expect, init, fmt, ...) \
do { \
char a[sizeof init]; \
strcpy (a, init); \
ELIM (expect == snprintf (0, 0, fmt, __VA_ARGS__)); \
} while (0)
/* Exercise a local char array initialized by a call to strcpy. */
void test_local_strcpy (void)
{
T (0, "", "%s", a);
T (1, "1", "%s", a);
T (2, "12", "%s", a);
T (3, "123", "%s", a);
T (4, "1234", "%s", a);
T (5, "123", "s=%s", a);
T (5, "1234", "s=%s", a + 1);
T (2, "1234", "s=%s", a + 4);
T (5, "12345", "s=%s", &a[2]);
T (5, "123456", "s=%.*s", 3, &a[2]);
}
#undef T
#define T(expect, init, fmt, ...) \
do { \
char a[n]; \
strcpy (a, init); \
ELIM (expect == snprintf (0, 0, fmt, __VA_ARGS__)); \
} while (0)
/* Exercise a VLA initialized by a call to strcpy. */
void test_vla_strcpy (unsigned n)
{
T (0, "", "%s", a);
T (1, "1", "%s", a);
T (2, "12", "%s", a);
T (3, "123", "%s", a);
T (4, "1234", "%s", a);
T (5, "123", "s=%s", a);
T (5, "1234", "s=%s", a + 1);
T (2, "1234", "s=%s", a + 4);
T (5, "12345", "s=%s", &a[2]);
T (5, "123456", "s=%.*s", 3, &a[2]);
}
/* { dg-final { scan-tree-dump-times "printf" 0 "optimized" } }
{ dg-final { scan-tree-dump-times "strlen" 0 "optimized" } }
{ dg-final { scan-tree-dump-times "not_eliminated" 0 "optimized" } } */

View File

@ -0,0 +1,152 @@
/* Test to verify that snprintf can determine the correct range
of lengths of dynamically constructed string arguments.
{ dg-do compile }
{ dg-options "-O2 -Wall -fdump-tree-optimized" } */
typedef __SIZE_TYPE__ size_t;
void* memcpy (void*, const void*, size_t);
char* strcpy (char * restrict, const char * restrict);
int snprintf (char * restrict, size_t, const char *restrict, ...);
void sink (void*, ...);
#define CONCAT(x, y) x ## y
#define CAT(x, y) CONCAT (x, y)
#define FAILNAME(name, counter) \
CAT (CAT (CAT (call_ ## name ##_on_line_, __LINE__), _), counter)
#define FAIL(name, counter) do { \
extern void FAILNAME (name, counter) (void); \
FAILNAME (name, counter)(); \
} while (0)
/* Macro to emit a call to funcation named
call_in_true_branch_not_eliminated_on_line_NNN()
for each call that's expected to be eliminated. The dg-final
scan-tree-dump-time directive at the bottom of the test verifies
that no such call appears in output. */
#define VERIFY_ELIM(expr) \
if (!(expr)) FAIL (in_true_branch_not_eliminated, __COUNTER__); else (void)0
/* Macro to emit a call to a function named
call_made_in_{true,false}_branch_on_line_NNN()
for each call that's expected to be retained. The dg-final
scan-tree-dump-time directive at the bottom of the test verifies
that the expected number of both kinds of calls appears in output
(a pair for each line with the invocation of the KEEP() macro. */
#define VERIFY_KEEP(expr) \
if (expr) \
FAIL (made_in_true_branch, __COUNTER__); \
else \
FAIL (made_in_false_branch, __COUNTER__)
#define ARGS(...) __VA_ARGS__
/* Each test macro expands to a new function to get around bug 81776
- missing sprintf optimization due to pointer escape analysis. */
#define ELIM(expect, dst, init, fmt, ...) \
void CAT (test_func_on_line_, __LINE__)(void) \
{ \
memcpy (dst, init, sizeof (init) - 1); \
const int res = snprintf (0, 0, fmt, __VA_ARGS__); \
VERIFY_ELIM (expect res); \
} typedef void dummy_typedef
#define KEEP(expect, dst, init, fmt, ...) \
void CAT (test_func_on_line_, __LINE__)(void) \
{ \
memcpy (dst, init, sizeof (init) - 1); \
const int ret = snprintf (0, 0, fmt, __VA_ARGS__); \
VERIFY_KEEP (expect ret); \
} typedef void dummy_typedef
/* Verify that conditions involving snprintf calls with a string
of some minimum but otherwise unbounded length stored in an array
of unknown bound are not folded unless the format string itself
restricts the maximum. The string could be longer than INT_MAX
making the snprintf call fail and return a negative value. */
extern char gax[];
KEEP (1 <=, gax, "1", "%s", gax);
KEEP (2 <=, gax, "12", "%s", gax);
KEEP (3 <=, gax, "123", "%s", gax);
ELIM (3 ==, gax, "123", "%.3s", gax);
ELIM (5 ==, gax, "123", "%.3s%.2s", gax, gax);
/* Disabled. The global pointer passed to memcpy as the destination
might point at itself, i.e., gptr == &gptr is a valid argument to
memcpy.
extern char *gptr;
KEEP (1 <=, gptr, "1", "%s", gptr);
KEEP (2 <=, gptr, "12", "%s", gptr);
KEEP (3 <=, gptr, "123", "%s", gptr);
ELIM (3 ==, gptr, "123", "%.3s", gptr);
ELIM (5 ==, gptr, "123", "%.3s%.2s", gptr, gptr);
*/
/* Verify that conditions involving snprintf calls with a string
of some minimum but otherwise unbounded length stored in an array
of a known bound are folded. The longest string that can be
stored in such arrays is bounded by the size of the array. */
extern char ga4[4];
ELIM (0 <=, ga4, "\0", "%s", ga4);
ELIM (3 >=, ga4, "\0", "%s", ga4);
ELIM (1 <=, ga4, "1", "%s", ga4);
ELIM (0 <=, ga4, "1", "%s", ga4 + 1);
ELIM (0 <=, ga4, "1", "%s", &ga4[1]);
ELIM (3 >=, ga4, "1", "%s", ga4);
ELIM (2 >=, ga4, "1", "%s", ga4 + 1);
ELIM (2 >=, ga4, "1", "%s", &ga4[1]);
ELIM (2 <=, ga4, "12", "%s", ga4);
ELIM (3 >=, ga4, "12", "%s", ga4);
ELIM (3 <=, ga4, "123", "%s", ga4);
ELIM (3 ==, ga4, "123", "%.3s", ga4);
ELIM (5 ==, ga4, "123", "%.3s%.2s", ga4, ga4);
/* Verify conditionals involving dynamically created strings of known
length stored in local arrays. */
#undef ELIM
#define ELIM(expect, N1, N2, init1, init2, fmt, ...) \
void CAT (test_func_on_line_, __LINE__)(int i) \
{ \
char a1[N1], a2[N2]; \
memcpy (a1, init1, sizeof (init1) - 1); \
memcpy (a2, init2, sizeof (init2) - 1); \
const int res = snprintf (0, 0, fmt, __VA_ARGS__); \
VERIFY_ELIM (expect res); \
} typedef void dummy_typedef
ELIM (0 ==, 2, 2, "\0", "\0", "%s", i ? a1 : a2);
ELIM (2 ==, 2, 2, "\0", "\0", "s=%s", i ? a1 : a2);
ELIM (1 ==, 2, 2, "a\0", "b\0", "%s", i ? a1 : a2);
ELIM (3 ==, 2, 2, "a\0", "b\0", "s=%s", i ? a1 : a2);
ELIM (2 ==, 3, 5, "ab\0", "cd\0", "%s", i ? a1 : a2);
ELIM (3 ==, 3, 5, "ab\0", "cd\0", "%3s", i ? a1 : a2);
ELIM (3 ==, 5, 5, "abcd\0", "efgh\0", "%.3s", i ? a1 : a2);
ELIM (3 ==, 4, 1, "abc\0", "", "%s", i ? a1 : "def");
ELIM (4 ==, 1, 5, "", "efgh\0", "%s", i ? "abcd" : a2);
ELIM (4 ==, 5, 5, "abcd\0", "efgh\0", "%s", i < 0 ? a1 : 0 < i ? a2 : "ijkl");
/* { dg-final { scan-tree-dump-times "_not_eliminated" 0 "optimized" } }
{ dg-final { scan-tree-dump-times "call_made_" 6 "optimized" } } */

View File

@ -0,0 +1,41 @@
/* Test to verify that snprintf can determine the correct range
of lengths of string arguments based on the results of prior
calls to strlen.
{ dg-do compile }
{ dg-options "-O2 -Wall -fdump-tree-optimized" } */
typedef __SIZE_TYPE__ size_t;
void abort (void);
size_t strlen (const char *);
int snprintf (char * restrict, size_t, const char *restrict, ...);
void one_str_exact (const char *str)
{
if (1 == strlen (str))
if (1 != snprintf (0, 0, "%s", str))
abort ();
}
void two_str_exact (const char *s1, const char *s2)
{
if (1 == strlen (s1) && 2 == strlen (s2))
if (3 != snprintf (0, 0, "%s%s", s1, s2))
abort ();
}
void one_str_maxlen (const char *str)
{
if (2 >= strlen (str))
if (2 < snprintf (0, 0, "%s", str))
abort ();
}
void two_str_maxlen (const char *s1, const char *s2)
{
if (2 >= strlen (s1) && 3 >= strlen (s2))
if (5 < snprintf (0, 0, "%s%s", s1, s2))
abort ();
}
/* { dg-final { scan-tree-dump-not "abort" "optimized" } } */

View File

@ -0,0 +1,163 @@
/* Test to verify that --param ssa_name_def_chain_limit can be used to
limit the maximum number of SSA_NAME assignments the built-in code
follows to determine the variable value/string length.
{ dg-do compile }
{ dg-options "-O2 -Wall --param ssa-name-def-chain-limit=4 -fdump-tree-optimized" } */
void abort (void);
int sprintf (char * restrict, const char *restrict, ...);
void sink (const char*, ...);
const char a0[] = "";
const char a1[] = "1";
const char a2[] = "12";
const char a3[] = "123";
const char a4[] = "1234";
const char a5[] = "12345";
const char a6[] = "123456";
const char a7[] = "1234567";
const char a8[] = "12345678";
const char a9[] = "123456789";
int i0, i1, i2, i3, i4, i5, i6, i7, i8;
void g1 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
sink (p0, p1);
if (sprintf (d, "%s", p1) > 2)
abort ();
}
void g2 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
sink (p0, p1, p2);
if (sprintf (d, "%s", p2) > 3)
abort ();
}
void g3 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
sink (p0, p1, p2, p3);
if (sprintf (d, "%s", p3) > 4)
abort ();
}
void g4 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
const char *p4 = i4 ? p3 : a5;
sink (p0, p1, p2, p3, p4);
// p4 below is the result of the following five PHI assignments
// and with the limit set to 4 the sprintf call result is not
// determined:
// iftmp.0_7 = PHI <&a0(2), &a1(3)>
// iftmp.2_8 = PHI <iftmp.0_7(4), &a2(5)>
// iftmp.4_9 = PHI <iftmp.2_8(6), &a3(7)>
// iftmp.6_10 = PHI <iftmp.4_9(8), &a4(9)>
// iftmp.8_17 = PHI <iftmp.6_10(10), &a5(11)>
// p4 = iftmp.8_17
extern void keep_g4 (void);
if (sprintf (d, "%s", p4) > 5)
keep_g4 ();
}
void g5 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
const char *p4 = i4 ? p3 : a5;
const char *p5 = i5 ? p4 : a6;
sink (p0, p1, p2, p3, p4, p5);
extern void keep_g5 (void);
if (sprintf (d, "%s", p5) > 6)
keep_g5 ();
/* { dg-final { scan-tree-dump-times "keep_g5" 1 "optimized" } } */
}
void g6 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
const char *p4 = i4 ? p3 : a5;
const char *p5 = i5 ? p4 : a6;
const char *p6 = i6 ? p5 : a7;
sink (p0, p1, p2, p3, p4, p5, p6);
extern void keep_g6 (void);
if (sprintf (d, "%s", p6) > 7)
keep_g6 ();
/* { dg-final { scan-tree-dump-times "keep_g6" 1 "optimized" } } */
}
void g7 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
const char *p4 = i4 ? p3 : a5;
const char *p5 = i5 ? p4 : a6;
const char *p6 = i6 ? p5 : a7;
const char *p7 = i7 ? p6 : a8;
sink (p0, p1, p2, p3, p4, p5, p6, p7);
extern void keep_g7 (void);
if (sprintf (d, "%s", p7) > 8)
keep_g7 ();
/* { dg-final { scan-tree-dump-times "keep_g7" 1 "optimized" } } */
}
void g8 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
const char *p4 = i4 ? p3 : a5;
const char *p5 = i5 ? p4 : a6;
const char *p6 = i6 ? p5 : a7;
const char *p7 = i7 ? p6 : a8;
const char *p8 = i8 ? p7 : a9;
sink (p0, p1, p2, p3, p4, p5, p6, p7, p8);
extern void keep_g8 (void);
if (sprintf (d, "%s", p8) > 9)
keep_g8 ();
/* { dg-final { scan-tree-dump-times "keep_g8" 1 "optimized" } } */
}
/* { dg-final { scan-tree-dump-not "abort" "optimized" } } */

View File

@ -0,0 +1,140 @@
/* Test to verify that --param ssa_name_def_chain_limit can be used to
limit the maximum number of SSA_NAME assignments the built-in code
follows.
{ dg-do compile }
{ dg-options "-O2 -Wall -Wformat-truncation=2 --param ssa-name-def-chain-limit=4 -fdump-tree-optimized" } */
typedef __SIZE_TYPE__ size_t;
int snprintf (char * restrict, size_t, const char *restrict, ...);
void sink (const char*, ...);
const char a0[] = "";
const char a1[] = "1";
const char a2[] = "12";
const char a3[] = "123";
const char a4[] = "1234";
const char a5[] = "12345";
const char a6[] = "123456";
const char a7[] = "1234567";
const char a8[] = "12345678";
const char a9[] = "123456789";
int i0, i1, i2, i3, i4, i5, i6, i7, i8;
void g1 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
sink (p0, p1);
snprintf (d, 1, "%s", p1); // { dg-warning "\\\[-Wformat-truncation" }
}
void g2 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
sink (p0, p1, p2);
snprintf (d, 2, "%s", p2); // { dg-warning "\\\[-Wformat-truncation" }
}
void g3 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
sink (p0, p1, p2, p3);
snprintf (d, 3, "%s", p3); // { dg-warning "\\\[-Wformat-truncation" }
}
void g4 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
const char *p4 = i4 ? p3 : a5;
sink (p0, p1, p2, p3, p4);
// p4 below is the result of the following five PHI assignments
// and with the limit set to 4 the snprintf call is not diagnosed
// iftmp.0_7 = PHI <&a0(2), &a1(3)>
// iftmp.2_8 = PHI <iftmp.0_7(4), &a2(5)>
// iftmp.4_9 = PHI <iftmp.2_8(6), &a3(7)>
// iftmp.6_10 = PHI <iftmp.4_9(8), &a4(9)>
// iftmp.8_17 = PHI <iftmp.6_10(10), &a5(11)>
// p4 = iftmp.8_17
snprintf (d, 4, "%s", p4);
}
void g5 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
const char *p4 = i4 ? p3 : a5;
const char *p5 = i5 ? p4 : a6;
sink (p0, p1, p2, p3, p4, p5);
snprintf (d, 5, "%s", p5);
}
void g6 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
const char *p4 = i4 ? p3 : a5;
const char *p5 = i5 ? p4 : a6;
const char *p6 = i6 ? p5 : a7;
sink (p0, p1, p2, p3, p4, p5, p6);
snprintf (d, 6, "%s", p6);
}
void g7 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
const char *p4 = i4 ? p3 : a5;
const char *p5 = i5 ? p4 : a6;
const char *p6 = i6 ? p5 : a7;
const char *p7 = i7 ? p6 : a8;
sink (p0, p1, p2, p3, p4, p5, p6, p7);
snprintf (d, 7, "%s", p7);
}
void g8 (char *d)
{
const char *p0 = i0 ? a0 : a1;
const char *p1 = i1 ? p0 : a2;
const char *p2 = i2 ? p1 : a3;
const char *p3 = i3 ? p2 : a4;
const char *p4 = i4 ? p3 : a5;
const char *p5 = i5 ? p4 : a6;
const char *p6 = i6 ? p5 : a7;
const char *p7 = i7 ? p6 : a8;
const char *p8 = i8 ? p7 : a9;
sink (p0, p1, p2, p3, p4, p5, p6, p7, p8);
snprintf (d, 8, "%s", p8);
}

View File

@ -0,0 +1,94 @@
/* PR tree-optimization/83431 -Wformat-truncation may incorrectly report
truncation
{ dg-do compile }
{ dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
typedef __SIZE_TYPE__ size_t;
extern int snprintf (char*, size_t, const char*, ...);
extern char* strcpy (char*, const char*);
struct S
{
char a9[9];
char a5[5];
int x;
};
void test_assign_nowarn (struct S* s)
{
int i = 0;
{
char a9[9] = "1234";
snprintf (s[i].a5, sizeof (s[i].a5), "%s", a9); /* { dg-bogus "\\\[-Wformat-truncation]" } */
}
{
++i;
char a8[8] = "123";
snprintf (s[i].a5, sizeof (s[i].a5), "%s\n", a8); /* { dg-bogus "\\\[-Wformat-truncation]" } */
}
{
++i;
char a7[7] = "12";
snprintf (s[i].a5, sizeof (s[i].a5), "[%s]", a7); /* { dg-bogus "\\\[-Wformat-truncation]" } */
}
{
++i;
char a6[6] = "1";
snprintf (s[i].a5, sizeof (s[i].a5), "[%s]\n", a6); /* { dg-bogus "\\\[-Wformat-truncation]" } */
}
}
void test_strcpy_nowarn (struct S* s)
{
int i = 0;
strcpy (s[i].a9, "1234");
snprintf (s[i].a5, sizeof (s[i].a5), "%s", s[i].a9);
++i;
strcpy (s[i].a9, "123");
snprintf (s[i].a5, sizeof (s[i].a5), "%s\n", s[i].a9); /* { dg-bogus "\\\[-Wformat-truncation]" } */
++i;
strcpy (s[i].a9, "12");
snprintf (s[i].a5, sizeof (s[i].a5), "[%s]", s[i].a9); /* { dg-bogus "\\\[-Wformat-truncation]" } */
++i;
strcpy (s[i].a9, "1");
snprintf (s[i].a5, sizeof (s[i].a5), "[%s]\n", s[i].a9); /* { dg-bogus "\\\[-Wformat-truncation]" } */
}
void test_warn (struct S* s)
{
int i = 0;
strcpy (s[i].a9, "12345678");
snprintf (s[i].a5, sizeof (s[i].a5), "%s", s[i].a9); /* { dg-warning "'%s' directive output truncated writing 8 bytes into a region of size 5" } */
++i;
strcpy (s[i].a9, "1234567");
snprintf (s[i].a5, sizeof (s[i].a5), "%s", s[i].a9); /* { dg-warning "'%s' directive output truncated writing 7 bytes into a region of size 5" } */
++i;
strcpy (s[i].a9, "123456");
snprintf (s[i].a5, sizeof (s[i].a5), "%s", s[i].a9); /* { dg-warning "'%s' directive output truncated writing 6 bytes into a region of size 5" } */
++i;
strcpy (s[i].a9, "12345");
snprintf (s[i].a5, sizeof (s[i].a5), "%s", s[i].a9); /* { dg-warning "'snprintf' output truncated before the last format character" } */
++i;
strcpy (s[i].a9, "1234");
snprintf (s[i].a5, sizeof (s[i].a5), "%s\n", s[i].a9); /* { dg-warning "output truncated before the last format character" } */
++i;
strcpy (s[i].a9, "123");
snprintf (s[i].a5, sizeof (s[i].a5), ">%s<", s[i].a9); /* { dg-warning "output truncated before the last format character" } */
}

View File

@ -0,0 +1,11 @@
/* PR middle-end/87052 - STRING_CST printing incomplete in Gimple dumps
{ dg-do compile }
{ dg-options "-fdump-tree-original" } */
void* f (char *d, int c)
{
return __builtin_memchr ("1\0\0", c, 4);
}
/* Veriy the full string appears in the dump:
{ dg-final { scan-tree-dump "\"1\\\\x00\\\\x00\"" "original" } } */

View File

@ -11,4 +11,4 @@ void f (void)
__builtin_abort ();
}
/* { dg-final { scan-tree-dump-not "__builtin_strlen" "strlen" } } */
/* { dg-final { scan-tree-dump-not "__builtin_strlen" "strlen1" } } */

View File

@ -12,4 +12,4 @@ void f3 (void)
f (__builtin_strlen (s));
}
/* { dg-final { scan-tree-dump-times "strlen" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strlen" 0 "strlen1" } } */

View File

@ -419,6 +419,7 @@ extern gimple_opt_pass *make_pass_omp_target_link (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_oacc_device_lower (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_omp_device_lower (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_object_sizes (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_warn_printf (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_strlen (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_fold_builtins (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_post_ipa_warn (gcc::context *ctxt);

File diff suppressed because it is too large Load Diff

View File

@ -25,4 +25,11 @@ extern bool is_strlen_related_p (tree, tree);
extern bool maybe_diag_stxncpy_trunc (gimple_stmt_iterator, tree, tree);
extern tree set_strlen_range (tree, wide_int, wide_int, tree = NULL_TREE);
struct c_strlen_data;
class vr_values;
extern void get_range_strlen_dynamic (tree , c_strlen_data *, const vr_values *);
/* APIs internal to strlen pass. Defined in in gimple-ssa-sprintf.c. */
extern bool handle_printf_call (gimple_stmt_iterator *, const vr_values *);
#endif // GCC_TREE_SSA_STRLEN_H

View File

@ -369,7 +369,7 @@ value_range_base::singleton_p (tree *result) const
tree
value_range_base::type () const
{
gcc_assert (m_min || undefined_p ());
gcc_assert (m_min);
return TREE_TYPE (min ());
}

View File

@ -234,7 +234,7 @@ vr_values::update_value_range (const_tree var, value_range *new_vr)
called, if we are anyway, keep it VARYING. */
if (old_vr->varying_p ())
{
new_vr->set_varying (new_vr->type ());
new_vr->set_varying (TREE_TYPE (var));
is_new = false;
}
else if (new_vr->undefined_p ())