1 | // RUN: %clang_analyze_cc1 -x c -analyzer-checker=core -analyzer-output=text -verify %s |
2 | |
3 | #define NULL 0 |
4 | |
5 | int test_noparammacro() { |
6 | int *x = NULL; // expected-note{{'x' initialized to a null pointer value}} |
7 | return *x; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}} |
8 | // expected-note@-1{{Dereference of null pointer (loaded from variable 'x')}} |
9 | } |
10 | |
11 | #define DYN_CAST(X) (X ? (char*)X : 0) |
12 | #define GENERATE_NUMBER(X) (0) |
13 | |
14 | char test_assignment(int *param) { |
15 | char *param2; |
16 | param2 = DYN_CAST(param); |
17 | return *param2; |
18 | } |
19 | |
20 | char test_declaration(int *param) { |
21 | char *param2 = DYN_CAST(param); |
22 | return *param2; |
23 | } |
24 | |
25 | int coin(); |
26 | |
27 | int test_multi_decl(int *paramA, int *paramB) { |
28 | char *param1 = DYN_CAST(paramA), *param2 = DYN_CAST(paramB); |
29 | if (coin()) |
30 | return *param1; |
31 | return *param2; |
32 | } |
33 | |
34 | int testDivision(int a) { |
35 | int divider = GENERATE_NUMBER(2); // expected-note{{'divider' initialized to 0}} |
36 | return 1/divider; // expected-warning{{Division by zero}} |
37 | // expected-note@-1{{Division by zero}} |
38 | } |
39 | |
40 | // Warning should not be suppressed if it happens in the same macro. |
41 | #define DEREF_IN_MACRO(X) int fn() {int *p = 0; return *p; } |
42 | |
43 | DEREF_IN_MACRO(0) // expected-warning{{Dereference of null pointer}} |
44 | // expected-note@-1{{'p' initialized to a null}} |
45 | // expected-note@-2{{Dereference of null pointer}} |
46 | |
47 | // Warning should not be suppressed if the null returned by the macro |
48 | // is not related to the warning. |
49 | #define RETURN_NULL() (0) |
50 | extern int* returnFreshPointer(); |
51 | int noSuppressMacroUnrelated() { |
52 | int *x = RETURN_NULL(); |
53 | x = returnFreshPointer(); // expected-note{{Value assigned to 'x'}} |
54 | if (x) {} // expected-note{{Taking false branch}} |
55 | // expected-note@-1{{Assuming 'x' is null}} |
56 | return *x; // expected-warning{{Dereference of null pointer}} |
57 | // expected-note@-1{{Dereference}} |
58 | } |
59 | |
60 | // Value haven't changed by the assignment, but the null pointer |
61 | // did not come from the macro. |
62 | int noSuppressMacroUnrelatedOtherReason() { |
63 | int *x = RETURN_NULL(); |
64 | x = returnFreshPointer(); |
65 | x = 0; // expected-note{{Null pointer value stored to 'x'}} |
66 | return *x; // expected-warning{{Dereference of null pointer}} |
67 | // expected-note@-1{{Dereference}} |
68 | } |
69 | |