diff --git a/gcc/params.opt b/gcc/params.opt index 507d24c2f37..b88e1372005 100644 --- a/gcc/params.opt +++ b/gcc/params.opt @@ -613,6 +613,10 @@ The maximum number of insns in loop header duplicated by the copy loop headers p Common Joined UInteger Var(param_max_modulo_backtrack_attempts) Init(40) Param Optimization The maximum number of backtrack attempts the scheduler should make when modulo scheduling a loop. +-param=min-pagesize= +Common Joined UInteger Var(param_min_pagesize) Init(4096) Param Optimization +Minimum page size for warning purposes. + -param=max-partial-antic-length= Common Joined UInteger Var(param_max_partial_antic_length) Init(100) Param Optimization Maximum length of partial antic set when performing tree pre optimization. diff --git a/gcc/pointer-query.cc b/gcc/pointer-query.cc index 1c3b7329272..4390535ef56 100644 --- a/gcc/pointer-query.cc +++ b/gcc/pointer-query.cc @@ -2243,7 +2243,7 @@ compute_objsize_r (tree ptr, gimple *stmt, bool addr, int ostype, } case ARRAY_REF: - return handle_array_ref (ptr, stmt, addr, ostype, pref, snlim, qry); + return handle_array_ref (ptr, stmt, addr, ostype, pref, snlim, qry); case COMPONENT_REF: return handle_component_ref (ptr, stmt, addr, ostype, pref, snlim, qry); @@ -2264,12 +2264,14 @@ compute_objsize_r (tree ptr, gimple *stmt, bool addr, int ostype, } case INTEGER_CST: - /* Pointer constants other than null are most likely the result - of erroneous null pointer addition/subtraction. Unless zero - is a valid address set size to zero. For null pointers, set - size to the maximum for now since those may be the result of - jump threading. */ - if (integer_zerop (ptr)) + /* Pointer constants other than null smaller than param_min_pagesize + might be the result of erroneous null pointer addition/subtraction. + Unless zero is a valid address set size to zero. For null pointers, + set size to the maximum for now since those may be the result of + jump threading. Similarly, for values >= param_min_pagesize in + order to support (type *) 0x7cdeab00. */ + if (integer_zerop (ptr) + || wi::to_widest (ptr) >= param_min_pagesize) pref->set_max_size_range (); else if (POINTER_TYPE_P (TREE_TYPE (ptr))) { diff --git a/gcc/testsuite/gcc.dg/pr100680.c b/gcc/testsuite/gcc.dg/pr100680.c new file mode 100644 index 00000000000..4b5ffc6565f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100680.c @@ -0,0 +1,31 @@ +/* PR middle-end/100680 */ +/* { dg-do compile { target size32plus } } */ +/* { dg-options "-O2 -Wstringop-overread" } */ + +struct s { + char a[8]; + int i; + long l; +}; + +extern char ea[8]; +static char sa[8] = { 1, 2, 3, 4 }; + +int +test (void) +{ + const struct s *ps = (const struct s *) 0x12345678L; + if (__builtin_memcmp (ps->a, ps->a, 8)) + return 0; + + if (__builtin_memcmp (ps->a, ea, 8)) /* { dg-bogus "exceeds source size 0" } */ + return 0; + + if (__builtin_memcmp (ps->a, sa, 8)) /* { dg-bogus "exceeds source size 0" } */ + return 0; + + if (__builtin_memcmp (ps->a, "abcdABCD", 8)) /* { dg-bogus "exceeds source size 0" } */ + return 0; + + return 1; +} diff --git a/gcc/testsuite/gcc.dg/pr100834.c b/gcc/testsuite/gcc.dg/pr100834.c new file mode 100644 index 00000000000..4bd2691aca7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100834.c @@ -0,0 +1,42 @@ +/* PR tree-optimization/100834 */ +/* { dg-do compile { target size32plus } } */ +/* { dg-options "-O2 -Wall" } */ + +#define PAGE_SIZE 4096 +#define STACK_SIZE PAGE_SIZE + +union registers +{ + struct + { + unsigned long r15, r14, r13, r12, r11, r10, r9, r8; + unsigned long rdi, rsi, rbp, unused, rbx, rdx, rcx, rax; + }; + unsigned long by_index[16]; +}; + +struct per_cpu +{ + union + { + unsigned char stack[STACK_SIZE]; + struct + { + unsigned char __fill[STACK_SIZE - sizeof (union registers)]; + union registers guest_regs; + }; + }; +} __attribute__((aligned (PAGE_SIZE))); + +static inline struct per_cpu * +this_cpu_data (void) +{ + return (struct per_cpu *) 0xdeadbeef; +} + +void +foo (void) +{ + struct per_cpu *cpu_data = this_cpu_data (); + __builtin_memset (&cpu_data->guest_regs, 0, sizeof (cpu_data->guest_regs)); /* { dg-bogus "is out of the bounds" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr99578-1.c b/gcc/testsuite/gcc.dg/pr99578-1.c new file mode 100644 index 00000000000..c31d95dbccb --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr99578-1.c @@ -0,0 +1,26 @@ +/* PR middle-end/99578 */ +/* { dg-do compile { target int32 } } */ +/* { dg-options "-O2 -Warray-bounds" } */ + +struct S { int a, b[4]; }; +struct T { int a, b[8192], c[4]; }; + +void +foo (struct S *p) +{ + if (p) return; + __builtin_memset (p->b, 0, sizeof p->b); /* { dg-warning "offset \\\[0, 15\\\] is out of the bounds \\\[0, 0\\\]" } */ +} + +void +bar (struct T *p) +{ + if (p) return; + __builtin_memset (p->c, 0, sizeof p->c); /* { dg-warning "offset \\\[0, 15\\\] is out of the bounds \\\[0, 0\\\]" "" { xfail *-*-* } } */ +} + +void +baz (void) +{ + __builtin_memset ((void *) 0x8004, 0, 16); /* { dg-bogus "is out of the bounds" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr99578-2.c b/gcc/testsuite/gcc.dg/pr99578-2.c new file mode 100644 index 00000000000..462b606cae1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr99578-2.c @@ -0,0 +1,26 @@ +/* PR middle-end/99578 */ +/* { dg-do compile { target int32 } } */ +/* { dg-options "-O2 -Wstringop-overflow" } */ + +struct S { int a, b[4]; }; +struct T { int a, b[8192], c[4]; }; + +void +foo (struct S *p) +{ + if (p) return; + __builtin_memset (p->b, 0, sizeof p->b); /* { dg-warning "writing 16 bytes into a region of size 0 overflows the destination" } */ +} + +void +bar (struct T *p) +{ + if (p) return; + __builtin_memset (p->c, 0, sizeof p->c); /* { dg-warning "writing 16 bytes into a region of size 0 overflows the destination" "" { xfail *-*-* } } */ +} + +void +baz (void) +{ + __builtin_memset ((void *) 0x8004, 0, 16); /* { dg-bogus "overflows the destination" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr99578-3.c b/gcc/testsuite/gcc.dg/pr99578-3.c new file mode 100644 index 00000000000..ef563243dbf --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr99578-3.c @@ -0,0 +1,13 @@ +/* PR middle-end/99578 */ +/* { dg-do compile { target size32plus } } */ +/* { dg-options "-O2 -Wstringop-overread" } */ + +struct S { unsigned int s; }; +extern struct S v; +extern void *memcpy (void *, const void *, __SIZE_TYPE__); + +void +foo (void) +{ + memcpy (&v, (void *)(0xe8ffc000), sizeof (struct S)); /* { dg-bogus "from a region of size 0" } */ +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr99578-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr99578-1.c new file mode 100644 index 00000000000..030f3bd3cf9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr99578-1.c @@ -0,0 +1,22 @@ +/* PR middle-end/99578 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-not "&MEM" "optimized" } } */ +/* { dg-final { scan-tree-dump-times "PHI <-?1\\\(\[0-9\]+\\\), -?1\\\(\[0-9\]+\\\)>" 2 "optimized" } } */ + +struct S { int a, b[4]; }; +struct T { int a, b[8192], c[4]; }; + +int +foo (struct S *p) +{ + if (p) return -1; + return p->b == (void *)4; +} + +int +bar (struct T *p) +{ + if (p) return -1; + return p->c == (void *)32772; +}