xref: /llvm-project/clang/test/Analysis/diagnostics/macro-null-return-suppression.cpp (revision 0dd49a5628bbe01cecf6516017da59ae44863ab3)
1 // RUN: %clang_analyze_cc1 -x c -analyzer-checker=core -analyzer-output=text -verify %s
2 
3 #define NULL 0
4 
test_noparammacro(void)5 int test_noparammacro(void) {
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 
test_assignment(int * param)14 char test_assignment(int *param) {
15   char *param2;
16   param2 = DYN_CAST(param);
17   return *param2;
18 }
19 
test_declaration(int * param)20 char test_declaration(int *param) {
21   char *param2 = DYN_CAST(param);
22   return *param2;
23 }
24 
25 int coin(void);
26 
test_multi_decl(int * paramA,int * paramB)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 
testDivision(int a)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(void) {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(void);
noSuppressMacroUnrelated(void)51 int noSuppressMacroUnrelated(void) {
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.
noSuppressMacroUnrelatedOtherReason(void)62 int noSuppressMacroUnrelatedOtherReason(void) {
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