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
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
  198
  199
  200
  201
  202
  203
  204
  205
  206
  207
  208
  209
// RUN: %clang_cc1 -Wno-unused-value -verify %s

#define NODEREF __attribute__((noderef))

struct S {
  int a;
  int b;
};

struct S2 {
  int a[2];
  int NODEREF a2[2];
  int *b;
  int NODEREF *b2;
  struct S *s;
  struct S NODEREF *s2;
};

int NODEREF *func(int NODEREF *arg) {  // expected-note{{arg declared here}}
  int y = *arg; // expected-warning{{dereferencing arg; was declared with a 'noderef' type}}
  return arg;
}

void func2(int x) {}

int test() {
  int NODEREF *p; // expected-note 34 {{p declared here}}
  int *p2;

  int x = *p;               // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  x = *((int NODEREF *)p2); // expected-warning{{dereferencing expression marked as 'noderef'}}

  int NODEREF **q;
  int *NODEREF *q2; // expected-note 4 {{q2 declared here}}

  // Indirection
  x = **q;  // expected-warning{{dereferencing expression marked as 'noderef'}}
  p2 = *q2; // expected-warning{{dereferencing q2; was declared with a 'noderef' type}}

  **q; // expected-warning{{dereferencing expression marked as 'noderef'}}

  p = *&*q;
  p = **&q;
  q = &**&q;
  p = &*p;
  p = *&p;
  p = &(*p);
  p = *(&p);
  x = **&p; // expected-warning{{dereferencing expression marked as 'noderef'}}

  *p = 2;   // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  *q = p;   // ok
  **q = 2;  // expected-warning{{dereferencing expression marked as 'noderef'}}
  *q2 = p2; // expected-warning{{dereferencing q2; was declared with a 'noderef' type}}

  p = p + 1;
  p = &*(p + 1);

  // Struct member access
  struct S NODEREF *s;  // expected-note 2 {{s declared here}}
  x = s->a;   // expected-warning{{dereferencing s; was declared with a 'noderef' type}}
  x = (*s).b; // expected-warning{{dereferencing s; was declared with a 'noderef' type}}
  p = &s->a;
  p = &(*s).b;

  // Nested struct access
  struct S2 NODEREF *s2_noderef;    // expected-note 5 {{s2_noderef declared here}}
  p = s2_noderef->a;  // ok since result is an array in a struct
  p = s2_noderef->a2; // ok
  p = s2_noderef->b;  // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
  p = s2_noderef->b2; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
  s = s2_noderef->s;  // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
  s = s2_noderef->s2; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
  p = s2_noderef->a + 1;

  struct S2 *s2;
  p = s2->a;
  p = s2->a2;
  p = s2->b;
  p = s2->b2;
  s = s2->s;
  s = s2->s2;
  &(*(*s2).s2).b;

  // Subscript access
  x = p[1];    // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  x = q[0][0]; // expected-warning{{dereferencing expression marked as 'noderef'}}
  p2 = q2[0];  // expected-warning{{dereferencing q2; was declared with a 'noderef' type}}
  p = q[*p];   // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  x = p[*p];   // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
               // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}

  int NODEREF arr[10];    // expected-note 1 {{arr declared here}}
  x = arr[1]; // expected-warning{{dereferencing arr; was declared with a 'noderef' type}}

  int NODEREF *(arr2[10]);
  int NODEREF *elem = *arr2;

  int NODEREF(*arr3)[10];
  elem = *arr3;

  // Combinations between indirection, subscript, and member access
  struct S2 NODEREF *s2_arr[10];
  struct S2 NODEREF *s2_arr2[10][10];

  p = s2_arr[1]->a;
  p = s2_arr[1]->b; // expected-warning{{dereferencing expression marked as 'noderef'}}
  int **bptr = &s2_arr[1]->b;

  x = s2->s2->a;        // expected-warning{{dereferencing expression marked as 'noderef'}}
  x = s2_noderef->a[1]; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
  p = &s2_noderef->a[1];

  // Casting to dereferenceable pointer
  p2 = p;             // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
  p2 = *q;            // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
  p2 = q[0];          // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
  s2 = s2_arr[1];     // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
  s2 = s2_arr2[1][1]; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
  p2 = p, p2 = *q;    // expected-warning 2 {{casting to dereferenceable pointer removes 'noderef' attribute}}

  // typedefs
  typedef int NODEREF *ptr_t;
  ptr_t ptr; // expected-note 2 {{ptr declared here}}
  ptr_t *ptr2;
  *ptr; // expected-warning{{dereferencing ptr; was declared with a 'noderef' type}}
  *ptr2;
  **ptr2; // expected-warning{{dereferencing expression marked as 'noderef'}}

  typedef struct S2 NODEREF *s2_ptr_t;
  s2_ptr_t s2_ptr; // expected-note 4 {{s2_ptr declared here}}
  s2_ptr->a;       // ok since result is an array in a struct
  s2_ptr->a2;      // ok
  s2_ptr->b;       // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}}
  s2_ptr->b2;      // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}}
  s2_ptr->s;       // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}}
  s2_ptr->s2;      // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}}
  s2_ptr->a + 1;

  typedef int(int_t);
  typedef int_t NODEREF *(noderef_int_t);
  typedef noderef_int_t *noderef_int_nested_t;
  noderef_int_nested_t noderef_int_nested_ptr;
  *noderef_int_nested_ptr;
  **noderef_int_nested_ptr; // expected-warning{{dereferencing expression marked as 'noderef'}}

  typedef int_t *(NODEREF noderef_int2_t);
  typedef noderef_int2_t *noderef_int2_nested_t;
  noderef_int2_nested_t noderef_int2_nested_ptr; // expected-note{{noderef_int2_nested_ptr declared here}}
  *noderef_int2_nested_ptr;                      // expected-warning{{dereferencing noderef_int2_nested_ptr; was declared with a 'noderef' type}}

  typedef int_t *(noderef_int3_t);
  typedef noderef_int3_t(NODEREF(*(noderef_int3_nested_t)));
  noderef_int3_nested_t noderef_int3_nested_ptr; // expected-note{{noderef_int3_nested_ptr declared here}}
  *noderef_int3_nested_ptr;                      // expected-warning{{dereferencing noderef_int3_nested_ptr; was declared with a 'noderef' type}}

  // Parentheses
  (((*((p))))); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  (*(*(&(p)))); // expected-warning{{dereferencing expression marked as 'noderef'}}

  (p[1]);      // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  (q[0]);      // ok
  (q[0][0]);   // expected-warning{{dereferencing expression marked as 'noderef'}}
  (q2[0]);     // expected-warning{{dereferencing q2; was declared with a 'noderef' type}}
  (q[(*(p))]); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  (p[(*(p))]); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
               // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}

  (*(ptr)); // expected-warning{{dereferencing ptr; was declared with a 'noderef' type}}
  (*(ptr2));
  (*(*(ptr2))); // expected-warning{{dereferencing expression marked as 'noderef'}}

  // Functions
  x = *(func(p)); // expected-warning{{dereferencing expression marked as 'noderef'}}

  // Casting is ok
  q = (int NODEREF **)&p;
  q = (int NODEREF **)&p2;
  q = &p;
  q = &p2;
  x = s2->s2->a; // expected-warning{{dereferencing expression marked as 'noderef'}}

  // Other expressions
  func2(*p);         // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  func2(*p + 1);     // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  func2(!*p);        // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  func2((x = *p));   // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  func2((char)(*p)); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}

  // Other statements
  if (*p) {}          // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  else if (*p) {}     // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  switch (*p){}       // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  for (*p; *p; *p){}  // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
                      // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
                      // expected-warning@-2{{dereferencing p; was declared with a 'noderef' type}}
  for (*p; *p;){}     // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
                      // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
  for (*p;; *p){}     // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
                      // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
  for (; *p; *p){}    // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
                      // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
  for (*p;;){}        // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  for (;*p;){}        // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  for (;;*p){}        // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  while (*p){}        // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  do {} while (*p);   // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  return *p;          // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
}