Commit a76acaed by Martin Sebor Committed by Martin Sebor

PR tree-optimization/84468 - bogus -Wstringop-truncation despite assignment…

PR tree-optimization/84468 - bogus -Wstringop-truncation despite assignment after conditional strncpy

gcc/ChangeLog:

	PR tree-optimization/84468
	* tree-ssa-strlen.c (maybe_diag_stxncpy_trunc): Consider successor
	basic block when looking for nul assignment.

gcc/testsuite/ChangeLog:

	PR tree-optimization/84468
	* g++.dg/warn/Wstringop-truncation-2.C: New test.
	* gcc.dg/Wstringop-truncation.c: New test.
	* gcc.dg/Wstringop-truncation-2.c: New test.

From-SVN: r258339
parent b78b513e
2018-03-07 Martin Sebor <msebor@redhat.com>
PR tree-optimization/84468
* tree-ssa-strlen.c (maybe_diag_stxncpy_trunc): Consider successor
basic block when looking for nul assignment.
2018-03-07 Eric Botcazou <ebotcazou@adacore.com>
PR target/84277
......
2018-03-07 Martin Sebor <msebor@redhat.com>
PR tree-optimization/84468
* g++.dg/warn/Wstringop-truncation-2.C: New test.
* gcc.dg/Wstringop-truncation.c: New test.
* gcc.dg/Wstringop-truncation-2.c: New test.
2018-03-07 Jakub Jelinek <jakub@redhat.com>
PR fortran/84565
......
......@@ -37,7 +37,7 @@ void good_nowarn_size_m1 ()
sink (&str);
}
void good_nowarn_size_m1_var (const char* s)
static void good_nowarn_size_m1_var (const char* s)
{
GoodString<3> str (s); // { dg-bogus "\\\[-Wstringop-truncation]" }
sink (&str);
......@@ -112,7 +112,7 @@ private:
char str[N + 1];
};
void bad3_warn_size_m1_var (const char *s)
static void bad3_warn_size_m1_var (const char *s)
{
BadString3<3> str (s);
sink (&str);
......
// PR tree-optimization/84468 - bogus -Wstringop-truncation despite
// assignment after conditional strncpy
// Compile with -g to verify the warning deals properly with debug
// statements.
// { dg-do compile }
// { dg-options "-O2 -Wstringop-truncation -g" }
extern "C" char* strncpy (char*, const char*, __SIZE_TYPE__);
char d[3];
void g ();
void fnowarn1 (const char *s)
{
// Update dummy but never actually use it so it's eliminated
// but causes debugging statements to be emitted for each
// modification.
int dummy = 0;
try
{
g ();
strncpy (d, s, sizeof d); // { dg-bogus "\\\[-Wstringop-truncation]" }
++dummy;
}
catch (...)
{
++dummy;
d[0] = 0;
}
++dummy;
d[sizeof d - 1] = 0;
}
void fnowarn2 (const char *s)
{
int dummy = 0;
try
{
g ();
strncpy (d, s, sizeof d);
++dummy;
}
catch (...)
{
++dummy;
return;
}
++dummy;
d[sizeof d - 1] = 0;
}
void fnowarn3 (const char *s)
{
int dummy = 0;
try
{
g ();
strncpy (d, s, sizeof d);
++dummy;
try
{
++dummy;
d[sizeof d - 1] = 0;
g ();
}
catch (...)
{
++dummy;
}
}
catch (...)
{
++dummy;
return;
}
++dummy;
d[sizeof d - 1] = 0;
}
void fnowarn4 (const char *s)
{
int dummy = 0;
try
{
g ();
}
catch (...)
{
strncpy (d, s, sizeof d); // { dg-bogus "\\\[-Wstringop-truncation]" "bug 84468" { xfail *-*-*} }
++dummy;
}
++dummy;
d[sizeof d - 1] = 0;
}
void fwarn1 (const char *s)
{
int dummy = 0;
try
{
++dummy;
g ();
++dummy;
strncpy (d, s, sizeof d); // { dg-warning "\\\[-Wstringop-truncation]" }
++dummy;
}
catch (...)
{
++dummy;
}
++dummy;
}
void fwarn2 (const char *s)
{
int dummy = 0;
try
{
++dummy;
strncpy (d, s, sizeof d); // { dg-warning "\\\[-Wstringop-truncation]" }
++dummy;
g ();
++dummy;
}
catch (...)
{
++dummy;
}
++dummy;
}
void fwarn3 (const char *s)
{
int dummy = 0;
try
{
++dummy;
g ();
++dummy;
strncpy (d, s, sizeof d); // { dg-warning "\\\[-Wstringop-truncation]" }
++dummy;
}
catch (...)
{
++dummy;
d[0] = 0;
}
++dummy;
}
/* PR tree-optimization/84468 - bogus -Wstringop-truncation despite
assignment after conditional strncpy
{ dg-do compile }
{ dg-options "-O2 -Wstringop-truncation -g" } */
extern char* strncpy (char*, const char*, __SIZE_TYPE__);
char a[4];
void f1 (char *s)
{
int i = 0;
if (s[0] == '0')
{
i += 1;
strncpy (a, s, sizeof a); /* { dg-bogus "\\\[-Wstringop-truncation]" } */
}
else
i += 2;
a[sizeof a - 1] = 0;
}
void f2 (char *s)
{
int i = 0;
if (s[0] == '0')
{
i += 1;
if (s[1] == '1')
{
i += 2;
strncpy (a, s, sizeof a); /* { dg-bogus "\\\[-Wstringop-truncation]" } */
}
else
i += 3;
}
else
i += 4;
a[sizeof a - 1] = 0;
}
void f3 (char *s)
{
int i = 0;
if (s[0] == '0')
{
i += 1;
if (s[1] == '1')
{
i += 2;
if (s[2] == '2')
strncpy (a, s, sizeof a); /* { dg-bogus "\\\[-Wstringop-truncation]" } */
else
i += 3;
}
else
i += 4;
}
else
i += 5;
a[sizeof a - 1] = 0;
}
void f4 (char *s)
{
int i = 0;
if (s[0] == '0')
{
i += 1;
if (s[1] == '1')
{
i += 2;
if (s[2] == '2')
{
i += 3;
if (s[3] == '3')
strncpy (a, s, sizeof a); /* { dg-bogus "\\\[-Wstringop-truncation]" } */
else
i += 4;
}
else
i += 5;
}
else
i += 6;
}
else
i += 7;
a[sizeof a - 1] = 0;
}
void f4_warn (char *s)
{
int i = 0;
if (s[0] == '0')
{
i += 1;
if (s[1] == '1')
{
i += 2;
if (s[2] == '2')
{
i += 3;
if (s[3] == '3')
strncpy (a, s, sizeof a); /* { dg-warning "\\\[-Wstringop-truncation]" } */
else
i += 4;
}
else
i += 5;
}
else
i += 6;
}
else
i += 7;
}
/* PR tree-optimization/84468 - Inconsistent -Wstringop-truncation warnings
with -O2
{ dg-do compile }
{ dg-options "-O2 -Wstringop-truncation -ftrack-macro-expansion=0 -g" } */
#define strncpy __builtin_strncpy
struct A
{
char a[4];
};
void no_pred_succ_lit (struct A *p)
{
/* The following is folded early on, before the strncpy statement
has a basic block. Verify that the case is handled gracefully
(i.e., there's no assumption that the statement does have
a basic block). */
strncpy (p->a, "1234", sizeof p->a - 1); /* { dg-warning "\\\[-Wstringop-truncation" } */
}
/* Verify a strncpy call in a basic block with no predecessor or
successor. */
void no_pred_succ (struct A *p, const struct A *q)
{
strncpy (p->a, q->a, sizeof p->a - 1); /* { dg-warning "\\\[-Wstringop-truncation" } */
}
/* Verify a strncpy call in a basic block with no successor. */
void no_succ (struct A *p, const struct A *q)
{
if (q->a)
strncpy (p->a, q->a, sizeof p->a - 1); /* { dg-warning "\\\[-Wstringop-truncation" } */
}
/* Verify a strncpy call in a basic block with nul assignment in
a successor block. */
void succ (struct A *p, const struct A *q)
{
/* Verify that the assignment suppresses the warning for the conditional
strcnpy call. The conditional should be folded to true since the
address of an array can never be null (see bug 84470). */
if (q->a)
strncpy (p->a, q->a, sizeof p->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation" } */
p->a[sizeof p->a - 1] = 0;
}
void succ_2 (struct A *p, const struct A *q, int i)
{
/* Same as above but with a conditional that cannot be eliminated. */
if (i < 0)
strncpy (p->a, q->a, sizeof p->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation" } */
p->a[sizeof p->a - 1] = 0;
}
/* Verify a strncpy call in a basic block with nul assignment in
the next successor block. */
int next_succ (struct A *p, const struct A *q, int i, int j)
{
/* Same as above but with a nested conditionals with else clauses. */
if (i < 0)
{
if (j < 0)
strncpy (p->a, q->a, sizeof p->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation" } */
}
else
__builtin_strcpy (p->a, q->a);
p->a[sizeof p->a - 1] = 0;
return 0;
}
int next_succ_1 (struct A *p, const struct A *q, int i, int j)
{
/* Same as above but with a nested conditionals with else clauses. */
if (i < 0)
{
if (j < 0)
strncpy (p->a, q->a, sizeof p->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation" } */
else
strncpy (p->a, q->a, sizeof p->a - 2); /* { dg-bogus "\\\[-Wstringop-truncation" } */
}
p->a[sizeof p->a - 2] = 0;
return 1;
}
int next_succ_2 (struct A *p, const struct A *q, int i, int j)
{
/* Same as above but with a nested conditionals with else clauses. */
if (i < 0)
{
if (j < 0)
strncpy (p->a, q->a, sizeof p->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation" } */
else
strncpy (p->a, q->a, sizeof p->a - 2); /* { dg-bogus "\\\[-Wstringop-truncation" } */
}
else
__builtin_strcpy (p->a, q->a);
p->a[sizeof p->a - 2] = 0;
return 2;
}
void cond_succ_warn (struct A *p, const struct A *q, int i)
{
/* Verify that a conditional assignment doesn't suppress the warning. */
strncpy (p->a, q->a, sizeof p->a - 1); /* { dg-warning "\\\[-Wstringop-truncation" } */
if (i < 0)
p->a[sizeof p->a - 1] = 0;
}
void cond_succ_nowarn (struct A *p, const struct A *q)
{
/* Verify that distinct but provably equivalent conditionals are
recognized and don't trigger the warning. */
if (p != q)
strncpy (p->a, q->a, sizeof p->a - 1);
if (p->a != q->a)
p->a[sizeof p->a - 1] = 0;
}
......@@ -1856,8 +1856,33 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt)
avoid the truncation warning. */
gsi_next_nondebug (&gsi);
gimple *next_stmt = gsi_stmt (gsi);
if (!next_stmt)
{
/* When there is no statement in the same basic block check
the immediate successor block. */
if (basic_block bb = gimple_bb (stmt))
{
if (single_succ_p (bb))
{
/* For simplicity, ignore blocks with multiple outgoing
edges for now and only consider successor blocks along
normal edges. */
edge e = EDGE_SUCC (bb, 0);
if (!(e->flags & EDGE_ABNORMAL))
{
gsi = gsi_start_bb (e->dest);
next_stmt = gsi_stmt (gsi);
if (next_stmt && is_gimple_debug (next_stmt))
{
gsi_next_nondebug (&gsi);
next_stmt = gsi_stmt (gsi);
}
}
}
}
}
if (!gsi_end_p (gsi) && is_gimple_assign (next_stmt))
if (next_stmt && is_gimple_assign (next_stmt))
{
tree lhs = gimple_assign_lhs (next_stmt);
tree_code code = TREE_CODE (lhs);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment