Hi,

Yes of course, I tested many days ago since regtesting takes several days
on my box, I should have retested !
But I got an account for the compile farm today, so I'm on it immediately,
I also see a divergence in the warnings on my box.

Thanks for the report !
Sincerely sorry,
Benjamin.

On Thu, Jun 8, 2023 at 7:53 PM Maxim Kuvyrkov <maxim.kuvyr...@linaro.org>
wrote:

> > On Jun 6, 2023, at 15:48, Benjamin Priour via Gcc-patches <
> gcc-patches@gcc.gnu.org> wrote:
> >
> > From: Benjamin Priour <vultk...@gcc.gnu.org>
> >
> > This patch enchances -Wanalyzer-out-of-bounds that is no longer paired
> > with a -Wanalyzer-use-of-uninitialized-value on out-of-bounds-read.
> >
> > This also fixes PR analyzer/109437.
> > Before there could always be at most one OOB-read warning per frame
> because
> > -Wanalyzer-use-of-uninitialized-value always terminates the analysis
> > path.
> >
> > PR analyzer/109439
> >
> > gcc/analyzer/ChangeLog:
> >
> > * bounds-checking.cc (region_model::check_symbolic_bounds):
> >          Returns whether the BASE_REG region access was OOB.
> > (region_model::check_region_bounds): Likewise.
> > * region-model.cc (region_model::get_store_value): Creates an
> >          unknown svalue on OOB-read access to REG.
> > (region_model::check_region_access): Returns whether an
> > unknown svalue needs be created.
> > (region_model::check_region_for_read): Passes
> > check_region_access return value.
> > * region-model.h: Update prior function definitions.
> >
> > gcc/testsuite/ChangeLog:
> >
> > * gcc.dg/analyzer/out-of-bounds-2.c: Cleaned test for
> >          uninitialized-value warning.
> > * gcc.dg/analyzer/out-of-bounds-5.c: Likewise.
> > * gcc.dg/analyzer/pr101962.c: Likewise.
> > * gcc.dg/analyzer/realloc-5.c: Likewise.
> > * gcc.dg/analyzer/pr109439.c: New test.
> > ---
>
> Hi Benjamin,
>
> This patch makes two tests fail on arm-linux-gnueabihf.  Probably, they
> need to be updated as well.  Would you please investigate?  Let me know if
> it doesn't easily reproduce for you, and I'll help.
>
> === g++ tests ===
>
> Running g++:g++.dg/analyzer/analyzer.exp ...
> FAIL: g++.dg/analyzer/pr100244.C -std=c++14 (test for warnings, line 17)
> FAIL: g++.dg/analyzer/pr100244.C -std=c++17 (test for warnings, line 17)
> FAIL: g++.dg/analyzer/pr100244.C -std=c++20 (test for warnings, line 17)
>
> === gcc tests ===
>
> Running gcc:gcc.dg/analyzer/analyzer.exp ...
> FAIL: gcc.dg/analyzer/pr101962.c (test for warnings, line 19)
>
> Thanks,
>
> --
> Maxim Kuvyrkov
> https://www.linaro.org
>
>
>
> > gcc/analyzer/bounds-checking.cc               | 30 +++++++++++++------
> > gcc/analyzer/region-model.cc                  | 22 +++++++++-----
> > gcc/analyzer/region-model.h                   |  8 ++---
> > .../gcc.dg/analyzer/out-of-bounds-2.c         |  1 -
> > .../gcc.dg/analyzer/out-of-bounds-5.c         |  2 --
> > gcc/testsuite/gcc.dg/analyzer/pr101962.c      |  1 -
> > gcc/testsuite/gcc.dg/analyzer/pr109439.c      | 12 ++++++++
> > gcc/testsuite/gcc.dg/analyzer/realloc-5.c     |  1 -
> > 8 files changed, 51 insertions(+), 26 deletions(-)
> > create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr109439.c
> >
> > diff --git a/gcc/analyzer/bounds-checking.cc
> b/gcc/analyzer/bounds-checking.cc
> > index 3bf542a8eba..479b8e4b88d 100644
> > --- a/gcc/analyzer/bounds-checking.cc
> > +++ b/gcc/analyzer/bounds-checking.cc
> > @@ -767,9 +767,11 @@ public:
> >   }
> > };
> >
> > -/* Check whether an access is past the end of the BASE_REG.  */
> > +/* Check whether an access is past the end of the BASE_REG.
> > +  Return TRUE if the access was valid, FALSE otherwise.
> > +*/
> >
> > -void
> > +bool
> > region_model::check_symbolic_bounds (const region *base_reg,
> >     const svalue *sym_byte_offset,
> >     const svalue *num_bytes_sval,
> > @@ -800,6 +802,7 @@ region_model::check_symbolic_bounds (const region
> *base_reg,
> >      offset_tree,
> >      num_bytes_tree,
> >      capacity_tree));
> > +    return false;
> >  break;
> > case DIR_WRITE:
> >  ctxt->warn (make_unique<symbolic_buffer_overflow> (base_reg,
> > @@ -807,9 +810,11 @@ region_model::check_symbolic_bounds (const region
> *base_reg,
> >     offset_tree,
> >     num_bytes_tree,
> >     capacity_tree));
> > +    return false;
> >  break;
> > }
> >     }
> > +  return true;
> > }
> >
> > static tree
> > @@ -822,9 +827,11 @@ maybe_get_integer_cst_tree (const svalue *sval)
> >   return NULL_TREE;
> > }
> >
> > -/* May complain when the access on REG is out-of-bounds.  */
> > +/* May complain when the access on REG is out-of-bounds.
> > +   Return TRUE if the access was valid, FALSE otherwise.
> > +*/
> >
> > -void
> > +bool
> > region_model::check_region_bounds (const region *reg,
> >   enum access_direction dir,
> >   region_model_context *ctxt) const
> > @@ -839,14 +846,14 @@ region_model::check_region_bounds (const region
> *reg,
> >      (e.g. because the analyzer did not see previous offsets on the
> latter,
> >      it might think that a negative access is before the buffer).  */
> >   if (base_reg->symbolic_p ())
> > -    return;
> > +    return true;
> >
> >   /* Find out how many bytes were accessed.  */
> >   const svalue *num_bytes_sval = reg->get_byte_size_sval (m_mgr);
> >   tree num_bytes_tree = maybe_get_integer_cst_tree (num_bytes_sval);
> >   /* Bail out if 0 bytes are accessed.  */
> >   if (num_bytes_tree && zerop (num_bytes_tree))
> > -    return;
> > +    return true;
> >
> >   /* Get the capacity of the buffer.  */
> >   const svalue *capacity = get_capacity (base_reg);
> > @@ -877,13 +884,13 @@ region_model::check_region_bounds (const region
> *reg,
> > }
> >       else
> > byte_offset_sval = reg_offset.get_symbolic_byte_offset ();
> > -      check_symbolic_bounds (base_reg, byte_offset_sval, num_bytes_sval,
> > +      return check_symbolic_bounds (base_reg, byte_offset_sval,
> num_bytes_sval,
> >     capacity, dir, ctxt);
> > -      return;
> >     }
> >
> >   /* Otherwise continue to check with concrete values.  */
> >   byte_range out (0, 0);
> > +  bool oob_safe = true;
> >   /* NUM_BYTES_TREE should always be interpreted as unsigned.  */
> >   byte_offset_t num_bytes_unsigned = wi::to_offset (num_bytes_tree);
> >   byte_range read_bytes (offset, num_bytes_unsigned);
> > @@ -899,10 +906,12 @@ region_model::check_region_bounds (const region
> *reg,
> > case DIR_READ:
> >  ctxt->warn (make_unique<concrete_buffer_under_read> (reg, diag_arg,
> >       out));
> > +    oob_safe = false;
> >  break;
> > case DIR_WRITE:
> >  ctxt->warn (make_unique<concrete_buffer_underwrite> (reg, diag_arg,
> >       out));
> > +    oob_safe = false;
> >  break;
> > }
> >     }
> > @@ -911,7 +920,7 @@ region_model::check_region_bounds (const region *reg,
> >      do a symbolic check here because the inequality check does not
> reason
> >      whether constants are greater than symbolic values.  */
> >   if (!cst_capacity_tree)
> > -    return;
> > +    return oob_safe;
> >
> >   byte_range buffer (0, wi::to_offset (cst_capacity_tree));
> >   /* If READ_BYTES exceeds BUFFER, we do have an overflow.  */
> > @@ -929,13 +938,16 @@ region_model::check_region_bounds (const region
> *reg,
> > case DIR_READ:
> >  ctxt->warn (make_unique<concrete_buffer_over_read> (reg, diag_arg,
> >      out, byte_bound));
> > +    oob_safe = false;
> >  break;
> > case DIR_WRITE:
> >  ctxt->warn (make_unique<concrete_buffer_overflow> (reg, diag_arg,
> >     out, byte_bound));
> > +    oob_safe = false;
> >  break;
> > }
> >     }
> > +  return oob_safe;
> > }
> >
> > } // namespace ana
> > diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
> > index 3bb3df2f063..fb96cd54940 100644
> > --- a/gcc/analyzer/region-model.cc
> > +++ b/gcc/analyzer/region-model.cc
> > @@ -2396,7 +2396,8 @@ region_model::get_store_value (const region *reg,
> >   if (reg->empty_p ())
> >     return m_mgr->get_or_create_unknown_svalue (reg->get_type ());
> >
> > -  check_region_for_read (reg, ctxt);
> > +  if (check_region_for_read (reg, ctxt))
> > +    return m_mgr->get_or_create_unknown_svalue(reg->get_type());
> >
> >   /* Special-case: handle var_decls in the constant pool.  */
> >   if (const decl_region *decl_reg = reg->dyn_cast_decl_region ())
> > @@ -2802,19 +2803,22 @@ region_model::get_string_size (const region
> *reg) const
> > }
> >
> > /* If CTXT is non-NULL, use it to warn about any problems accessing REG,
> > -   using DIR to determine if this access is a read or write.  */
> > +   using DIR to determine if this access is a read or write.
> > +   Return TRUE if an UNKNOWN_SVALUE needs be created.  */
> >
> > -void
> > +bool
> > region_model::check_region_access (const region *reg,
> >   enum access_direction dir,
> >   region_model_context *ctxt) const
> > {
> >   /* Fail gracefully if CTXT is NULL.  */
> >   if (!ctxt)
> > -    return;
> > +    return false;
> >
> > +  bool need_unknown_sval = false;
> >   check_region_for_taint (reg, dir, ctxt);
> > -  check_region_bounds (reg, dir, ctxt);
> > +  if (!check_region_bounds (reg, dir, ctxt))
> > +    need_unknown_sval = true;
> >
> >   switch (dir)
> >     {
> > @@ -2827,6 +2831,7 @@ region_model::check_region_access (const region
> *reg,
> >       check_for_writable_region (reg, ctxt);
> >       break;
> >     }
> > +  return need_unknown_sval;
> > }
> >
> > /* If CTXT is non-NULL, use it to warn about any problems writing to
> REG.  */
> > @@ -2838,13 +2843,14 @@ region_model::check_region_for_write (const
> region *dest_reg,
> >   check_region_access (dest_reg, DIR_WRITE, ctxt);
> > }
> >
> > -/* If CTXT is non-NULL, use it to warn about any problems reading from
> REG.  */
> > +/* If CTXT is non-NULL, use it to warn about any problems reading from
> REG.
> > +  Returns TRUE if an unknown svalue needs be created.  */
> >
> > -void
> > +bool
> > region_model::check_region_for_read (const region *src_reg,
> >     region_model_context *ctxt) const
> > {
> > -  check_region_access (src_reg, DIR_READ, ctxt);
> > +  return check_region_access (src_reg, DIR_READ, ctxt);
> > }
> >
> > /* Concrete subclass for casts of pointers that lead to trailing bytes.
> */
> > diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
> > index fe3db0b0c98..12f84b20463 100644
> > --- a/gcc/analyzer/region-model.h
> > +++ b/gcc/analyzer/region-model.h
> > @@ -553,22 +553,22 @@ private:
> >
> >   void check_for_writable_region (const region* dest_reg,
> >  region_model_context *ctxt) const;
> > -  void check_region_access (const region *reg,
> > +  bool check_region_access (const region *reg,
> >    enum access_direction dir,
> >    region_model_context *ctxt) const;
> > -  void check_region_for_read (const region *src_reg,
> > +  bool check_region_for_read (const region *src_reg,
> >      region_model_context *ctxt) const;
> >   void check_region_size (const region *lhs_reg, const svalue *rhs_sval,
> >  region_model_context *ctxt) const;
> >
> >   /* Implemented in bounds-checking.cc  */
> > -  void check_symbolic_bounds (const region *base_reg,
> > +  bool check_symbolic_bounds (const region *base_reg,
> >      const svalue *sym_byte_offset,
> >      const svalue *num_bytes_sval,
> >      const svalue *capacity,
> >      enum access_direction dir,
> >      region_model_context *ctxt) const;
> > -  void check_region_bounds (const region *reg, enum access_direction
> dir,
> > +  bool check_region_bounds (const region *reg, enum access_direction
> dir,
> >    region_model_context *ctxt) const;
> >
> >   void check_call_args (const call_details &cd) const;
> > diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-2.c
> b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-2.c
> > index 1330090f348..336f624441c 100644
> > --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-2.c
> > +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-2.c
> > @@ -82,5 +82,4 @@ void test5 (void)
> >   /* { dg-warning "heap-based buffer over-read" "bounds warning" {
> target *-*-* } test5 } */
> >   /* { dg-message "read of 4 bytes from after the end of the region"
> "num bad bytes note" { target *-*-* } test5 } */
> >
> > -  /* { dg-warning "use of uninitialized value" "uninit warning" {
> target *-*-* } test5 } */
> > }
> > diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-5.c
> b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-5.c
> > index 2a61d8ca236..568f9cad199 100644
> > --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-5.c
> > +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-5.c
> > @@ -68,7 +68,6 @@ void test8 (size_t size, size_t offset)
> >   char dst[size];
> >   memcpy (dst, src, size + offset); /* { dg-line test8 } */
> >   /* { dg-warning "over-read" "warning" { target *-*-* } test8 } */
> > -  /* { dg-warning "use of uninitialized value" "warning" { target *-*-*
> } test8 } */
> >   /* { dg-warning "overflow" "warning" { target *-*-* } test8 } */
> > }
> >
> > @@ -78,7 +77,6 @@ void test9 (size_t size, size_t offset)
> >   int32_t dst[size];
> >   memcpy (dst, src, 4 * size + 1); /* { dg-line test9 } */
> >   /* { dg-warning "over-read" "warning" { target *-*-* } test9 } */
> > -  /* { dg-warning "use of uninitialized value" "warning" { target *-*-*
> } test9 } */
> >   /* { dg-warning "overflow" "warning" { target *-*-* } test9 } */
> > }
> >
> > diff --git a/gcc/testsuite/gcc.dg/analyzer/pr101962.c
> b/gcc/testsuite/gcc.dg/analyzer/pr101962.c
> > index 08c0aba5cbf..b878aad9cf1 100644
> > --- a/gcc/testsuite/gcc.dg/analyzer/pr101962.c
> > +++ b/gcc/testsuite/gcc.dg/analyzer/pr101962.c
> > @@ -24,7 +24,6 @@ test_1 (void)
> >   __analyzer_eval (a != NULL); /* { dg-warning "TRUE" } */
> >   return *a; /* { dg-line test_1 } */
> >
> > -  /* { dg-warning "use of uninitialized value '\\*a'" "warning" {
> target *-*-* } test_1 } */
> >   /* { dg-warning "stack-based buffer over-read" "warning" { target
> *-*-* } test_1 } */
> > }
> >
> > diff --git a/gcc/testsuite/gcc.dg/analyzer/pr109439.c
> b/gcc/testsuite/gcc.dg/analyzer/pr109439.c
> > new file mode 100644
> > index 00000000000..01c87cf171c
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/analyzer/pr109439.c
> > @@ -0,0 +1,12 @@
> > +int would_like_only_oob (int i)
> > +{
> > +    int arr[] = {1,2,3,4,5,6,7};
> > +    arr[10] = 9; /* { dg-warning "stack-based buffer overflow" } */
> > +    arr[11] = 15; /* { dg-warning "stack-based buffer overflow" } */
> > +    int y1 = arr[9]; /* { dg-warning "stack-based buffer over-read" } */
> > +            /* { dg-bogus "use of uninitialized value" "" { target
> *-*-* } .-1 } */
> > +
> > +    arr[18] = 15; /* { dg-warning "stack-based buffer overflow" } */
> > +
> > +    return y1;
> > +}
> > diff --git a/gcc/testsuite/gcc.dg/analyzer/realloc-5.c
> b/gcc/testsuite/gcc.dg/analyzer/realloc-5.c
> > index 137e05b87aa..f65f2c6ca25 100644
> > --- a/gcc/testsuite/gcc.dg/analyzer/realloc-5.c
> > +++ b/gcc/testsuite/gcc.dg/analyzer/realloc-5.c
> > @@ -40,7 +40,6 @@ void test_1 ()
> >
> >       /* { dg-warning "UNKNOWN" "warning" { target *-*-* } eval } */
> >       /* { dg-warning "heap-based buffer over-read" "warning" { target
> *-*-* } eval } */
> > -      /* { dg-warning "use of uninitialized value" "warning" { target
> *-*-* } eval } */
> >     }
> >
> >   free (q);
> > --
> > 2.34.1
> >
>
>

Reply via email to