102 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection %s \2// RUN: -triple x86_64-pc-linux-gnu -verify3 4void clang_analyzer_eval(int);5 6#define BINOP(OP) [](auto x, auto y) { return x OP y; }7 8template <typename BinOp>9void nonloc_OP_loc(int *p, BinOp op) {10 long p_as_integer = (long)p;11 if (op(12, p_as_integer) != 11)12 return;13 14 // Perfectly constrain 'p', thus 'p_as_integer', and trigger a simplification15 // of the previously recorded constraint.16 if (p) {17 // no-crash18 }19 if (p == (int *)0x1b) {20 // no-crash21 }22}23 24// Same as before, but the operands are swapped.25template <typename BinOp>26void loc_OP_nonloc(int *p, BinOp op) {27 long p_as_integer = (long)p;28 if (op(p_as_integer, 12) != 11)29 return;30 31 if (p) {32 // no-crash33 }34 if (p == (int *)0x1b) {35 // no-crash36 }37}38 39void instantiate_tests_for_nonloc_OP_loc(int *p) {40 // Multiplicative and additive operators:41 nonloc_OP_loc(p, BINOP(*));42 nonloc_OP_loc(p, BINOP(/)); // no-crash43 nonloc_OP_loc(p, BINOP(%)); // no-crash44 nonloc_OP_loc(p, BINOP(+));45 nonloc_OP_loc(p, BINOP(-)); // no-crash46 47 // Bitwise operators:48 nonloc_OP_loc(p, BINOP(<<)); // no-crash49 nonloc_OP_loc(p, BINOP(>>)); // no-crash50 nonloc_OP_loc(p, BINOP(&));51 nonloc_OP_loc(p, BINOP(^));52 nonloc_OP_loc(p, BINOP(|));53}54 55void instantiate_tests_for_loc_OP_nonloc(int *p) {56 // Multiplicative and additive operators:57 loc_OP_nonloc(p, BINOP(*));58 loc_OP_nonloc(p, BINOP(/));59 loc_OP_nonloc(p, BINOP(%));60 loc_OP_nonloc(p, BINOP(+));61 loc_OP_nonloc(p, BINOP(-));62 63 // Bitwise operators:64 loc_OP_nonloc(p, BINOP(<<));65 loc_OP_nonloc(p, BINOP(>>));66 loc_OP_nonloc(p, BINOP(&));67 loc_OP_nonloc(p, BINOP(^));68 loc_OP_nonloc(p, BINOP(|));69}70 71// from: nullptr.cpp72void zoo1backwards() {73 char **p = nullptr;74 // expected-warning@+1 {{Dereference of null pointer [core.NullDereference]}}75 *(0 + p) = nullptr; // warn76 **(0 + p) = 'a'; // no-warning: this should be unreachable77}78 79void test_simplified_before_cast_add(long t1) {80 long t2 = t1 + 3;81 if (!t2) {82 int *p = (int *) t2;83 clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}84 }85}86 87void test_simplified_before_cast_sub(long t1) {88 long t2 = t1 - 3;89 if (!t2) {90 int *p = (int *) t2;91 clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}92 }93}94 95void test_simplified_before_cast_mul(long t1) {96 long t2 = t1 * 3;97 if (!t2) {98 int *p = (int *) t2;99 clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}100 }101}102