view gcc/testsuite/gcc.dg/analyzer/analyzer-verbosity-2.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
line wrap: on
line source

/* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-show-caret -fanalyzer-verbosity=2" } */
/* { dg-enable-nn-line-numbers "" } */

#include <stdlib.h>

void calls_free_1 (void *ptr)
{
  free (ptr); /* { dg-warning "double-'free' of 'ptr'" } */
}

void test_1 (void *ptr, int a, int b)
{
  if (a)
    calls_free_1 (ptr);

  if (b)
    {
    }
  else
    calls_free_1 (ptr);
}

/* { dg-begin-multiline-output "" }
   NN |   free (ptr);
      |   ^~~~~~~~~~
  'test_1': events 1-4
    |
    |   NN | void test_1 (void *ptr, int a, int b)
    |      |      ^~~~~~
    |      |      |
    |      |      (1) entry to 'test_1'
    |   NN | {
    |   NN |   if (a)
    |      |      ~
    |      |      |
    |      |      (2) following 'true' branch (when 'a != 0')...
    |   NN |     calls_free_1 (ptr);
    |      |     ~~~~~~~~~~~~~~~~~~
    |      |     |
    |      |     (3) ...to here
    |      |     (4) calling 'calls_free_1' from 'test_1'
    |
    +--> 'calls_free_1': events 5-6
           |
           |   NN | void calls_free_1 (void *ptr)
           |      |      ^~~~~~~~~~~~
           |      |      |
           |      |      (5) entry to 'calls_free_1'
           |   NN | {
           |   NN |   free (ptr);
           |      |   ~~~~~~~~~~
           |      |   |
           |      |   (6) first 'free' here
           |
    <------+
    |
  'test_1': events 7-10
    |
    |   NN |     calls_free_1 (ptr);
    |      |     ^~~~~~~~~~~~~~~~~~
    |      |     |
    |      |     (7) returning to 'test_1' from 'calls_free_1'
    |   NN | 
    |   NN |   if (b)
    |      |      ~
    |      |      |
    |      |      (8) following 'false' branch (when 'b == 0')...
    |......
    |   NN |     calls_free_1 (ptr);
    |      |     ~~~~~~~~~~~~~~~~~~
    |      |     |
    |      |     (9) ...to here
    |      |     (10) passing freed pointer 'ptr' in call to 'calls_free_1' from 'test_1'
    |
    +--> 'calls_free_1': events 11-12
           |
           |   NN | void calls_free_1 (void *ptr)
           |      |      ^~~~~~~~~~~~
           |      |      |
           |      |      (11) entry to 'calls_free_1'
           |   NN | {
           |   NN |   free (ptr);
           |      |   ~~~~~~~~~~
           |      |   |
           |      |   (12) second 'free' here; first 'free' was at (6)
           |
  { dg-end-multiline-output "" } */

void calls_free_2 (void *ptr)
{
  free (ptr); /* { dg-warning "double-'free' of 'ptr'" } */
}

void test_2 (void *ptr, int a, int b)
{
  switch (a)
    {
    default:
      break;
    case 1:
      break;
    case 3:
      calls_free_2 (ptr);
      break;
    }

  switch (b)
    {
    default:
      calls_free_2 (ptr);
      break;
    case 1:
      break;
    case 42:
      break;
    }
}

/* { dg-begin-multiline-output "" }
   NN |   free (ptr);
      |   ^~~~~~~~~~
  'test_2': events 1-4
    |
    |   NN | void test_2 (void *ptr, int a, int b)
    |      |      ^~~~~~
    |      |      |
    |      |      (1) entry to 'test_2'
    |   NN | {
    |   NN |   switch (a)
    |      |   ~~~~~~
    |      |   |
    |      |   (2) following 'case 3:' branch...
    |......
    |   NN |     case 3:
    |      |     ~~~~
    |      |     |
    |      |     (3) ...to here
    |   NN |       calls_free_2 (ptr);
    |      |       ~~~~~~~~~~~~~~~~~~
    |      |       |
    |      |       (4) calling 'calls_free_2' from 'test_2'
    |
    +--> 'calls_free_2': events 5-6
           |
           |   NN | void calls_free_2 (void *ptr)
           |      |      ^~~~~~~~~~~~
           |      |      |
           |      |      (5) entry to 'calls_free_2'
           |   NN | {
           |   NN |   free (ptr);
           |      |   ~~~~~~~~~~
           |      |   |
           |      |   (6) first 'free' here
           |
    <------+
    |
  'test_2': events 7-10
    |
    |   NN |       calls_free_2 (ptr);
    |      |       ^~~~~~~~~~~~~~~~~~
    |      |       |
    |      |       (7) returning to 'test_2' from 'calls_free_2'
    |......
    |   NN |   switch (b)
    |      |   ~~~~~~
    |      |   |
    |      |   (8) following 'default:' branch...
    |   NN |     {
    |   NN |     default:
    |      |     ~~~~~~~
    |      |     |
    |      |     (9) ...to here
    |   NN |       calls_free_2 (ptr);
    |      |       ~~~~~~~~~~~~~~~~~~
    |      |       |
    |      |       (10) passing freed pointer 'ptr' in call to 'calls_free_2' from 'test_2'
    |
    +--> 'calls_free_2': events 11-12
           |
           |   NN | void calls_free_2 (void *ptr)
           |      |      ^~~~~~~~~~~~
           |      |      |
           |      |      (11) entry to 'calls_free_2'
           |   NN | {
           |   NN |   free (ptr);
           |      |   ~~~~~~~~~~
           |      |   |
           |      |   (12) second 'free' here; first 'free' was at (6)
           |
  { dg-end-multiline-output "" } */

// TODO: range cases

/* The call/return to this function shouldn't appear in the path.  */

void called_by_test_3 (void)
{
}

void test_3 (void *ptr)
{
  free (ptr);
  called_by_test_3 ();
  free (ptr); /* { dg-warning "double-'free' of 'ptr'" } */
}

/* { dg-begin-multiline-output "" }
   NN |   free (ptr);
      |   ^~~~~~~~~~
  'test_3': events 1-2
    |
    |   NN |   free (ptr);
    |      |   ^~~~~~~~~~
    |      |   |
    |      |   (1) first 'free' here
    |   NN |   called_by_test_3 ();
    |   NN |   free (ptr);
    |      |   ~~~~~~~~~~
    |      |   |
    |      |   (2) second 'free' here; first 'free' was at (1)
    |
  { dg-end-multiline-output "" } */