On Tue, 2026-02-17 at 20:04 +0000, Qing Zhao wrote:
> 
> 
> > On Feb 17, 2026, at 13:26, David Malcolm <[email protected]>
> > wrote:
> > 
> > On Tue, 2026-02-17 at 12:24 -0500, David Malcolm wrote:
> > > On Tue, 2026-02-17 at 16:33 +0000, Qing Zhao wrote:
> > > > Hi, David,
> > > > 
> > > > I am working on PR96503 right now, and the initial
> > > > implementation
> > > > has
> > > > some regression in analyzer as show from the following small
> > > > testing
> > > > case:
> > > > $ cat t.c
> > > > #include <stdlib.h>
> > > > #include <stdio.h>
> > > > #include <stdint.h>
> > > > 
> > > > /* Tests with constant buffer sizes.  */
> > > > 
> > > > void test_2 (void)
> > > > {
> > > >   int32_t *ptr = (int32_t *) malloc (21 * sizeof (int16_t)); /*
> > > > {
> > > > dg-
> > > > line malloc2 } */
> > > >   free (ptr);
> > > > 
> > > >   /* { dg-warning "allocated buffer size is not a multiple of
> > > > the
> > > > pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* }
> > > > malloc2
> > > > }
> > > > */
> > > >   /* { dg-message "42 bytes" "note" { target *-*-* } malloc2 }
> > > > */
> > > >   /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int
> > > > \\*'\\\})?
> > > > here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'"
> > > > "note" { target c } malloc2 } */
> > > >   /* { dg-message "'int32_t\\*' (\\\{aka '(long )?int\\*'\\\})?
> > > > here;
> > > > 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'"
> > > > "note" {
> > > > target c++ } malloc2 } */
> > > > }
> > > > 
> > > > ****Without my change, the IR for the above is:
> > > > 
> > > > void test_2 ()
> > > > {
> > > >   int32_t * ptr;
> > > > 
> > > >   ptr = malloc (42);
> > > >   free (ptr);
> > > > }
> > > > 
> > > > And when compiled with "-fdiagnostics-plain-output -fanalyzer -
> > > > Wanalyzer-too-complex -Wanalyzer-symbol-too-complex -S”:t.c: In
> > > > function ‘test_2’:
> > > > t.c:9:30: warning: allocated buffer size is not a multiple of
> > > > the
> > > > pointee's size [CWE-131] [-Wanalyzer-allocation-size]
> > > > t.c:9:30: note: (1) allocated 42 bytes here
> > > > t.c:9:30: note: (2) assigned to ‘int32_t *’ {aka ‘int *’} here;
> > > > ‘sizeof (int32_t {aka int})’ is ‘4’
> > > > 
> > > > **** with my change, the IR for the above is:
> > > > void test_2 ()
> > > > {
> > > >   int32_t * ptr;
> > > > 
> > > >   _1 = malloc (42);
> > > >   ptr = .ACCESS_WITH_SIZE (_1, 42, 4B, 1);
> > > >   free (ptr);
> > > > }
> > > > 
> > > > And the analyzer cannot detect the warning anymore.
> > > > 
> > > > *****After studying a little bit in analyzer, I realize that I
> > > > might
> > > > need to add the IFN_ACCESS_WITH_SIZE as a known internal
> > > > function
> > > > into
> > > > Analyzer, (similar as malloc), such as:
> > > > 
> > > > kfm.add ("malloc", std::make_unique<kf_malloc> ());
> > > > 
> > > > Is this correct understanding? 
> > > 
> > > Yes, though IFNs use a slightly different subclass and
> > > registration
> > > mechanism - see register_known_functions in analyzer/kf.cc, which
> > > currently has:
> > > 
> > >   /* Internal fns the analyzer has known_functions for.  */
> > >   {
> > >     kfm.add (IFN_BUILTIN_EXPECT, std::make_unique<kf_expect> ());
> > >   }
> > > 
> > > You'll want to add something similar for IFN_ACCESS_WITH_SIZE.
> > > 
> > > > I also need to define a “kf_access_with_size” class similar as
> > > > “kf_malloc” and define the kf_access_with_size::impl_call_pre
> > > > as
> > > > well?
> > > 
> > > Yes.  Looks like you'll want to use:
> > >   model->deref_value
> > > to get at the region pointed to by the pointer, and 
> > >   model->get_manager ()->get_sized_region () 
> > > to get a region of the correct size for the access at that
> > > address.
> > > 
> > > Normally we'd use model->get_store_value (region) to actually do
> > > the
> > > access and get the contents of memory, which should do the bounds
> > > checking for you.  So the simplest approach is probably to do
> > > that
> > > and
> > > discard the result, or perhaps for efficiency you could just call
> > > check_region_for_read on it (but that might miss some special-
> > > cases
> > > e.g. when the region is zero-sized).
> > 
> > Or if this just a no-op pass through of the param 1, then the
> > behavior
> > of kf_expect might be appropriate.
> 
> IFN_ACCESS_WITH_SIZE should not be a no-op in analyzer.
> From my understanding, it should be treated similar as a “malloc”,
> and the size of the returned pointer 
> Will be represented by 2nd (and 3rd) parameters. 
> Qing

internal-fn.cc has:
/* Expand the IFN_ACCESS_WITH_SIZE function:
   ACCESS_WITH_SIZE (REF_TO_OBJ, REF_TO_SIZE,
                     TYPE_OF_SIZE + ACCESS_MODE, TYPE_SIZE_UNIT for element)
   which returns the REF_TO_OBJ same as the 1st argument;

   [...snip...]

   For each call to a .ACCESS_WITH_SIZE, replace it with its 1st argument.  */

Isn't this more like IFN_BUILTIN_EXPECT than malloc?  I don't see where
memory allocation would take place.  Are you wanting to have it capture
knowledge about the size of the underlying memory region?  If so, then
use region_model::set_dynamic_extents to let the bounds-checking code
know about it.

Sorry if I'm missing something here
Dave

> > 
> > 
> > > 
> > > Dave
> > > 
> > > > 
> > > > What else I need to do in analyzer to resolve this problem?
> > > > 
> > > > Thanks a lot for your help.
> > > > 
> > > > Qing
> 
> 

Reply via email to