1 // RUN: %clang_analyze_cc1 %s -verify=fn-pointer \
2 // RUN:   -analyzer-checker=core \
3 // RUN:   -analyzer-config core.CallAndMessage:FunctionPointer=true \
4 // RUN:   -analyzer-config core.CallAndMessage:ParameterCount=false \
5 // RUN:   -analyzer-config core.CallAndMessage:CXXThisMethodCall=false \
6 // RUN:   -analyzer-config core.CallAndMessage:CXXDeallocationArg=false \
7 // RUN:   -analyzer-config core.CallAndMessage:ArgInitializedness=false \
8 // RUN:   -analyzer-config core.CallAndMessage:ArgPointeeInitializedness=false \
9 // RUN:   -analyzer-config core.CallAndMessage:NilReceiver=false \
10 // RUN:   -analyzer-config core.CallAndMessage:UndefReceiver=false
11 
12 // RUN: %clang_analyze_cc1 %s -verify=param-count \
13 // RUN:   -analyzer-checker=core \
14 // RUN:   -analyzer-config core.CallAndMessage:FunctionPointer=false \
15 // RUN:   -analyzer-config core.CallAndMessage:ParameterCount=true \
16 // RUN:   -analyzer-config core.CallAndMessage:CXXThisMethodCall=false \
17 // RUN:   -analyzer-config core.CallAndMessage:CXXDeallocationArg=false \
18 // RUN:   -analyzer-config core.CallAndMessage:ArgInitializedness=false \
19 // RUN:   -analyzer-config core.CallAndMessage:ArgPointeeInitializedness=false \
20 // RUN:   -analyzer-config core.CallAndMessage:NilReceiver=false \
21 // RUN:   -analyzer-config core.CallAndMessage:UndefReceiver=false
22 
23 // RUN: %clang_analyze_cc1 %s -verify=method \
24 // RUN:   -analyzer-checker=core \
25 // RUN:   -analyzer-config core.CallAndMessage:FunctionPointer=false \
26 // RUN:   -analyzer-config core.CallAndMessage:ParameterCount=false \
27 // RUN:   -analyzer-config core.CallAndMessage:CXXThisMethodCall=true \
28 // RUN:   -analyzer-config core.CallAndMessage:CXXDeallocationArg=false \
29 // RUN:   -analyzer-config core.CallAndMessage:ArgInitializedness=false \
30 // RUN:   -analyzer-config core.CallAndMessage:ArgPointeeInitializedness=false \
31 // RUN:   -analyzer-config core.CallAndMessage:NilReceiver=false \
32 // RUN:   -analyzer-config core.CallAndMessage:UndefReceiver=false
33 
34 // RUN: %clang_analyze_cc1 %s -verify=delete \
35 // RUN:   -analyzer-checker=core \
36 // RUN:   -analyzer-config core.CallAndMessage:FunctionPointer=false \
37 // RUN:   -analyzer-config core.CallAndMessage:ParameterCount=false \
38 // RUN:   -analyzer-config core.CallAndMessage:CXXThisMethodCall=false \
39 // RUN:   -analyzer-config core.CallAndMessage:CXXDeallocationArg=true \
40 // RUN:   -analyzer-config core.CallAndMessage:ArgInitializedness=false \
41 // RUN:   -analyzer-config core.CallAndMessage:ArgPointeeInitializedness=false \
42 // RUN:   -analyzer-config core.CallAndMessage:NilReceiver=false \
43 // RUN:   -analyzer-config core.CallAndMessage:UndefReceiver=false
44 
45 // RUN: %clang_analyze_cc1 %s -verify=arg-init \
46 // RUN:   -analyzer-checker=core \
47 // RUN:   -analyzer-config core.CallAndMessage:FunctionPointer=false \
48 // RUN:   -analyzer-config core.CallAndMessage:ParameterCount=false \
49 // RUN:   -analyzer-config core.CallAndMessage:CXXThisMethodCall=false \
50 // RUN:   -analyzer-config core.CallAndMessage:CXXDeallocationArg=false \
51 // RUN:   -analyzer-config core.CallAndMessage:ArgInitializedness=true \
52 // RUN:   -analyzer-config core.CallAndMessage:ArgPointeeInitializedness=false \
53 // RUN:   -analyzer-config core.CallAndMessage:NilReceiver=false \
54 // RUN:   -analyzer-config core.CallAndMessage:UndefReceiver=false
55 
56 // Testing for ArgPointeeInitializedness is in call-and-message.c.
57 
58 // RUN: %clang_analyze_cc1 %s \
59 // RUN:   -verify=fn-pointer,param-count,method,delete,arg-init \
60 // RUN:   -analyzer-checker=core \
61 // RUN:   -analyzer-output=plist -o %t.plist
62 // RUN: cat %t.plist | FileCheck %s
63 
64 namespace function_pointer {
65 using Fn = void (*)();
66 
uninit()67 void uninit() {
68   Fn f;
69   f(); // fn-pointer-warning{{Called function pointer is an uninitialized pointer value [core.CallAndMessage]}}
70 }
71 
null()72 void null() {
73   Fn f = nullptr;
74   f(); // fn-pointer-warning{{Called function pointer is null (null dereference) [core.CallAndMessage]}}
75 }
76 
77 // TODO: If this hash ever changes, turn
78 // core.CallAndMessage:FunctionPointer from a checker option into a
79 // checker, as described in the CallAndMessage comments!
80 // CHECK: <key>issue_hash_content_of_line_in_context</key>
81 // CHECK-SAME: <string>eb2083c01775eef452afa75728dd4d8f</string>
82 // CHECK: <key>issue_hash_content_of_line_in_context</key>
83 // CHECK-SAME: <string>407c50d9bedd8db28bf34f9411308100</string>
84 
85 } // namespace function_pointer
86 
87 namespace wrong_param_count {
88 using FnOneParam = void (*)(int);
89 using FnTwoParam = void (*)(int, int);
90 
f(int,int)91 void f(int, int) {}
92 
wrong_cast()93 void wrong_cast() {
94   FnTwoParam f1 = f;
95   FnOneParam f2 = reinterpret_cast<FnOneParam>(f1);
96   f2(5); // param-count-warning{{Function taking 2 arguments is called with fewer (1) [core.CallAndMessage]}}
97 }
98 
99 // TODO: If this hash ever changes, turn
100 // core.CallAndMessage:ParameterCount from a checker option into a
101 // checker, as described in the CallAndMessage comments!
102 // CHECK: <key>issue_hash_content_of_line_in_context</key>
103 // CHECK-SAME: <string>9ff0e9b728422017945c9d5a673de223</string>
104 } // namespace wrong_param_count
105 
106 namespace method_call {
107 struct A {
108   void m();
109 };
110 
uninit()111 void uninit() {
112   A *a;
113   a->m(); // method-warning{{Called C++ object pointer is uninitialized [core.CallAndMessage]}}
114 }
115 
116 // TODO: If this hash ever changes, turn
117 // core.CallAndMessage:CXXThisMethodCall from a checker option into a
118 // checker, as described in the CallAndMessage comments!
119 // CHECK: <key>issue_hash_content_of_line_in_context</key>
120 // CHECK-SAME: <string>7bc35c70465837948a3f5018f27b21cd</string>
121 
null()122 void null() {
123   A *a = nullptr;
124   a->m(); // method-warning{{Called C++ object pointer is null [core.CallAndMessage]}}
125 }
126 
127 // TODO: If this hash ever changes, turn
128 // core.CallAndMessage:CXXThisMethodCall from a checker option into a
129 // checker, as described in the CallAndMessage comments!
130 // CHECK: <key>issue_hash_content_of_line_in_context</key>
131 // CHECK-SAME: <string>8ec260c9ef11d7c51fa872212df1163f</string>
132 } // namespace method_call
133 
134 namespace operator_delete {
f()135 void f() {
136   int *i;
137   delete i; // delete-warning{{Argument to 'delete' is uninitialized [core.CallAndMessage]}}
138 }
139 
140 // TODO: If this hash ever changes, turn
141 // core.CallAndMessage:CXXDeallocationArg from a checker option into a
142 // checker, as described in the CallAndMessage comments!
143 // CHECK: <key>issue_hash_content_of_line_in_context</key>
144 // CHECK-SAME: <string>a8ff99ebaa8746457d3e14af8ef7e75c</string>
145 } // namespace operator_delete
146 
147 namespace uninit_arg {
148 template <class T>
149 void consume(T);
150 
fundamental_uninit()151 void fundamental_uninit() {
152   int i;
153   consume(i); // arg-init-warning{{1st function call argument is an uninitialized value [core.CallAndMessage]}}
154 }
155 
156 struct A {
157   int i;
158 };
159 
record_uninit()160 void record_uninit() {
161   A a;
162   consume(a); // arg-init-warning{{Passed-by-value struct argument contains uninitialized data (e.g., field: 'i') [core.CallAndMessage]}}
163 }
164 
165 // TODO: If this hash ever changes, turn
166 // core.CallAndMessage:ArgInitializedness from a checker option into a
167 // checker, as described in the CallAndMessage comments!
168 // CHECK: <key>issue_hash_content_of_line_in_context</key>
169 // CHECK-SAME: <string>a46bb5c1ee44d4611ffeb13f7f499605</string>
170 // CHECK: <key>issue_hash_content_of_line_in_context</key>
171 // CHECK-SAME: <string>e0e0d30ea5a7b2e3a71e1931fa0768a5</string>
172 } // namespace uninit_arg
173