Bug Summary

File:trg/trg/src/State.cc
Warning:line 51, column 20
Array access (via field '_state') results in a null pointer dereference

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -O3 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name State.cc -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/data/b2soft/buildbot/development/build -fcoverage-compilation-dir=/data/b2soft/buildbot/development/build -resource-dir /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/lib/clang/21 -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/include/c++ -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/include/c++/x86_64-redhat-linux -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/include/c++/backward -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/include -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/include/python3.12 -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/include/CLHEP -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/include/Geant4 -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/include -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/include/root -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/include/belle_legacy -I include/ -D _PACKAGE_="trg" -D G4UI_USE_TCSH -D RaveDllExport= -D HAS_SQLITE -D HAS_CALLGRIND -I include -I /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/include/libxml2 -internal-isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/bin/../lib64/gcc/x86_64-redhat-linux/15.2.0/../../../../include/c++ -internal-isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/bin/../lib64/gcc/x86_64-redhat-linux/15.2.0/../../../../include/c++/x86_64-redhat-linux -internal-isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/bin/../lib64/gcc/x86_64-redhat-linux/15.2.0/../../../../include/c++/backward -internal-isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/bin/../lib64/gcc/x86_64-redhat-linux/15.2.0/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-missing-braces -Wno-unused-command-line-argument -std=c++20 -fdeprecated-macro -ferror-limit 19 -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /scan_build/2026-05-31-004316-385593-1 -x c++ trg/trg/src/State.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <algorithm>
10#include <iostream>
11#include <ctype.h>
12#include <cstring>
13#include "trg/trg/Utilities.h"
14#include "trg/trg/State.h"
15
16using namespace std;
17
18namespace Belle2 {
19
20 const unsigned
21 TRGState::_su = sizeof(unsigned);
22
23 const unsigned
24 TRGState::_bsu = 8 * sizeof(unsigned);
25
26 TRGState::TRGState(unsigned bitSize)
27 : _size(bitSize),
28 _n(0),
29 _state(0)
30 {
31 _n = _size / _bsu;
32 if (_size % _bsu) ++_n;
33 if (_n)
34 _state = (unsigned*) calloc(_n, _su);
35 }
36
37 TRGState::TRGState(unsigned bitSize, unsigned value)
38 : _size(bitSize),
39 _n(0),
40 _state(0)
1
Null pointer value stored to field '_state'
41 {
42 _n = _size / _bsu;
43 if (_size % _bsu) ++_n;
2
Assuming the condition is false
3
Taking false branch
44 if (_n)
4
Assuming field '_n' is 0
5
Taking false branch
45 _state = (unsigned*) calloc(_n, _su);
46
47 for (unsigned i = 0; i < bitSize; i++) {
6
Assuming 'i' is < 'bitSize'
7
Loop condition is true. Entering loop body
48 const unsigned wp = i / _bsu;
49 const unsigned bp = i % _bsu;
50 if (value & (1 << i))
8
Assuming the condition is true
9
Taking true branch
51 _state[wp] |= (1 << bp);
10
Array access (via field '_state') results in a null pointer dereference
52 }
53 }
54
55 TRGState::TRGState(unsigned bitSize, const bool* const s)
56 : _size(bitSize),
57 _n(0),
58 _state(0)
59 {
60
61 _n = _size / _bsu;
62 if (_size % _bsu) ++_n;
63 _state = (unsigned*) calloc(_n, _su);
64
65 for (unsigned i = 0; i < _size; i++) {
66 const unsigned wp = i / _bsu;
67 const unsigned bp = i % _bsu;
68 if (s[i])
69 _state[wp] |= (1 << bp);
70 else
71 _state[wp] &= ~(1 << bp);
72 }
73 }
74
75 TRGState::TRGState(vector<bool> states)
76 : _size(0),
77 _n(0),
78 _state(0)
79 {
80
81 _size = states.size();
82 _n = _size / _bsu;
83 if (_size % _bsu) ++_n;
84 _state = (unsigned*) calloc(_n, _su);
85
86 for (unsigned i = 0; i < _size; i++) {
87 const unsigned wp = i / _bsu;
88 const unsigned bp = i % _bsu;
89 if (states[i])
90 _state[wp] |= (1 << bp);
91 else
92 _state[wp] &= ~(1 << bp);
93
94// cout << "size,given,states=" << _size << "," << states[i] << ","
95// << _state[wp] << endl;
96
97 }
98 }
99
100 TRGState::TRGState(vector<unsigned>& states, unsigned order)
101 : _size(0),
102 _n(0),
103 _state(0)
104 {
105
106 _size = states.size() * _bsu;
107 _n = _size / _bsu;
108 _state = (unsigned*) calloc(_n, _su);
109
110 for (unsigned i = 0; i < _n; i++) {
111
112 if (order == 0) _state[i] = states[i];
113 else _state[_n - 1 - i] = states[i];
114// cout << "size,given,states=" << _size << "," << states[i] << ","
115// << _state[wp] << endl;
116
117 }
118 }
119
120 TRGState::TRGState(const char* inChar, unsigned inType)
121 : _size(0),
122 _n(0),
123 _state(0)
124 {
125
126 if (inType == 0) {
127 _size = strlen(inChar);
128 // Check if all values are binary
129 for (unsigned iBit = 0; iBit < _size; iBit++) {
130 if (!(inChar[iBit] == '0' || inChar[iBit] == '1')) {
131#ifdef TRG_DEBUG
132 cout << "TRGState::TRGState !!! invalid char found : aborted"
133 << endl;
134 cout << " invalid char = [" << inChar[iBit]
135 << "]" << endl;
136#endif
137 return;
138 }
139 }
140 } else if (inType == 1) {
141 _size = strlen(inChar) * 4;
142 // Check if all values are hex
143 for (unsigned iChar = 0; iChar < _size / 4; iChar++) {
144 if (!isxdigit(inChar[iChar])) {
145#ifdef TRG_DEBUG
146 cout << "TRGState::TRGState !!! invalid char found : aborted"
147 << endl;
148 cout << " invalid char = ["
149 << inChar[iChar] << "]" << endl;
150#endif
151 return;
152 }
153 }
154 } else {
155#ifdef TRG_DEBUG
156 cout << "TRGState::TRGState !!! invalid type : aborted"
157 << endl;
158 cout << " invalid type = " << inType
159 << endl;
160#endif
161 return;
162 }
163
164 _n = _size / _bsu;
165 if (_size % _bsu) ++_n;
166 _state = (unsigned*) calloc(_n, _su);
167 if (inType == 0) {
168 for (unsigned iBit = 0; iBit < _size; iBit++) {
169 const unsigned wp = iBit / _bsu;
170 const unsigned bp = iBit % _bsu;
171 if (inChar[_size - 1 - iBit] == '1')
172 _state[wp] |= (1 << bp);
173 else
174 _state[wp] &= ~(1 << bp);
175 }
176 } else if (inType == 1) {
177 for (unsigned iChar = 0; iChar < _size / 4; iChar++) {
178 if (iChar % 8 == 0) _state[iChar / 8] = 0;
179 short unsigned t_int;
180 unsigned charP = _size / 4 - 1 - iChar;
181 if (inChar[charP] > 47 && inChar[charP] < 58) t_int = inChar[charP] - 48;
182 else t_int = inChar[charP] - 97 + 10;
183 _state[iChar / 8] += t_int << ((iChar % 8) * 4);
184 }
185 }
186 }
187
188 TRGState::~TRGState()
189 {
190 if (_state)
191 free(_state);
192 }
193
194 void
195 TRGState::dump(const string& msg,
196 const string& pre) const
197 {
198
199// bool bin = true;
200 bool large = (_size > 60) || msg.find("large") != string::npos;
201
202 if (! large) {
203 cout << pre << "size=" << _size << ",";
204 for (unsigned i = 0; i < _size; i++) {
205 const unsigned j = _size - i - 1;
206 if ((j % 8) == 7)
207 cout << "_";
208 if ((* this)[j])
209 cout << "1";
210 else
211 cout << "0";
212 }
213 cout << dec << endl;
214 } else {
215 cout << pre << "size=" << _size << endl;
216
217 const unsigned nPerLines = 64;
218 const unsigned lines = _size / nPerLines + 1;
219 const unsigned rem = _size % nPerLines;
220
221 cout << "TRGState" <<
222 " +56 +48 +40 +32 +24 +16 +8"
223 << " +0" << endl;
224
225 bool skipLast = false;
226 for (unsigned i = 0; i < lines; i++) {
227 const unsigned n0 = (i == 0) ? rem - 1 : nPerLines - 1;
228 const int n1 = 0;
229 const int os = (lines - i - 1) * nPerLines;
230
231 const string b = TRGUtilities::itostring(os);
232
233 TRGState s = subset(n1 + os, n0 - n1 + 1);
234
235// s.dump("", "*** ");
236
237 bool skip = false;
238 if (! s.active())
239 skip = true;
240
241 if (skip) {
242 if (!skipLast) {
243 cout << "... (all zero)" << endl;
244 }
245
246 skipLast = true;
247 continue;
248 }
249
250 skipLast = false;
251
252 cout.width(5);
253 cout << b;
254 cout << " ";
255
256 if (i == 0) {
257 unsigned n = nPerLines - rem + (nPerLines - rem) / 8;
258 if (rem % 8) ++n;
259 for (unsigned j = 0; j < n; j++)
260 cout << " ";
261 }
262
263 for (int j = n0; j >= n1; --j) {
264 const unsigned v = (* this)[j + os];
265
266 if ((j % 8) == 7)
267 cout << "_";
268 if (v)
269 cout << "1";
270 else
271 cout << "0";
272 }
273 cout << endl;
274 }
275 }
276
277 // else {
278 // cout << pre << "size=" << _size << ",0x";
279 // bool first = true;
280 // for (unsigned i = 0; i < _n; i++) {
281 // const unsigned j = _n - i - 1;
282 // if (((j % 4) == 3) && (! first))
283 // cout << "_";
284 // cout << hex << _state[j];
285 // first = false;
286 // }
287 // cout << dec << endl;
288
289 // cout << pre << "size=" << _size << ",0x";
290 // bool first = true;
291 // for (unsigned i = 0; i < _n; i++) {
292 // const unsigned j = _n - i - 1;
293 // if (! first)
294 // cout << "_";
295 // cout << hex << _state[j];
296 // cout << "(";
297 // for (unsigned k = 0; k < 4; k++) {
298 // unsigned c = ((_state[j] >> (4 - k + 1) * 8) & 0xff);
299 // if (c < 0x10)
300 // cout << ".";
301 // cout << c;
302 // }
303 // cout << ")";
304 // first = false;
305 // }
306 // cout << dec << endl;
307 // }
308 }
309
310 TRGState&
311 TRGState::operator+=(const TRGState& a)
312 {
313
314 //...Check final size...
315 const unsigned sizeNew = _size + a.size();
316 const unsigned sizeMax = _n * _bsu;
317 const unsigned oldSize = _size;
318
319 //...Necessary to extend...
320 if (sizeNew > sizeMax) {
321 unsigned nNew = sizeNew / _bsu;
322 if (sizeNew % _bsu) ++nNew;
323 unsigned* tmp = (unsigned*) calloc(nNew, _su);
324 for (unsigned i = 0; i < _n; i++) {
325 tmp[i] = _state[i];
326 }
327 if (_state)
328 free(_state);
329 _state = tmp;
330 _n = nNew;
331 }
332 _size = sizeNew;
333
334 for (unsigned i = 0; i < a.size(); i++) {
335 unsigned j = i + oldSize;
336 const unsigned wp = j / _bsu;
337 const unsigned bp = j % _bsu;
338 if (a[i])
339 _state[wp] |= (1 << bp);
340 else
341 _state[wp] &= ~(1 << bp);
342
343// cout << "size,given,states=" << _size << "," << states[i] << ","
344// << _state[wp] << endl;
345
346 }
347
348 return (* this);
349 }
350
351 TRGState
352 TRGState::subset(unsigned s, unsigned n) const
353 {
354 vector<bool> stack;
355 for (unsigned i = s; i < s + n; i++) {
356 if ((* this)[i])
357 stack.push_back(true);
358 else
359 stack.push_back(false);
360 }
361 return TRGState(stack);
362 }
363
364 TRGState& TRGState::operator=(const TRGState& a)
365 {
366 if (_state)
367 free(_state);
368
369 _size = a._size;
370 _n = a._n;
371 _state = (unsigned*) calloc(_n, _su);
372 for (unsigned i = 0; i < _n; i++) {
373 _state[i] = a._state[i];
374 }
375
376 return * this;
377 }
378
379 bool
380 TRGState::operator<(const TRGState& a) const
381 {
382 const unsigned long long n0(* this);
383 const unsigned long long n1(a);
384 if (n0 < n1)
385 return true;
386 return false;
387 }
388
389} // namespace Belle2
390
391namespace std {
392
393 ostream&
394 operator<<(ostream& out, const Belle2::TRGState& s)
395 {
396 for (unsigned i = 0; i < s.size(); i++) {
397 const unsigned j = s.size() - i - 1;
398 if (s.active(j))
399 out << "1";
400 else
401 out << "0";
402 }
403 return out;
404 }
405
406}