noderef.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. // RUN: %clang_cc1 -Wno-unused-value -verify %s
  2. #define NODEREF __attribute__((noderef))
  3. struct S {
  4. int a;
  5. int b;
  6. };
  7. struct S2 {
  8. int a[2];
  9. int NODEREF a2[2];
  10. int *b;
  11. int NODEREF *b2;
  12. struct S *s;
  13. struct S NODEREF *s2;
  14. };
  15. int NODEREF *func(int NODEREF *arg) { // expected-note{{arg declared here}}
  16. int y = *arg; // expected-warning{{dereferencing arg; was declared with a 'noderef' type}}
  17. return arg;
  18. }
  19. void func2(int x) {}
  20. int test() {
  21. int NODEREF *p; // expected-note 34 {{p declared here}}
  22. int *p2;
  23. int x = *p; // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  24. x = *((int NODEREF *)p2); // expected-warning{{dereferencing expression marked as 'noderef'}}
  25. int NODEREF **q;
  26. int *NODEREF *q2; // expected-note 4 {{q2 declared here}}
  27. // Indirection
  28. x = **q; // expected-warning{{dereferencing expression marked as 'noderef'}}
  29. p2 = *q2; // expected-warning{{dereferencing q2; was declared with a 'noderef' type}}
  30. **q; // expected-warning{{dereferencing expression marked as 'noderef'}}
  31. p = *&*q;
  32. p = **&q;
  33. q = &**&q;
  34. p = &*p;
  35. p = *&p;
  36. p = &(*p);
  37. p = *(&p);
  38. x = **&p; // expected-warning{{dereferencing expression marked as 'noderef'}}
  39. *p = 2; // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  40. *q = p; // ok
  41. **q = 2; // expected-warning{{dereferencing expression marked as 'noderef'}}
  42. *q2 = p2; // expected-warning{{dereferencing q2; was declared with a 'noderef' type}}
  43. p = p + 1;
  44. p = &*(p + 1);
  45. // Struct member access
  46. struct S NODEREF *s; // expected-note 2 {{s declared here}}
  47. x = s->a; // expected-warning{{dereferencing s; was declared with a 'noderef' type}}
  48. x = (*s).b; // expected-warning{{dereferencing s; was declared with a 'noderef' type}}
  49. p = &s->a;
  50. p = &(*s).b;
  51. // Nested struct access
  52. struct S2 NODEREF *s2_noderef; // expected-note 5 {{s2_noderef declared here}}
  53. p = s2_noderef->a; // ok since result is an array in a struct
  54. p = s2_noderef->a2; // ok
  55. p = s2_noderef->b; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
  56. p = s2_noderef->b2; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
  57. s = s2_noderef->s; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
  58. s = s2_noderef->s2; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
  59. p = s2_noderef->a + 1;
  60. struct S2 *s2;
  61. p = s2->a;
  62. p = s2->a2;
  63. p = s2->b;
  64. p = s2->b2;
  65. s = s2->s;
  66. s = s2->s2;
  67. &(*(*s2).s2).b;
  68. // Subscript access
  69. x = p[1]; // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  70. x = q[0][0]; // expected-warning{{dereferencing expression marked as 'noderef'}}
  71. p2 = q2[0]; // expected-warning{{dereferencing q2; was declared with a 'noderef' type}}
  72. p = q[*p]; // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  73. x = p[*p]; // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  74. // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
  75. int NODEREF arr[10]; // expected-note 1 {{arr declared here}}
  76. x = arr[1]; // expected-warning{{dereferencing arr; was declared with a 'noderef' type}}
  77. int NODEREF *(arr2[10]);
  78. int NODEREF *elem = *arr2;
  79. int NODEREF(*arr3)[10];
  80. elem = *arr3;
  81. // Combinations between indirection, subscript, and member access
  82. struct S2 NODEREF *s2_arr[10];
  83. struct S2 NODEREF *s2_arr2[10][10];
  84. p = s2_arr[1]->a;
  85. p = s2_arr[1]->b; // expected-warning{{dereferencing expression marked as 'noderef'}}
  86. int **bptr = &s2_arr[1]->b;
  87. x = s2->s2->a; // expected-warning{{dereferencing expression marked as 'noderef'}}
  88. x = s2_noderef->a[1]; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
  89. p = &s2_noderef->a[1];
  90. // Casting to dereferenceable pointer
  91. p2 = p; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
  92. p2 = *q; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
  93. p2 = q[0]; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
  94. s2 = s2_arr[1]; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
  95. s2 = s2_arr2[1][1]; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
  96. p2 = p, p2 = *q; // expected-warning 2 {{casting to dereferenceable pointer removes 'noderef' attribute}}
  97. // typedefs
  98. typedef int NODEREF *ptr_t;
  99. ptr_t ptr; // expected-note 2 {{ptr declared here}}
  100. ptr_t *ptr2;
  101. *ptr; // expected-warning{{dereferencing ptr; was declared with a 'noderef' type}}
  102. *ptr2;
  103. **ptr2; // expected-warning{{dereferencing expression marked as 'noderef'}}
  104. typedef struct S2 NODEREF *s2_ptr_t;
  105. s2_ptr_t s2_ptr; // expected-note 4 {{s2_ptr declared here}}
  106. s2_ptr->a; // ok since result is an array in a struct
  107. s2_ptr->a2; // ok
  108. s2_ptr->b; // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}}
  109. s2_ptr->b2; // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}}
  110. s2_ptr->s; // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}}
  111. s2_ptr->s2; // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}}
  112. s2_ptr->a + 1;
  113. typedef int(int_t);
  114. typedef int_t NODEREF *(noderef_int_t);
  115. typedef noderef_int_t *noderef_int_nested_t;
  116. noderef_int_nested_t noderef_int_nested_ptr;
  117. *noderef_int_nested_ptr;
  118. **noderef_int_nested_ptr; // expected-warning{{dereferencing expression marked as 'noderef'}}
  119. typedef int_t *(NODEREF noderef_int2_t);
  120. typedef noderef_int2_t *noderef_int2_nested_t;
  121. noderef_int2_nested_t noderef_int2_nested_ptr; // expected-note{{noderef_int2_nested_ptr declared here}}
  122. *noderef_int2_nested_ptr; // expected-warning{{dereferencing noderef_int2_nested_ptr; was declared with a 'noderef' type}}
  123. typedef int_t *(noderef_int3_t);
  124. typedef noderef_int3_t(NODEREF(*(noderef_int3_nested_t)));
  125. noderef_int3_nested_t noderef_int3_nested_ptr; // expected-note{{noderef_int3_nested_ptr declared here}}
  126. *noderef_int3_nested_ptr; // expected-warning{{dereferencing noderef_int3_nested_ptr; was declared with a 'noderef' type}}
  127. // Parentheses
  128. (((*((p))))); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  129. (*(*(&(p)))); // expected-warning{{dereferencing expression marked as 'noderef'}}
  130. (p[1]); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  131. (q[0]); // ok
  132. (q[0][0]); // expected-warning{{dereferencing expression marked as 'noderef'}}
  133. (q2[0]); // expected-warning{{dereferencing q2; was declared with a 'noderef' type}}
  134. (q[(*(p))]); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  135. (p[(*(p))]); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  136. // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
  137. (*(ptr)); // expected-warning{{dereferencing ptr; was declared with a 'noderef' type}}
  138. (*(ptr2));
  139. (*(*(ptr2))); // expected-warning{{dereferencing expression marked as 'noderef'}}
  140. // Functions
  141. x = *(func(p)); // expected-warning{{dereferencing expression marked as 'noderef'}}
  142. // Casting is ok
  143. q = (int NODEREF **)&p;
  144. q = (int NODEREF **)&p2;
  145. q = &p;
  146. q = &p2;
  147. x = s2->s2->a; // expected-warning{{dereferencing expression marked as 'noderef'}}
  148. // Other expressions
  149. func2(*p); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  150. func2(*p + 1); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  151. func2(!*p); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  152. func2((x = *p)); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  153. func2((char)(*p)); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  154. // Other statements
  155. if (*p) {} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  156. else if (*p) {} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  157. switch (*p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  158. for (*p; *p; *p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  159. // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
  160. // expected-warning@-2{{dereferencing p; was declared with a 'noderef' type}}
  161. for (*p; *p;){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  162. // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
  163. for (*p;; *p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  164. // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
  165. for (; *p; *p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  166. // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
  167. for (*p;;){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  168. for (;*p;){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  169. for (;;*p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  170. while (*p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  171. do {} while (*p); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  172. return *p; // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
  173. }