public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Jakub Jelinek <jakub@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc r11-9731] Allow (void *) 0xdeadbeef accesses without warnings [PR99578] Date: Tue, 29 Mar 2022 05:54:24 +0000 (GMT) [thread overview] Message-ID: <20220329055424.3DBC6385DC06@sourceware.org> (raw) https://gcc.gnu.org/g:91f7d7e1bb6827bf8e0b7ba7eb949953a5b1bd18 commit r11-9731-g91f7d7e1bb6827bf8e0b7ba7eb949953a5b1bd18 Author: Jakub Jelinek <jakub@redhat.com> Date: Fri Mar 18 18:58:06 2022 +0100 Allow (void *) 0xdeadbeef accesses without warnings [PR99578] Starting with GCC11 we keep emitting false positive -Warray-bounds or -Wstringop-overflow etc. warnings on widely used *(type *)0x12345000 style accesses (or memory/string routines to such pointers). This is a standard programming style supported by all C/C++ compilers I've ever tried, used mostly in kernel or DSP programming, but sometimes also together with mmap MAP_FIXED when certain things, often I/O registers but could be anything else too are known to be present at fixed addresses. Such INTEGER_CST addresses can appear in code either because a user used it like that (in which case it is fine) or because somebody used pointer arithmetics (including &((struct whatever *)NULL)->field) on a NULL pointer. The middle-end warning code wrongly assumes that the latter case is what is very likely, while the former is unlikely and users should change their code. The following patch adds a min-pagesize param defaulting to 4KB, and treats INTEGER_CST addresses smaller than that as assumed results of pointer arithmetics from NULL while addresses equal or larger than that as expected user constant addresses. For GCC 13 we can represent results from pointer arithmetics on NULL using &MEM[(void*)0 + offset] instead of (void*)offset INTEGER_CSTs. 2022-03-18 Jakub Jelinek <jakub@redhat.com> PR middle-end/99578 PR middle-end/100680 PR tree-optimization/100834 * params.opt (--param=min-pagesize=): New parameter. * builtins.c (compute_objsize_r) <case INTEGER_CST>: Use maximum object size instead of zero for pointer constants equal or larger than min-pagesize. * gcc.dg/tree-ssa/pr99578-1.c: New test. * gcc.dg/pr99578-1.c: New test. * gcc.dg/pr99578-2.c: New test. * gcc.dg/pr99578-3.c: New test. * gcc.dg/pr100680.c: New test. * gcc.dg/pr100834.c: New test. (cherry picked from commit 32ca611c42658948f1b8883994796f35e8b4e74d) Diff: --- gcc/builtins.c | 13 ++++++---- gcc/params.opt | 4 +++ gcc/testsuite/gcc.dg/pr100680.c | 31 +++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr100834.c | 42 +++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr99578-1.c | 26 +++++++++++++++++++ gcc/testsuite/gcc.dg/pr99578-2.c | 26 +++++++++++++++++++ gcc/testsuite/gcc.dg/pr99578-3.c | 13 ++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr99578-1.c | 22 ++++++++++++++++ 8 files changed, 172 insertions(+), 5 deletions(-) diff --git a/gcc/builtins.c b/gcc/builtins.c index fb90c5d4a7c..f36ac1ef4a5 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -5605,11 +5605,14 @@ compute_objsize_r (tree ptr, int ostype, access_ref *pref, if (code == INTEGER_CST) { - /* Pointer constants other than null are most likely the result - of erroneous null pointer addition/subtraction. 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 pref->sizrng[0] = pref->sizrng[1] = 0; diff --git a/gcc/params.opt b/gcc/params.opt index 8ba281b4cfa..5f03a386c37 100644 --- a/gcc/params.opt +++ b/gcc/params.opt @@ -598,6 +598,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/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; +}
reply other threads:[~2022-03-29 5:54 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20220329055424.3DBC6385DC06@sourceware.org \ --to=jakub@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).