gcc/gcc/testsuite/gcc.dg/Walloca-1.c

65 lines
1.4 KiB
C
Raw Normal View History

/* { dg-do compile } */
/* { dg-require-effective-target alloca } */
PR c/81117 - Improve buffer overflow checking in strncpy gcc/ChangeLog: PR c/81117 * builtins.c (compute_objsize): Handle arrays that compute_builtin_object_size likes to fail for. Make extern. * builtins.h (compute_objsize): Declare. (check_strncpy_sizes): New function. (expand_builtin_strncpy): Call check_strncpy_sizes. * gimple-fold.c (gimple_fold_builtin_strncpy): Implement -Wstringop-truncation. (gimple_fold_builtin_strncat): Same. * gimple.c (gimple_build_call_from_tree): Set call location. * tree-ssa-strlen.c (strlen_to_stridx): New global variable. (maybe_diag_bound_equal_length, is_strlen_related_p): New functions. (handle_builtin_stxncpy, handle_builtin_strncat): Same. (handle_builtin_strlen): Use strlen_to_stridx. (strlen_optimize_stmt): Handle flavors of strncat, strncpy, and stpncpy. Use strlen_to_stridx. (pass_strlen::execute): Release strlen_to_stridx. * doc/invoke.texi (-Wsizeof-pointer-memaccess): Document enhancement. (-Wstringop-truncation): Document new option. gcc/ada/ChangeLog: PR c/81117 * ada/adadecode.c (__gnat_decode): Use memcpy instead of strncpy. * ada/argv.c (__gnat_fill_arg, __gnat_fill_env): Same. gcc/c-family/ChangeLog: PR c/81117 * c-common.c (catenate_strings): Use memcpy instead of strncpy. * c-warn.c (sizeof_pointer_memaccess_warning): Handle arrays. * c.opt (-Wstringop-truncation): New option. gcc/fortran/ChangeLog: PR c/81117 * gcc/fortran/decl.c (build_sym): Use strcpy instead of strncpy. gcc/objc/ChangeLog: PR c/81117 * objc-encoding.c (encode_type): Use memcpy instead of strncpy. gcc/testsuite/ChangeLog: PR c/81117 * c-c++-common/Wsizeof-pointer-memaccess3.c: New test. * c-c++-common/Wstringop-overflow.c: Same. * c-c++-common/Wstringop-truncation.c: Same. * c-c++-common/Wsizeof-pointer-memaccess2.c: Adjust. * c-c++-common/attr-nonstring-2.c: New test. * g++.dg/torture/Wsizeof-pointer-memaccess1.C: Adjust. * g++.dg/torture/Wsizeof-pointer-memaccess2.C: Same. * gcc.dg/torture/pr63554.c: Same. * gcc.dg/Walloca-1.c: Disable macro tracking. From-SVN: r254630
2017-11-10 17:35:26 +01:00
/* { dg-options "-Walloca-larger-than=2000 -O2 -ftrack-macro-expansion=0" } */
#define alloca __builtin_alloca
typedef __SIZE_TYPE__ size_t;
extern size_t strlen(const char *);
extern void useit (char *);
int num;
void foo1 (size_t len, size_t len2, size_t len3)
{
int i;
for (i=0; i < 123; ++i)
{
char *s = alloca (566); /* { dg-warning "'alloca' within a loop" } */
useit (s);
}
char *s = alloca (123);
useit (s); // OK, constant argument to alloca
Fix discrepancy in Walloca test on 32-bit systems. There is a discrepancy in the way we report -Walloca-larger-than= errors on 32-bit versus 64-bit architectures, due to the nature of ranges derived from a cast operation. For the Walloca-1 tests on 64-bits we get: int num.0_1; long unsigned int _2; <bb 2> [local count: 1073741824]: num.0_1 = num; _2 = (long unsigned int) num.0_1; s_8 = __builtin_alloca (_2); Because of the cast of a 32-bit quantity into a 64-bit quantity in _2, ranger calculates its range as: long unsigned int [0, 2147483647][18446744071562067968, +INF] Thus excluding the numbers that can't exist in _2. This causes the Walloca pass to report that the argument to alloca may be too large. However, for -m32 on x86, the gimple is: int num.0_1; unsigned int num.1_2; <bb 2> [local count: 1073741824]: num.0_1 = num; num.1_2 = (unsigned int) num.0_1; s_8 = __builtin_alloca (num.1_2); Since num.0_1 and num.1_2 are of the same size, we cannot determine any useful range, so we return VARYING. In the Walloca pass, VARYING basically means "unbounded" (no known bounds for the alloca call argument). So on 32-bits, the error message issued is slightly different: warning: unbounded use of ‘alloca’ versus on 64-bits, where due to the cast, it is: warning: argument to ‘alloca’ may be too large In reality both versions of the IL show an unbounded call, but in one version (64-bits) we can exclude some values so we assume the range was provided, but it was out of bounds. I've mentioned various times that all these diagnostics passes (alloca, restrict, printf, etc), could benefit from less specific error messages since what we have can potentially confuse the user. However, no consensus has been reached on how to report these things. In the meantime, this patch adjusts the testcase to accept both variants. gcc/testsuite/ChangeLog: * gcc.dg/Walloca-1.c: Adjust for 32-bits.
2020-10-21 08:47:03 +02:00
s = alloca (num); // { dg-warning "\(may be too large|unbounded use\)" }
useit (s);
s = alloca (30000); /* { dg-warning "is too large" } */
useit (s);
if (len < 2000)
{
s = alloca(len); // OK, bounded
useit (s);
}
if (len + len2 < 2000) // OK, bounded
{
s = alloca(len + len2);
useit (s);
}
if (len3 <= 2001)
{
s = alloca(len3); /* { dg-warning "may be too large" } */
useit(s);
}
}
void foo2 (__SIZE_TYPE__ len)
{
// Test that a direct call to __builtin_alloca_with_align is not confused
// with a VLA.
void *p = __builtin_alloca_with_align (len, 8); // { dg-warning "unbounded use of 'alloca'" }
useit (p);
}
void foo3 (unsigned char a)
{
if (a == 0)
useit (__builtin_alloca (a)); // { dg-warning "argument to 'alloca' is zero" }
}