Bug Summary

File:scratch/gluex/scan-build-work/hdgeant4/src/G4fixes/G4GeometryWorkspace.cc
Location:line 239, column 30
Description:Called C++ object pointer is null

Annotated Source Code

1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27// $Id: G4GeometryWorkspace.cc 93288 2015-10-15 09:51:02Z gcosmo $
28//
29//
30// Class G4GeometryWorkspace - implementation
31//
32// ----------------------------------------------------------------------
33
34#include "G4GeometryWorkspace.hh"
35
36#include "G4PVReplica.hh"
37#include "G4PVParameterised.hh"
38#include "G4VPVParameterisation.hh"
39#include "G4PhysicalVolumeStore.hh"
40#include "G4VSolid.hh"
41
42#include "G4LogicalVolume.hh"
43#include "G4VPhysicalVolume.hh"
44#include "G4PVDivision.hh"
45#include "G4Region.hh"
46
47#include "G4AutoLock.hh"
48
49namespace
50{
51 G4Mutex solidclone = G4MUTEX_INITIALIZER{ { 0, 0, 0, 0, 0, 0, 0, { 0, 0 } } };
52}
53
54// ----------------------------------------------------------------------
55//
56G4GeometryWorkspace::G4GeometryWorkspace()
57 : fVerbose(false)
58{
59 fpLogicalVolumeSIM=
60 &const_cast<G4LVManager&>(G4LogicalVolume::GetSubInstanceManager());
61 fpPhysicalVolumeSIM=
62 &const_cast<G4PVManager&>( G4VPhysicalVolume::GetSubInstanceManager() );
63 fpReplicaSIM=
64 &const_cast<G4PVRManager&>(G4PVReplica::GetSubInstanceManager());
65 fpRegionSIM=
66 &const_cast<G4RegionManager&>(G4Region::GetSubInstanceManager());
67
68 // Create a work area for Logical Volumes in this thread
69 // then capture its address
70 InitialiseWorkspace();
71
72 fLogicalVolumeOffset= fpLogicalVolumeSIM->GetOffset();
73
74 fPhysicalVolumeOffset= fpPhysicalVolumeSIM->GetOffset();
75
76 fReplicaOffset= fpReplicaSIM->GetOffset();
77
78 fRegionOffset= fpRegionSIM->GetOffset();
79}
80
81// ----------------------------------------------------------------------
82//
83G4GeometryWorkspace::~G4GeometryWorkspace()
84{
85}
86
87// ----------------------------------------------------------------------
88//
89void
90G4GeometryWorkspace::UseWorkspace()
91{
92 if( fVerbose )
93 {
94 G4cout(*G4cout_p) << "G4GeometryWorkspace::UseWorkspace: Start " << G4endlstd::endl;
95 }
96
97 // Implementation originally in:
98 // G4WorkerThread::BuildGeometryAndPhysicsVector()
99 // and improved for G4PVParamaterised
100
101 // Geometry related, split classes mechanism: instantiate sub-instance
102 // for this thread
103 fpLogicalVolumeSIM->UseWorkArea(fLogicalVolumeOffset);
104 fpPhysicalVolumeSIM->UseWorkArea(fPhysicalVolumeOffset);
105
106 fpReplicaSIM->UseWorkArea(fReplicaOffset);
107 fpRegionSIM->UseWorkArea(fRegionOffset);
108
109 // When recycling a workspace
110 // - it must be a lightweight operation, to reuse a valid work area
111 // - so it must NOT Initialise anything!
112 // Do not call InitialisePhysicalVolumes();
113
114 if( fVerbose )
115 {
116 G4cout(*G4cout_p) << "G4GeometryWorkspace::UseWorkspace: End " << G4endlstd::endl;
117 }
118}
119
120// ----------------------------------------------------------------------
121//
122void G4GeometryWorkspace::ReleaseWorkspace()
123{
124 fpLogicalVolumeSIM->UseWorkArea(0);
125 fpPhysicalVolumeSIM->UseWorkArea(0);
126
127 fpReplicaSIM->UseWorkArea(0);
128 fpRegionSIM->UseWorkArea(0);
129}
130
131// ----------------------------------------------------------------------
132//
133void G4GeometryWorkspace::InitialisePhysicalVolumes()
134{
135 G4PhysicalVolumeStore* physVolStore = G4PhysicalVolumeStore::GetInstance();
136 for (size_t ip=0; ip<physVolStore->size(); ip++)
3
Loop condition is true. Entering loop body
137 {
138 G4VPhysicalVolume* physVol = (*physVolStore)[ip];
139 G4LogicalVolume *logicalVol = physVol->GetLogicalVolume();
140
141 // Use shadow pointer
142 //
143 G4VSolid *solid = logicalVol->GetMasterSolid();
144 G4PVReplica *g4PVReplica = 0;
145 g4PVReplica = dynamic_cast<G4PVReplica*>(physVol);
146 G4PVDivision *g4PVDivision = 0;
147 g4PVDivision = dynamic_cast<G4PVDivision*>(physVol);
148 if (!g4PVReplica)
4
Assuming 'g4PVReplica' is non-null
5
Taking false branch
149 {
150 // Placement volume
151 logicalVol->InitialiseWorker(logicalVol,solid,0);
152 }
153 else
154 {
155 g4PVReplica->InitialiseWorker(g4PVReplica);
156 if( ! g4PVReplica->IsParameterised() || g4PVDivision != 0)
6
Assuming 'g4PVDivision' is equal to null
7
Taking false branch
157 {
158 logicalVol->InitialiseWorker(logicalVol,solid,0);
159
160 // If the replica's solid (in LV) is changed during navigation,
161 // it must be thread-private
162 //
163 CloneReplicaSolid( g4PVReplica );
164 }
165 else
166 {
167 G4PVParameterised *paramVol = dynamic_cast<G4PVParameterised*>(physVol);
8
'paramVol' initialized here
168 if (!paramVol)
9
Assuming 'paramVol' is null
10
Taking true branch
169 {
170 G4Exception("G4GeometryWorkspace::CreateAndUseWorkspace()",
171 "GeomVol0003", FatalException,
172 "Cannot find Parameterisation for parameterised volume.");
173 }
174 CloneParameterisedSolids( paramVol );
11
Passing null pointer value via 1st parameter 'paramVol'
12
Calling 'G4GeometryWorkspace::CloneParameterisedSolids'
175 }
176 }
177 }
178 if( fVerbose )
179 {
180 G4cout(*G4cout_p) << "G4GeometryWorkspace::InitialisePhysicalVolumes: "
181 << "Copying geometry - Done!" << G4endlstd::endl;
182 }
183}
184
185// ----------------------------------------------------------------------
186// Create a clone of the solid for this replica in this thread
187//
188G4bool G4GeometryWorkspace::CloneReplicaSolid( G4PVReplica *replicaPV )
189{
190 // The solid Ptr is in the Logical Volume
191 //
192 G4LogicalVolume *logicalV= replicaPV ->GetLogicalVolume();
193 G4VSolid *solid= logicalV->GetSolid();
194
195 G4AutoLock aLock(&solidclone);
196 G4VSolid *workerSolid = solid->Clone();
197 aLock.unlock();
198
199 if( workerSolid )
200 {
201 logicalV->InitialiseWorker(logicalV,workerSolid,0);
202 }
203 else
204 {
205 // In the case that not all solids support(ed) the Clone()
206 // method, we do similar thing here to dynamically cast
207 // and then get the clone method.
208 //
209 G4ExceptionDescription ed;
210 ed << "ERROR - Unable to initialise geometry for worker node." << "\n"
211 << "A solid lacks the Clone() method - or Clone() failed." << "\n"
212 << " Type of solid: " << solid->GetEntityType() << "\n"
213 << " Parameters: " << *solid;
214 G4Exception("G4GeometryWorkspace::CloneParameterisedVolume()",
215 "GeomVol0003", FatalException, ed);
216 return false;
217 }
218 return true; // It Worked
219}
220
221// ----------------------------------------------------------------------
222// Each G4PVParameterised instance, has associated with it at least one
223// solid for each worker thread.
224// *Simple* Parameterisations have a single type of solid, and the
225// pointer points to the same instance of a solid during the simulation.
226// For this case, it is possible to adapt automatically to
227// multi-threading, simply by cloning the solid - so long
228// as all solids support the Clone() method.
229//
230G4bool G4GeometryWorkspace::
231CloneParameterisedSolids( G4PVParameterised *paramVol )
232{
233 // Check whether it is a simple parameterisation or not
234 //
235 // G4VPVParameterisation *param= paramVol->GetParameterisation();
236 // unsigned int numCopies= paramVol->GetMultiplicity();
237 // unsigned int numDifferent= 0;
238
239 G4LogicalVolume *logicalV= paramVol->GetLogicalVolume();
13
Called C++ object pointer is null
240 G4VSolid *solid= logicalV->GetSolid();
241
242 // for( unsigned int i=0; i< numCopies; i++)
243 // {
244 // G4VSolid *solidChk= param->ComputeSolid(i, paramVol);
245 // if( solidChk != solid)
246 // {
247 // numDifferent++;
248 // }
249 // }
250 // if( numDifferent>0 )
251 // {
252 // G4ExceptionDescription ed;
253 // ed << "ERROR - Parameterisation using several instances of Solids \n"
254 // << "potentially to support different types of solids. \n"
255 // << "Geant4-MT currently does not support this type of \n"
256 // << "parameterisation, sorry !";
257 // G4Exception("G4GeometryWorkspace::CloneParameterisedVolume()",
258 // "GeomVol0001", FatalException, ed);
259 // }
260
261 // Threads may attempt to clone a solids simultaneously.
262 // Those cloned solids will be registered into a shared solid
263 // store (C++ container). Need a lock to guarantee thread safety
264 //
265 G4AutoLock aLock(&solidclone);
266 G4VSolid *workerSolid = solid->Clone();
267 aLock.unlock();
268 if( workerSolid )
269 {
270 logicalV->InitialiseWorker(logicalV,workerSolid,0);
271 }
272 else
273 {
274 // In the case that not all solids support(ed) the Clone()
275 // method, we do similar thing here to dynamically cast
276 // and then get the clone method
277 //
278 G4ExceptionDescription ed;
279 ed << "ERROR - Unable to initialise geometry for worker node. \n"
280 << "A solid lacks the Clone() method - or Clone() failed. \n"
281 << " Type of solid: " << solid->GetEntityType() << "\n"
282 << " Parameters: " << *solid;
283 G4Exception("G4GeometryWorkspace::CloneParameterisedVolume()",
284 "GeomVol0003", FatalException, ed);
285 }
286 return true; // It Worked
287}
288
289// ----------------------------------------------------------------------
290//
291void G4GeometryWorkspace::InitialiseWorkspace()
292{
293 if( fVerbose )
1
Taking false branch
294 {
295 G4cout(*G4cout_p) << "G4GeometryWorkspace::InitialiseWorkspace():"
296 << " Copying geometry - Start " << G4endlstd::endl;
297 }
298
299 // Implementation originally in:
300 // G4WorkerThread::BuildGeometryAndPhysicsVector()
301 // and improved for G4PVParamaterised
302
303 // Geometry related, split classes mechanism:
304 // Do *NOT* instantiate sub-instance for this thread, just copy the contents!
305 //
306 fpLogicalVolumeSIM->SlaveCopySubInstanceArray();
307 fpPhysicalVolumeSIM->SlaveCopySubInstanceArray();
308 fpReplicaSIM->SlaveCopySubInstanceArray();
309 fpRegionSIM->SlaveInitializeSubInstance();
310
311 InitialisePhysicalVolumes();
2
Calling 'G4GeometryWorkspace::InitialisePhysicalVolumes'
312
313 if( fVerbose )
314 {
315 G4cout(*G4cout_p) << "G4GeometryWorkspace::InitialiseWorkspace: "
316 << "Copying geometry - Done!" << G4endlstd::endl;
317 }
318}
319
320// ----------------------------------------------------------------------
321//
322void G4GeometryWorkspace::DestroyWorkspace()
323{
324 G4PhysicalVolumeStore* physVolStore = G4PhysicalVolumeStore::GetInstance();
325 for (size_t ip=0; ip<physVolStore->size(); ip++)
326 {
327 G4VPhysicalVolume* physVol = (*physVolStore)[ip];
328 G4LogicalVolume *logicalVol = physVol->GetLogicalVolume();
329 G4PVReplica *g4PVReplica = 0;
330 g4PVReplica = dynamic_cast<G4PVReplica*>(physVol);
331 if (g4PVReplica)
332 {
333 g4PVReplica->TerminateWorker(g4PVReplica);
334 G4PVParameterised *paramVol = 0;
335 paramVol = dynamic_cast<G4PVParameterised*>(physVol);
336 if (paramVol)
337 {
338 // G4VSolid *solid = logicalVol->fSolid;
339 logicalVol->TerminateWorker(logicalVol);
340 // if( solid->IsClone() ) delete solid;
341 }
342 else
343 {
344 logicalVol->TerminateWorker(logicalVol);
345 }
346 }
347 else
348 {
349 logicalVol->TerminateWorker(logicalVol);
350 }
351 }
352 fpLogicalVolumeSIM->FreeSlave();
353 fpPhysicalVolumeSIM->FreeSlave();
354 fpReplicaSIM->FreeSlave();
355 fpRegionSIM->FreeSlave();
356}