Check to see if null pointer is dereferenceable [PR102630]. Resolves: PR middle-end/102630 - Spurious -Warray-bounds with named address space gcc/ChangeLog: PR middle-end/102630 * pointer-query.cc (compute_objsize_r): Handle named address spaces. gcc/testsuite/ChangeLog: PR middle-end/102630 * gcc.dg/Warray-bounds-90.c: New test. diff --git a/gcc/pointer-query.cc b/gcc/pointer-query.cc index 83b1f0fc866..910f452868e 100644 --- a/gcc/pointer-query.cc +++ b/gcc/pointer-query.cc @@ -41,6 +41,7 @@ #include "pointer-query.h" #include "tree-pretty-print.h" #include "tree-ssanames.h" +#include "target.h" static bool compute_objsize_r (tree, int, access_ref *, ssa_name_limit_t &, pointer_query *); @@ -1869,13 +1870,24 @@ 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. */ + 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)) pref->set_max_size_range (); + else if (POINTER_TYPE_P (TREE_TYPE (ptr))) + { + tree deref_type = TREE_TYPE (TREE_TYPE (ptr)); + addr_space_t as = TYPE_ADDR_SPACE (deref_type); + if (targetm.addr_space.zero_address_valid (as)) + pref->set_max_size_range (); + else + pref->sizrng[0] = pref->sizrng[1] = 0; + } else pref->sizrng[0] = pref->sizrng[1] = 0; + pref->ref = ptr; return true; diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-90.c b/gcc/testsuite/gcc.dg/Warray-bounds-90.c new file mode 100644 index 00000000000..93461d4b238 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-90.c @@ -0,0 +1,31 @@ +/* PR middle-end/102630 - spurious -Warray-bounds with named address space + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +void sink (void*, ...); +#define sink(...) sink (0, __VA_ARGS__) + + +void test_generic_null (void) +{ + // We want some warning here but -Warray-bounds may not be it. + *(char*)0 = 0; // { dg-warning "" "pr??????" { xfail *-*-* } } +} + +void test_generic_cstaddr (void) +{ + /* We get -Warray-bounds (-Wstringop-overflow in GCC 11) but some + other warning might be preferable. */ + *(char*)1234 = 1; // { dg-warning "" } +} + + +void test_named_address_space_null (void) +{ + *(char __seg_fs*)0 = 0; // no warning (intentional) +} + +void test_named_address_space_cstaddr (void) +{ + *(char __seg_fs*)1234 = 0; // { dg-bogus "-Warray-bounds" } +}