Bug Summary

File:lib/Transforms/IPO/IPConstantPropagation.cpp
Warning:line 90, column 16
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name IPConstantPropagation.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -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 -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-9/lib/clang/9.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/lib/Transforms/IPO -I /build/llvm-toolchain-snapshot-9~svn362543/lib/Transforms/IPO -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/include -I /build/llvm-toolchain-snapshot-9~svn362543/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/include/clang/9.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-9/lib/clang/9.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/lib/Transforms/IPO -fdebug-prefix-map=/build/llvm-toolchain-snapshot-9~svn362543=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2019-06-05-060531-1271-1 -x c++ /build/llvm-toolchain-snapshot-9~svn362543/lib/Transforms/IPO/IPConstantPropagation.cpp -faddrsig
1//===-- IPConstantPropagation.cpp - Propagate constants through calls -----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This pass implements an _extremely_ simple interprocedural constant
10// propagation pass. It could certainly be improved in many different ways,
11// like using a worklist. This pass makes arguments dead, but does not remove
12// them. The existing dead argument elimination pass should be run after this
13// to clean up the mess.
14//
15//===----------------------------------------------------------------------===//
16
17#include "llvm/ADT/SmallVector.h"
18#include "llvm/ADT/Statistic.h"
19#include "llvm/Analysis/ValueTracking.h"
20#include "llvm/IR/CallSite.h"
21#include "llvm/IR/Constants.h"
22#include "llvm/IR/Instructions.h"
23#include "llvm/IR/Module.h"
24#include "llvm/Pass.h"
25#include "llvm/Transforms/IPO.h"
26using namespace llvm;
27
28#define DEBUG_TYPE"ipconstprop" "ipconstprop"
29
30STATISTIC(NumArgumentsProped, "Number of args turned into constants")static llvm::Statistic NumArgumentsProped = {"ipconstprop", "NumArgumentsProped"
, "Number of args turned into constants", {0}, {false}}
;
31STATISTIC(NumReturnValProped, "Number of return values turned into constants")static llvm::Statistic NumReturnValProped = {"ipconstprop", "NumReturnValProped"
, "Number of return values turned into constants", {0}, {false
}}
;
32
33namespace {
34 /// IPCP - The interprocedural constant propagation pass
35 ///
36 struct IPCP : public ModulePass {
37 static char ID; // Pass identification, replacement for typeid
38 IPCP() : ModulePass(ID) {
39 initializeIPCPPass(*PassRegistry::getPassRegistry());
40 }
41
42 bool runOnModule(Module &M) override;
43 };
44}
45
46/// PropagateConstantsIntoArguments - Look at all uses of the specified
47/// function. If all uses are direct call sites, and all pass a particular
48/// constant in for an argument, propagate that constant in as the argument.
49///
50static bool PropagateConstantsIntoArguments(Function &F) {
51 if (F.arg_empty() || F.use_empty()) return false; // No arguments? Early exit.
8
Assuming the condition is false
9
Taking false branch
52
53 // For each argument, keep track of its constant value and whether it is a
54 // constant or not. The bool is driven to true when found to be non-constant.
55 SmallVector<std::pair<Constant*, bool>, 16> ArgumentConstants;
56 ArgumentConstants.resize(F.arg_size());
57
58 unsigned NumNonconstant = 0;
59 for (Use &U : F.uses()) {
60 User *UR = U.getUser();
61 // Ignore blockaddress uses.
62 if (isa<BlockAddress>(UR)) continue;
10
Taking false branch
63
64 // If no abstract call site was created we did not understand the use, bail.
65 AbstractCallSite ACS(&U);
66 if (!ACS)
11
Assuming the condition is false
12
Taking false branch
67 return false;
68
69 // Mismatched argument count is undefined behavior. Simply bail out to avoid
70 // handling of such situations below (avoiding asserts/crashes).
71 unsigned NumActualArgs = ACS.getNumArgOperands();
72 if (F.isVarArg() ? ArgumentConstants.size() > NumActualArgs
13
Assuming the condition is false
14
'?' condition is false
16
Taking false branch
73 : ArgumentConstants.size() != NumActualArgs)
15
Assuming the condition is false
74 return false;
75
76 // Check out all of the potentially constant arguments. Note that we don't
77 // inspect varargs here.
78 Function::arg_iterator Arg = F.arg_begin();
79 for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++Arg) {
17
Assuming 'i' is not equal to 'e'
18
Loop condition is true. Entering loop body
23
Null pointer value stored to 'Arg'
24
Assuming 'i' is not equal to 'e'
25
Loop condition is true. Entering loop body
80
81 // If this argument is known non-constant, ignore it.
82 if (ArgumentConstants[i].second)
19
Assuming the condition is false
20
Taking false branch
26
Assuming the condition is false
27
Taking false branch
83 continue;
84
85 Value *V = ACS.getCallArgOperand(i);
86 Constant *C = dyn_cast_or_null<Constant>(V);
87
88 // Mismatched argument type is undefined behavior. Simply bail out to avoid
89 // handling of such situations below (avoiding asserts/crashes).
90 if (C && Arg->getType() != C->getType())
28
Called C++ object pointer is null
91 return false;
92
93 // We can only propagate thread independent values through callbacks.
94 // This is different to direct/indirect call sites because for them we
95 // know the thread executing the caller and callee is the same. For
96 // callbacks this is not guaranteed, thus a thread dependent value could
97 // be different for the caller and callee, making it invalid to propagate.
98 if (C && ACS.isCallbackCall() && C->isThreadDependent()) {
99 // Argument became non-constant. If all arguments are non-constant now,
100 // give up on this function.
101 if (++NumNonconstant == ArgumentConstants.size())
102 return false;
103
104 ArgumentConstants[i].second = true;
105 continue;
106 }
107
108 if (C && ArgumentConstants[i].first == nullptr) {
109 ArgumentConstants[i].first = C; // First constant seen.
110 } else if (C && ArgumentConstants[i].first == C) {
111 // Still the constant value we think it is.
112 } else if (V == &*Arg) {
21
Assuming the condition is true
22
Taking true branch
113 // Ignore recursive calls passing argument down.
114 } else {
115 // Argument became non-constant. If all arguments are non-constant now,
116 // give up on this function.
117 if (++NumNonconstant == ArgumentConstants.size())
118 return false;
119 ArgumentConstants[i].second = true;
120 }
121 }
122 }
123
124 // If we got to this point, there is a constant argument!
125 assert(NumNonconstant != ArgumentConstants.size())((NumNonconstant != ArgumentConstants.size()) ? static_cast<
void> (0) : __assert_fail ("NumNonconstant != ArgumentConstants.size()"
, "/build/llvm-toolchain-snapshot-9~svn362543/lib/Transforms/IPO/IPConstantPropagation.cpp"
, 125, __PRETTY_FUNCTION__))
;
126 bool MadeChange = false;
127 Function::arg_iterator AI = F.arg_begin();
128 for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++AI) {
129 // Do we have a constant argument?
130 if (ArgumentConstants[i].second || AI->use_empty() ||
131 AI->hasInAllocaAttr() || (AI->hasByValAttr() && !F.onlyReadsMemory()))
132 continue;
133
134 Value *V = ArgumentConstants[i].first;
135 if (!V) V = UndefValue::get(AI->getType());
136 AI->replaceAllUsesWith(V);
137 ++NumArgumentsProped;
138 MadeChange = true;
139 }
140 return MadeChange;
141}
142
143
144// Check to see if this function returns one or more constants. If so, replace
145// all callers that use those return values with the constant value. This will
146// leave in the actual return values and instructions, but deadargelim will
147// clean that up.
148//
149// Additionally if a function always returns one of its arguments directly,
150// callers will be updated to use the value they pass in directly instead of
151// using the return value.
152static bool PropagateConstantReturn(Function &F) {
153 if (F.getReturnType()->isVoidTy())
154 return false; // No return value.
155
156 // We can infer and propagate the return value only when we know that the
157 // definition we'll get at link time is *exactly* the definition we see now.
158 // For more details, see GlobalValue::mayBeDerefined.
159 if (!F.isDefinitionExact())
160 return false;
161
162 // Don't touch naked functions. The may contain asm returning
163 // value we don't see, so we may end up interprocedurally propagating
164 // the return value incorrectly.
165 if (F.hasFnAttribute(Attribute::Naked))
166 return false;
167
168 // Check to see if this function returns a constant.
169 SmallVector<Value *,4> RetVals;
170 StructType *STy = dyn_cast<StructType>(F.getReturnType());
171 if (STy)
172 for (unsigned i = 0, e = STy->getNumElements(); i < e; ++i)
173 RetVals.push_back(UndefValue::get(STy->getElementType(i)));
174 else
175 RetVals.push_back(UndefValue::get(F.getReturnType()));
176
177 unsigned NumNonConstant = 0;
178 for (BasicBlock &BB : F)
179 if (ReturnInst *RI = dyn_cast<ReturnInst>(BB.getTerminator())) {
180 for (unsigned i = 0, e = RetVals.size(); i != e; ++i) {
181 // Already found conflicting return values?
182 Value *RV = RetVals[i];
183 if (!RV)
184 continue;
185
186 // Find the returned value
187 Value *V;
188 if (!STy)
189 V = RI->getOperand(0);
190 else
191 V = FindInsertedValue(RI->getOperand(0), i);
192
193 if (V) {
194 // Ignore undefs, we can change them into anything
195 if (isa<UndefValue>(V))
196 continue;
197
198 // Try to see if all the rets return the same constant or argument.
199 if (isa<Constant>(V) || isa<Argument>(V)) {
200 if (isa<UndefValue>(RV)) {
201 // No value found yet? Try the current one.
202 RetVals[i] = V;
203 continue;
204 }
205 // Returning the same value? Good.
206 if (RV == V)
207 continue;
208 }
209 }
210 // Different or no known return value? Don't propagate this return
211 // value.
212 RetVals[i] = nullptr;
213 // All values non-constant? Stop looking.
214 if (++NumNonConstant == RetVals.size())
215 return false;
216 }
217 }
218
219 // If we got here, the function returns at least one constant value. Loop
220 // over all users, replacing any uses of the return value with the returned
221 // constant.
222 bool MadeChange = false;
223 for (Use &U : F.uses()) {
224 CallSite CS(U.getUser());
225 Instruction* Call = CS.getInstruction();
226
227 // Not a call instruction or a call instruction that's not calling F
228 // directly?
229 if (!Call || !CS.isCallee(&U))
230 continue;
231
232 // Call result not used?
233 if (Call->use_empty())
234 continue;
235
236 MadeChange = true;
237
238 if (!STy) {
239 Value* New = RetVals[0];
240 if (Argument *A = dyn_cast<Argument>(New))
241 // Was an argument returned? Then find the corresponding argument in
242 // the call instruction and use that.
243 New = CS.getArgument(A->getArgNo());
244 Call->replaceAllUsesWith(New);
245 continue;
246 }
247
248 for (auto I = Call->user_begin(), E = Call->user_end(); I != E;) {
249 Instruction *Ins = cast<Instruction>(*I);
250
251 // Increment now, so we can remove the use
252 ++I;
253
254 // Find the index of the retval to replace with
255 int index = -1;
256 if (ExtractValueInst *EV = dyn_cast<ExtractValueInst>(Ins))
257 if (EV->hasIndices())
258 index = *EV->idx_begin();
259
260 // If this use uses a specific return value, and we have a replacement,
261 // replace it.
262 if (index != -1) {
263 Value *New = RetVals[index];
264 if (New) {
265 if (Argument *A = dyn_cast<Argument>(New))
266 // Was an argument returned? Then find the corresponding argument in
267 // the call instruction and use that.
268 New = CS.getArgument(A->getArgNo());
269 Ins->replaceAllUsesWith(New);
270 Ins->eraseFromParent();
271 }
272 }
273 }
274 }
275
276 if (MadeChange) ++NumReturnValProped;
277 return MadeChange;
278}
279
280char IPCP::ID = 0;
281INITIALIZE_PASS(IPCP, "ipconstprop",static void *initializeIPCPPassOnce(PassRegistry &Registry
) { PassInfo *PI = new PassInfo( "Interprocedural constant propagation"
, "ipconstprop", &IPCP::ID, PassInfo::NormalCtor_t(callDefaultCtor
<IPCP>), false, false); Registry.registerPass(*PI, true
); return PI; } static llvm::once_flag InitializeIPCPPassFlag
; void llvm::initializeIPCPPass(PassRegistry &Registry) {
llvm::call_once(InitializeIPCPPassFlag, initializeIPCPPassOnce
, std::ref(Registry)); }
282 "Interprocedural constant propagation", false, false)static void *initializeIPCPPassOnce(PassRegistry &Registry
) { PassInfo *PI = new PassInfo( "Interprocedural constant propagation"
, "ipconstprop", &IPCP::ID, PassInfo::NormalCtor_t(callDefaultCtor
<IPCP>), false, false); Registry.registerPass(*PI, true
); return PI; } static llvm::once_flag InitializeIPCPPassFlag
; void llvm::initializeIPCPPass(PassRegistry &Registry) {
llvm::call_once(InitializeIPCPPassFlag, initializeIPCPPassOnce
, std::ref(Registry)); }
283
284ModulePass *llvm::createIPConstantPropagationPass() { return new IPCP(); }
285
286bool IPCP::runOnModule(Module &M) {
287 if (skipModule(M))
1
Assuming the condition is false
2
Taking false branch
288 return false;
289
290 bool Changed = false;
291 bool LocalChange = true;
292
293 // FIXME: instead of using smart algorithms, we just iterate until we stop
294 // making changes.
295 while (LocalChange) {
3
Loop condition is true. Entering loop body
296 LocalChange = false;
297 for (Function &F : M)
298 if (!F.isDeclaration()) {
4
Assuming the condition is true
5
Taking true branch
299 // Delete any klingons.
300 F.removeDeadConstantUsers();
301 if (F.hasLocalLinkage())
6
Taking true branch
302 LocalChange |= PropagateConstantsIntoArguments(F);
7
Calling 'PropagateConstantsIntoArguments'
303 Changed |= PropagateConstantReturn(F);
304 }
305 Changed |= LocalChange;
306 }
307 return Changed;
308}