Commit 1ebf0641 by Bernd Edlinger Committed by Jeff Law

re PR middle-end/87053 (wrong code with c_strlen)

gcc:
2018-08-22  Bernd Edlinger  <bernd.edlinger@hotmail.de>

	PR middle-end/87053
	* builtins.c (c_strlen): Improve range checks.

testsuite:
2018-08-22  Bernd Edlinger  <bernd.edlinger@hotmail.de>

	PR middle-end/87053
	* gcc.c-torture/execute/pr87053.c: New test.

From-SVN: r263968
parent d66ab7d1
2018-08-29 Bernd Edlinger <bernd.edlinger@hotmail.de>
PR middle-end/87053
* builtins.c (c_strlen): Improve range checks.
2018-08-29 Martin Sebor <msebor@redhat.com> 2018-08-29 Martin Sebor <msebor@redhat.com>
Jeff Law <law@redhat.com> Jeff Law <law@redhat.com>
......
...@@ -567,7 +567,7 @@ string_length (const void *ptr, unsigned eltsize, unsigned maxelts) ...@@ -567,7 +567,7 @@ string_length (const void *ptr, unsigned eltsize, unsigned maxelts)
tree tree
c_strlen (tree src, int only_value, unsigned eltsize) c_strlen (tree src, int only_value, unsigned eltsize)
{ {
gcc_assert (eltsize == 1 || eltsize == 2 || eltsize == 4); gcc_checking_assert (eltsize == 1 || eltsize == 2 || eltsize == 4);
STRIP_NOPS (src); STRIP_NOPS (src);
if (TREE_CODE (src) == COND_EXPR if (TREE_CODE (src) == COND_EXPR
&& (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0)))) && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
...@@ -656,10 +656,10 @@ c_strlen (tree src, int only_value, unsigned eltsize) ...@@ -656,10 +656,10 @@ c_strlen (tree src, int only_value, unsigned eltsize)
a null character if we can represent it as a single HOST_WIDE_INT. */ a null character if we can represent it as a single HOST_WIDE_INT. */
if (byteoff == 0) if (byteoff == 0)
eltoff = 0; eltoff = 0;
else if (! tree_fits_shwi_p (byteoff)) else if (! tree_fits_uhwi_p (byteoff) || tree_to_uhwi (byteoff) % eltsize)
eltoff = -1; eltoff = -1;
else else
eltoff = tree_to_shwi (byteoff) / eltsize; eltoff = tree_to_uhwi (byteoff) / eltsize;
/* If the offset is known to be out of bounds, warn, and call strlen at /* If the offset is known to be out of bounds, warn, and call strlen at
runtime. */ runtime. */
...@@ -691,6 +691,11 @@ c_strlen (tree src, int only_value, unsigned eltsize) ...@@ -691,6 +691,11 @@ c_strlen (tree src, int only_value, unsigned eltsize)
unsigned len = string_length (ptr + eltoff * eltsize, eltsize, unsigned len = string_length (ptr + eltoff * eltsize, eltsize,
strelts - eltoff); strelts - eltoff);
/* Don't know what to return if there was no zero termination.
Ideally this would turn into a gcc_checking_assert over time. */
if (len > maxelts - eltoff)
return NULL_TREE;
return ssize_int (len); return ssize_int (len);
} }
......
2018-08-29 Bernd Edlinger <bernd.edlinger@hotmail.de>
PR middle-end/87053
* gcc.c-torture/execute/pr87053.c: New test.
2018-08-29 Jakub Jelinek <jakub@redhat.com> 2018-08-29 Jakub Jelinek <jakub@redhat.com>
PR c++/87095 PR c++/87095
......
/* PR middle-end/87053 */
const union
{ struct {
char x[4];
char y[4];
};
struct {
char z[8];
};
} u = {{"1234", "567"}};
int main ()
{
if (__builtin_strlen (u.z) != 7)
__builtin_abort ();
}
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