@@ -174,16 +174,16 @@ static bool isSimpleEnoughPointerToCommit(Constant *C, const DataLayout &DL) {
174
174
return false ;
175
175
}
176
176
177
- // / Apply 'Func' to Ptr. If this returns nullptr, introspect the pointer's
178
- // / type and walk down through the initial elements to obtain additional
179
- // / pointers to try. Returns the first non-null return value from Func, or
180
- // / nullptr if the type can't be introspected further.
177
+ // / Apply \p TryLoad to Ptr. If this returns \p nullptr, introspect the
178
+ // / pointer's type and walk down through the initial elements to obtain
179
+ // / additional pointers to try. Returns the first non-null return value from
180
+ // / \p TryLoad, or \p nullptr if the type can't be introspected further.
181
181
static Constant *
182
182
evaluateBitcastFromPtr (Constant *Ptr, const DataLayout &DL,
183
183
const TargetLibraryInfo *TLI,
184
- std::function<Constant *(Constant *)> Func ) {
184
+ std::function<Constant *(Constant *)> TryLoad ) {
185
185
Constant *Val;
186
- while (!(Val = Func (Ptr))) {
186
+ while (!(Val = TryLoad (Ptr))) {
187
187
// If Ty is a non-opaque struct, we can convert the pointer to the struct
188
188
// into a pointer to its first member.
189
189
// FIXME: This could be extended to support arrays as well.
@@ -211,9 +211,11 @@ static Constant *getInitializer(Constant *C) {
211
211
Constant *Evaluator::ComputeLoadResult (Constant *P, Type *Ty) {
212
212
// If this memory location has been recently stored, use the stored value: it
213
213
// is the most up-to-date.
214
- auto findMemLoc = [this ](Constant *Ptr) { return MutatedMemory.lookup (Ptr); };
214
+ auto TryFindMemLoc = [this ](Constant *Ptr) {
215
+ return MutatedMemory.lookup (Ptr);
216
+ };
215
217
216
- if (Constant *Val = findMemLoc (P))
218
+ if (Constant *Val = TryFindMemLoc (P))
217
219
return Val;
218
220
219
221
// Access it.
@@ -237,7 +239,7 @@ Constant *Evaluator::ComputeLoadResult(Constant *P, Type *Ty) {
237
239
// If it hasn't, we may still be able to find a stored pointer by
238
240
// introspecting the type.
239
241
Constant *Val =
240
- evaluateBitcastFromPtr (CE->getOperand (0 ), DL, TLI, findMemLoc );
242
+ evaluateBitcastFromPtr (CE->getOperand (0 ), DL, TLI, TryFindMemLoc );
241
243
if (!Val)
242
244
Val = getInitializer (CE->getOperand (0 ));
243
245
if (Val)
@@ -369,17 +371,25 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst, BasicBlock *&NextBB,
369
371
// legal. If it's not, we can try introspecting the type to find a
370
372
// legal conversion.
371
373
372
- auto castValTy = [&](Constant *P) -> Constant * {
373
- Type *Ty = cast<PointerType>(P->getType ())->getElementType ();
374
- if (Constant *FV = ConstantFoldLoadThroughBitcast (Val, Ty, DL)) {
374
+ auto TryCastValTy = [&](Constant *P) -> Constant * {
375
+ // The conversion is illegal if the store is wider than the
376
+ // pointee proposed by `evaluateBitcastFromPtr`, since that would
377
+ // drop stores to other struct elements when the caller attempts to
378
+ // look through a struct's 0th element.
379
+ Type *NewTy = cast<PointerType>(P->getType ())->getElementType ();
380
+ Type *STy = Val->getType ();
381
+ if (DL.getTypeSizeInBits (NewTy) < DL.getTypeSizeInBits (STy))
382
+ return nullptr ;
383
+
384
+ if (Constant *FV = ConstantFoldLoadThroughBitcast (Val, NewTy, DL)) {
375
385
Ptr = P;
376
386
return FV;
377
387
}
378
388
return nullptr ;
379
389
};
380
390
381
391
Constant *NewVal =
382
- evaluateBitcastFromPtr (CE->getOperand (0 ), DL, TLI, castValTy );
392
+ evaluateBitcastFromPtr (CE->getOperand (0 ), DL, TLI, TryCastValTy );
383
393
if (!NewVal) {
384
394
LLVM_DEBUG (dbgs () << " Failed to bitcast constant ptr, can not "
385
395
" evaluate.\n " );
0 commit comments