PR middle-end/78245 - missing -Wformat-length on an overflow of a dynamically allocated buffer
gcc/testsuite/ChangeLog: PR middle-end/78245 * gcc.dg/tree-ssa/builtin-sprintf-warn-3.c: Add tests. gcc/ChangeLog: PR middle-end/78245 * gimple-ssa-sprintf.c (get_destination_size): Call {init,fini}object_sizes. * tree-object-size.c (addr_object_size): Adjust. (pass_through_call): Adjust. (pass_object_sizes::execute): Adjust. * tree-object-size.h (fini_object_sizes): Declare. From-SVN: r244293
This commit is contained in:
parent
b9f4757f8e
commit
eb07c7cffb
|
@ -2723,6 +2723,9 @@ get_destination_size (tree dest)
|
||||||
a member array as opposed to the whole enclosing object), otherwise
|
a member array as opposed to the whole enclosing object), otherwise
|
||||||
use type-zero object size to determine the size of the enclosing
|
use type-zero object size to determine the size of the enclosing
|
||||||
object (the function fails without optimization in this type). */
|
object (the function fails without optimization in this type). */
|
||||||
|
|
||||||
|
init_object_sizes ();
|
||||||
|
|
||||||
int ost = optimize > 0;
|
int ost = optimize > 0;
|
||||||
unsigned HOST_WIDE_INT size;
|
unsigned HOST_WIDE_INT size;
|
||||||
if (compute_builtin_object_size (dest, ost, &size))
|
if (compute_builtin_object_size (dest, ost, &size))
|
||||||
|
@ -3120,6 +3123,8 @@ pass_sprintf_length::execute (function *fun)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fini_object_sizes ();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
/* { dg-do compile } */
|
/* Verify that all sprintf built-ins detect overflow involving directives
|
||||||
/* { dg-options "-O2 -Wformat -Wformat-length=1 -ftrack-macro-expansion=0" } */
|
with non-constant arguments known to be constrained by some range of
|
||||||
|
values, and even when writing into dynamically allocated buffers.
|
||||||
|
-O2 (-ftree-vrp) is necessary for the tests involving ranges to pass,
|
||||||
|
otherwise -O1 is sufficient.
|
||||||
|
{ dg-do compile }
|
||||||
|
{ dg-options "-O2 -Wformat -Wformat-length=1 -ftrack-macro-expansion=0" } */
|
||||||
|
|
||||||
typedef __SIZE_TYPE__ size_t;
|
typedef __SIZE_TYPE__ size_t;
|
||||||
|
|
||||||
|
@ -9,18 +14,26 @@ typedef __SIZE_TYPE__ size_t;
|
||||||
|
|
||||||
#define bos(x) __builtin_object_size (x, 0)
|
#define bos(x) __builtin_object_size (x, 0)
|
||||||
|
|
||||||
|
/* Defined (and redefined) to the allocation function to use, either
|
||||||
|
malloc, or alloca, or a VLA. */
|
||||||
|
#define ALLOC(p, n) (p) = __builtin_malloc (n)
|
||||||
|
|
||||||
|
/* Defined (and redefined) to the sprintf function to exercise. */
|
||||||
|
#define TEST_SPRINTF(d, maxsize, objsize, fmt, ...) \
|
||||||
|
__builtin___sprintf_chk (d, 0, objsize, fmt, __VA_ARGS__)
|
||||||
|
|
||||||
#define T(bufsize, fmt, ...) \
|
#define T(bufsize, fmt, ...) \
|
||||||
do { \
|
do { \
|
||||||
if (!LINE || __LINE__ == LINE) \
|
if (!LINE || __LINE__ == LINE) \
|
||||||
{ \
|
{ \
|
||||||
char *d = (char *)__builtin_malloc (bufsize); \
|
char *d; \
|
||||||
__builtin___sprintf_chk (d, 0, bos (d), fmt, __VA_ARGS__); \
|
ALLOC (d, bufsize); \
|
||||||
|
TEST_SPRINTF (d, 0, bos (d), fmt, __VA_ARGS__); \
|
||||||
sink (d); \
|
sink (d); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
void
|
void sink (void*);
|
||||||
sink (void*);
|
|
||||||
|
|
||||||
/* Identity function to verify that the checker figures out the value
|
/* Identity function to verify that the checker figures out the value
|
||||||
of the operand even when it's not constant (i.e., makes use of
|
of the operand even when it's not constant (i.e., makes use of
|
||||||
|
@ -362,3 +375,88 @@ void test_too_large (char *d, int x, __builtin_va_list va)
|
||||||
__builtin___vsnprintf_chk (d, ptrmax_m1, 0, ptrmax_m1, "%c", va); /* { dg-warning "specified bound \[0-9\]+ exceeds .INT_MAX." "PTRDIFF_MAX - 1" { target lp64 } } */
|
__builtin___vsnprintf_chk (d, ptrmax_m1, 0, ptrmax_m1, "%c", va); /* { dg-warning "specified bound \[0-9\]+ exceeds .INT_MAX." "PTRDIFF_MAX - 1" { target lp64 } } */
|
||||||
__builtin___vsnprintf_chk (d, ptrmax, 0, ptrmax, "%c", va); /* { dg-warning "specified bound \[0-9\]+ exceeds .INT_MAX." "PTRDIFF_MAX" { target lp64 } } */
|
__builtin___vsnprintf_chk (d, ptrmax, 0, ptrmax, "%c", va); /* { dg-warning "specified bound \[0-9\]+ exceeds .INT_MAX." "PTRDIFF_MAX" { target lp64 } } */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Exercise ordinary sprintf with malloc. */
|
||||||
|
#undef TEST_SPRINTF
|
||||||
|
#define TEST_SPRINTF(d, maxsize, objsize, fmt, ...) \
|
||||||
|
__builtin_sprintf (d, fmt, __VA_ARGS__)
|
||||||
|
|
||||||
|
void test_sprintf_malloc (const char *s, const char *t)
|
||||||
|
{
|
||||||
|
#define x x ()
|
||||||
|
|
||||||
|
T (1, "%-s", x ? "" : "1"); /* { dg-warning "nul past the end" } */
|
||||||
|
T (1, "%-s", x ? "1" : ""); /* { dg-warning "nul past the end" } */
|
||||||
|
T (1, "%-s", x ? s : "1"); /* { dg-warning "nul past the end" } */
|
||||||
|
T (1, "%-s", x ? "1" : s); /* { dg-warning "nul past the end" } */
|
||||||
|
T (1, "%-s", x ? s : t);
|
||||||
|
|
||||||
|
T (2, "%-s", x ? "" : "1");
|
||||||
|
T (2, "%-s", x ? "" : s);
|
||||||
|
T (2, "%-s", x ? "1" : "");
|
||||||
|
T (2, "%-s", x ? s : "");
|
||||||
|
T (2, "%-s", x ? "1" : "2");
|
||||||
|
T (2, "%-s", x ? "" : "12"); /* { dg-warning "nul past the end" } */
|
||||||
|
T (2, "%-s", x ? "12" : ""); /* { dg-warning "nul past the end" } */
|
||||||
|
|
||||||
|
T (2, "%-s", x ? "" : "123"); /* { dg-warning "into a region" } */
|
||||||
|
T (2, "%-s", x ? "123" : ""); /* { dg-warning "into a region" } */
|
||||||
|
|
||||||
|
#undef x
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Exercise ordinary sprintf with alloca. */
|
||||||
|
#undef ALLOC
|
||||||
|
#define ALLOC(p, n) (p) = __builtin_alloca (n)
|
||||||
|
|
||||||
|
void test_sprintf_alloca (const char *s, const char *t)
|
||||||
|
{
|
||||||
|
#define x x ()
|
||||||
|
|
||||||
|
T (1, "%-s", x ? "" : "1"); /* { dg-warning "nul past the end" } */
|
||||||
|
T (1, "%-s", x ? "1" : ""); /* { dg-warning "nul past the end" } */
|
||||||
|
T (1, "%-s", x ? s : "1"); /* { dg-warning "nul past the end" } */
|
||||||
|
T (1, "%-s", x ? "1" : s); /* { dg-warning "nul past the end" } */
|
||||||
|
T (1, "%-s", x ? s : t);
|
||||||
|
|
||||||
|
T (2, "%-s", x ? "" : "1");
|
||||||
|
T (2, "%-s", x ? "" : s);
|
||||||
|
T (2, "%-s", x ? "1" : "");
|
||||||
|
T (2, "%-s", x ? s : "");
|
||||||
|
T (2, "%-s", x ? "1" : "2");
|
||||||
|
T (2, "%-s", x ? "" : "12"); /* { dg-warning "nul past the end" } */
|
||||||
|
T (2, "%-s", x ? "12" : ""); /* { dg-warning "nul past the end" } */
|
||||||
|
|
||||||
|
T (2, "%-s", x ? "" : "123"); /* { dg-warning "into a region" } */
|
||||||
|
T (2, "%-s", x ? "123" : ""); /* { dg-warning "into a region" } */
|
||||||
|
|
||||||
|
#undef x
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Exercise ordinary sprintf with a VLA. */
|
||||||
|
#undef ALLOC
|
||||||
|
#define ALLOC(p, n) char vla [i (n)]; (p) = vla
|
||||||
|
|
||||||
|
void test_sprintf_vla (const char *s, const char *t)
|
||||||
|
{
|
||||||
|
#define x x ()
|
||||||
|
|
||||||
|
T (1, "%-s", x ? "" : "1"); /* { dg-warning "nul past the end" } */
|
||||||
|
T (1, "%-s", x ? "1" : ""); /* { dg-warning "nul past the end" } */
|
||||||
|
T (1, "%-s", x ? s : "1"); /* { dg-warning "nul past the end" } */
|
||||||
|
T (1, "%-s", x ? "1" : s); /* { dg-warning "nul past the end" } */
|
||||||
|
T (1, "%-s", x ? s : t);
|
||||||
|
|
||||||
|
T (2, "%-s", x ? "" : "1");
|
||||||
|
T (2, "%-s", x ? "" : s);
|
||||||
|
T (2, "%-s", x ? "1" : "");
|
||||||
|
T (2, "%-s", x ? s : "");
|
||||||
|
T (2, "%-s", x ? "1" : "2");
|
||||||
|
T (2, "%-s", x ? "" : "12"); /* { dg-warning "nul past the end" } */
|
||||||
|
T (2, "%-s", x ? "12" : ""); /* { dg-warning "nul past the end" } */
|
||||||
|
|
||||||
|
T (2, "%-s", x ? "" : "123"); /* { dg-warning "into a region" } */
|
||||||
|
T (2, "%-s", x ? "123" : ""); /* { dg-warning "into a region" } */
|
||||||
|
|
||||||
|
#undef x
|
||||||
|
}
|
||||||
|
|
|
@ -1235,7 +1235,7 @@ init_object_sizes (void)
|
||||||
|
|
||||||
/* Destroy data structures after the object size computation. */
|
/* Destroy data structures after the object size computation. */
|
||||||
|
|
||||||
static void
|
void
|
||||||
fini_object_sizes (void)
|
fini_object_sizes (void)
|
||||||
{
|
{
|
||||||
int object_size_type;
|
int object_size_type;
|
||||||
|
|
|
@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#define GCC_TREE_OBJECT_SIZE_H
|
#define GCC_TREE_OBJECT_SIZE_H
|
||||||
|
|
||||||
extern void init_object_sizes (void);
|
extern void init_object_sizes (void);
|
||||||
|
extern void fini_object_sizes (void);
|
||||||
extern bool compute_builtin_object_size (tree, int, unsigned HOST_WIDE_INT *);
|
extern bool compute_builtin_object_size (tree, int, unsigned HOST_WIDE_INT *);
|
||||||
|
|
||||||
#endif // GCC_TREE_OBJECT_SIZE_H
|
#endif // GCC_TREE_OBJECT_SIZE_H
|
||||||
|
|
Loading…
Reference in New Issue