(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
analyzer/
out-of-bounds-container_of.c
       1  /* Further reduced container_of pattern from the Linux Kernel.  */
       2  
       3  struct inner {
       4    /* Don't care */
       5  };
       6  
       7  struct outer {
       8    int i;
       9    struct inner inner_struct;
      10  };
      11  
      12  struct outer *container_of (struct inner *ptr_to_inner)
      13  {
      14    struct outer *ptr_to_outer = ((struct outer *) (((void *) ptr_to_inner) - __builtin_offsetof(struct outer, inner_struct)));
      15    return ptr_to_outer;
      16  }
      17  
      18  int test (struct outer *outer_p, struct inner *inner_p)
      19  {
      20    struct outer test;
      21    test.i = 42;
      22    struct inner test2;
      23    int sum = 0;
      24    struct outer *o;
      25  
      26    /* Symbolic inner struct.  */
      27    o = container_of (inner_p);
      28    sum += o->i; // ok
      29    /* Not ok, but we can't be sure that outer
      30       is actually the container of inner.  */
      31    sum += (o - 1)->i;
      32    /* Symbolic outer struct.  */
      33    o = container_of (&(outer_p->inner_struct));
      34    sum += o->i; // ok
      35    /* Not ok, but indistinguishable from the case above.  */
      36    sum += (o - 1)->i;
      37    /* Concrete outer struct.  */
      38    o = container_of (&(test.inner_struct));
      39    sum += o->i;  // ok
      40    /* Not ok and we do have a concrete region.  */
      41    sum += (o - 1)->i; /* { dg-line testA } */
      42    /* Concrete inner struct, has no container.  */
      43    o = container_of (&test2);
      44    sum += o->i; /* { dg-line testB } */
      45  
      46    return sum;
      47    /* { dg-warning "stack-based buffer under-read" "warning" { target *-*-* } testA } */
      48    /* { dg-message "" "note" { target *-*-* } testA } */
      49    /* { dg-warning "stack-based buffer under-read" "warning" { target *-*-* } testB } */
      50    /* { dg-message "" "note" { target *-*-* } testB } */
      51  }