reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
// RUN: %clang_analyze_cc1 -x c -analyzer-checker=core -analyzer-output=text -verify %s

#define NULL 0

int test_noparammacro() {
  int *x = NULL; // expected-note{{'x' initialized to a null pointer value}}
  return *x; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}
             // expected-note@-1{{Dereference of null pointer (loaded from variable 'x')}}
}

#define DYN_CAST(X) (X ? (char*)X : 0)
#define GENERATE_NUMBER(X) (0)

char test_assignment(int *param) {
  char *param2;
  param2 = DYN_CAST(param);
  return *param2;
}

char test_declaration(int *param) {
  char *param2 = DYN_CAST(param);
  return *param2;
}

int coin();

int test_multi_decl(int *paramA, int *paramB) {
  char *param1 = DYN_CAST(paramA), *param2 = DYN_CAST(paramB);
  if (coin())
    return *param1;
  return *param2;
}

int testDivision(int a) {
  int divider = GENERATE_NUMBER(2); // expected-note{{'divider' initialized to 0}}
  return 1/divider; // expected-warning{{Division by zero}}
                    // expected-note@-1{{Division by zero}}
}

// Warning should not be suppressed if it happens in the same macro.
#define DEREF_IN_MACRO(X) int fn() {int *p = 0; return *p; }

DEREF_IN_MACRO(0) // expected-warning{{Dereference of null pointer}}
                  // expected-note@-1{{'p' initialized to a null}}
                  // expected-note@-2{{Dereference of null pointer}}

// Warning should not be suppressed if the null returned by the macro
// is not related to the warning.
#define RETURN_NULL() (0)
extern int* returnFreshPointer();
int noSuppressMacroUnrelated() {
  int *x = RETURN_NULL();
  x = returnFreshPointer();  // expected-note{{Value assigned to 'x'}}
  if (x) {} // expected-note{{Taking false branch}}
            // expected-note@-1{{Assuming 'x' is null}}
  return *x; // expected-warning{{Dereference of null pointer}}
             // expected-note@-1{{Dereference}}
}

// Value haven't changed by the assignment, but the null pointer
// did not come from the macro.
int noSuppressMacroUnrelatedOtherReason() {
  int *x = RETURN_NULL();
  x = returnFreshPointer();  
  x = 0; // expected-note{{Null pointer value stored to 'x'}}
  return *x; // expected-warning{{Dereference of null pointer}}
             // expected-note@-1{{Dereference}}
}