(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
analyzer/
leak-pr108045-without-call-summaries.c
       1  /* { dg-additional-options "-fno-analyzer-call-summaries" } */
       2  /* { dg-additional-options "-Wno-analyzer-too-complex" } */
       3  
       4  typedef __SIZE_TYPE__ size_t;
       5  #define NULL ((void *)0)
       6  
       7  /* data structures */
       8  
       9  struct screen_s {
      10  	size_t rows;
      11  	size_t cols;
      12  	char **data;
      13  };
      14  
      15  struct context_s {
      16  	struct screen_s *scr;
      17  };
      18  
      19  /* global context variable */
      20  
      21  static struct context_s *ctx;
      22  
      23  /* prototypes */
      24  
      25  struct screen_s *screen_create(size_t cols, size_t rows);
      26  void screen_destroy(struct screen_s *scr);
      27  void resize_screen(size_t cols, size_t rows);
      28  
      29  /* functions */
      30  
      31  struct screen_s *screen_create(size_t cols, size_t rows)
      32  {
      33  	struct screen_s *result = NULL;
      34  
      35  	result = __builtin_calloc(1, sizeof(*result));
      36  	if (!result)
      37  		return NULL;
      38  
      39  	result->cols = cols;
      40  	result->rows = rows;
      41  
      42  	/* make one allocation which will be accessed like a 2D array */
      43  	result->data = __builtin_calloc(rows, sizeof(result->data) + sizeof(*result->data) * cols);
      44  	if (!result->data) {
      45  		__builtin_free(result);
      46  		return NULL;
      47  	}
      48  
      49  	/* obtain pointer to start of data area */
      50  	char *ptr = (char *)(result->data + rows);
      51  
      52  	/* setup pointers for each row of data to allow 2D array access */
      53  	for (size_t row = 0; row < rows; row++)
      54  		result->data[row] = (ptr + row * cols);
      55  	/* array can now be accessed like data[row][col] */
      56  
      57  	return result;
      58  }
      59  
      60  void screen_destroy(struct screen_s *scr)
      61  {
      62  	if (!scr)
      63  		return;
      64  
      65  	__builtin_free(scr->data);
      66  
      67  	scr->data = NULL;
      68  	scr->rows = 0;
      69  	scr->cols = 0;
      70  
      71  	__builtin_free(scr); /* { dg-bogus "leak" } */
      72  }
      73  
      74  void resize_screen(size_t cols, size_t rows)
      75  {
      76  	/* create a new screen */
      77  	struct screen_s *new_scr = NULL;
      78  	new_scr = screen_create(cols, rows); /* { dg-bogus "leak" } */
      79  	if (!new_scr) {
      80  		return;
      81  	}
      82  
      83  	/* swap the old screen with the new one */
      84  	struct screen_s *old_scr = ctx->scr;
      85  	ctx->scr = new_scr;
      86  
      87  	/* omitted: copy the old screen contents to the new screen */
      88  
      89  	/* free the old screen */
      90  	screen_destroy(old_scr);
      91  }
      92  
      93  int main(void)
      94  {
      95  	ctx = __builtin_calloc(1, sizeof(*ctx));
      96  	if (!ctx)
      97  		__builtin_abort();
      98  
      99  	ctx->scr = screen_create(80, 25); /* { dg-bogus "leak" } */
     100  	resize_screen(100, 20);
     101  
     102  	/* tidy up and quit */
     103  	screen_destroy(ctx->scr);
     104  	__builtin_free(ctx);
     105  	ctx = NULL;
     106  	return 0;
     107  }