array-struct-region.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c %s
  2. // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c++ -analyzer-config c++-inlining=constructors %s
  3. // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c %s
  4. // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c++ -analyzer-config c++-inlining=constructors %s
  5. void clang_analyzer_eval(int);
  6. struct S {
  7. int field;
  8. #if __cplusplus
  9. const struct S *getThis() const { return this; }
  10. const struct S *operator +() const { return this; }
  11. bool check() const { return this == this; }
  12. bool operator !() const { return this != this; }
  13. int operator *() const { return field; }
  14. #endif
  15. };
  16. #if __cplusplus
  17. const struct S *operator -(const struct S &s) { return &s; }
  18. bool operator ~(const struct S &s) { return &s != &s; }
  19. #endif
  20. #ifdef INLINE
  21. struct S getS() {
  22. struct S s = { 42 };
  23. return s;
  24. }
  25. #else
  26. struct S getS();
  27. #endif
  28. void testAssignment() {
  29. struct S s = getS();
  30. if (s.field != 42) return;
  31. clang_analyzer_eval(s.field == 42); // expected-warning{{TRUE}}
  32. s.field = 0;
  33. clang_analyzer_eval(s.field == 0); // expected-warning{{TRUE}}
  34. #if __cplusplus
  35. clang_analyzer_eval(s.getThis() == &s); // expected-warning{{TRUE}}
  36. clang_analyzer_eval(+s == &s); // expected-warning{{TRUE}}
  37. clang_analyzer_eval(-s == &s); // expected-warning{{TRUE}}
  38. clang_analyzer_eval(s.check()); // expected-warning{{TRUE}}
  39. clang_analyzer_eval(!s); // expected-warning{{FALSE}}
  40. clang_analyzer_eval(~s); // expected-warning{{FALSE}}
  41. clang_analyzer_eval(*s == 0); // expected-warning{{TRUE}}
  42. #endif
  43. }
  44. void testImmediateUse() {
  45. int x = getS().field;
  46. if (x != 42) return;
  47. clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
  48. #if __cplusplus
  49. clang_analyzer_eval((void *)getS().getThis() == (void *)&x); // expected-warning{{FALSE}}
  50. clang_analyzer_eval((void *)+getS() == (void *)&x); // expected-warning{{FALSE}}
  51. clang_analyzer_eval((void *)-getS() == (void *)&x); // expected-warning{{FALSE}}
  52. clang_analyzer_eval(getS().check()); // expected-warning{{TRUE}}
  53. clang_analyzer_eval(!getS()); // expected-warning{{FALSE}}
  54. clang_analyzer_eval(~getS()); // expected-warning{{FALSE}}
  55. #endif
  56. }
  57. int getConstrainedField(struct S s) {
  58. if (s.field != 42) return 42;
  59. return s.field;
  60. }
  61. int getAssignedField(struct S s) {
  62. s.field = 42;
  63. return s.field;
  64. }
  65. void testArgument() {
  66. clang_analyzer_eval(getConstrainedField(getS()) == 42); // expected-warning{{TRUE}}
  67. clang_analyzer_eval(getAssignedField(getS()) == 42); // expected-warning{{TRUE}}
  68. }
  69. //--------------------
  70. // C++-only tests
  71. //--------------------
  72. #if __cplusplus
  73. void testReferenceAssignment() {
  74. const S &s = getS();
  75. if (s.field != 42) return;
  76. clang_analyzer_eval(s.field == 42); // expected-warning{{TRUE}}
  77. clang_analyzer_eval(s.getThis() == &s); // expected-warning{{TRUE}}
  78. clang_analyzer_eval(+s == &s); // expected-warning{{TRUE}}
  79. clang_analyzer_eval(s.check()); // expected-warning{{TRUE}}
  80. clang_analyzer_eval(!s); // expected-warning{{FALSE}}
  81. clang_analyzer_eval(~s); // expected-warning{{FALSE}}
  82. clang_analyzer_eval(*s == 42); // expected-warning{{TRUE}}
  83. }
  84. int getConstrainedFieldRef(const S &s) {
  85. if (s.field != 42) return 42;
  86. return s.field;
  87. }
  88. bool checkThis(const S &s) {
  89. return s.getThis() == &s;
  90. }
  91. bool checkThisOp(const S &s) {
  92. return +s == &s;
  93. }
  94. bool checkThisStaticOp(const S &s) {
  95. return -s == &s;
  96. }
  97. void testReferenceArgument() {
  98. clang_analyzer_eval(getConstrainedFieldRef(getS()) == 42); // expected-warning{{TRUE}}
  99. clang_analyzer_eval(checkThis(getS())); // expected-warning{{TRUE}}
  100. clang_analyzer_eval(checkThisOp(getS())); // expected-warning{{TRUE}}
  101. clang_analyzer_eval(checkThisStaticOp(getS())); // expected-warning{{TRUE}}
  102. }
  103. int getConstrainedFieldOp(S s) {
  104. if (*s != 42) return 42;
  105. return *s;
  106. }
  107. int getConstrainedFieldRefOp(const S &s) {
  108. if (*s != 42) return 42;
  109. return *s;
  110. }
  111. void testImmediateUseOp() {
  112. int x = *getS();
  113. if (x != 42) return;
  114. clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
  115. clang_analyzer_eval(getConstrainedFieldOp(getS()) == 42); // expected-warning{{TRUE}}
  116. clang_analyzer_eval(getConstrainedFieldRefOp(getS()) == 42); // expected-warning{{TRUE}}
  117. }
  118. #endif