@@ -174,16 +174,16 @@ static bool isSimpleEnoughPointerToCommit(Constant *C, const DataLayout &DL) {
174174 return false ;
175175}
176176
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.
181181static Constant *
182182evaluateBitcastFromPtr (Constant *Ptr, const DataLayout &DL,
183183 const TargetLibraryInfo *TLI,
184- std::function<Constant *(Constant *)> Func ) {
184+ std::function<Constant *(Constant *)> TryLoad ) {
185185 Constant *Val;
186- while (!(Val = Func (Ptr))) {
186+ while (!(Val = TryLoad (Ptr))) {
187187 // If Ty is a non-opaque struct, we can convert the pointer to the struct
188188 // into a pointer to its first member.
189189 // FIXME: This could be extended to support arrays as well.
@@ -211,9 +211,11 @@ static Constant *getInitializer(Constant *C) {
211211Constant *Evaluator::ComputeLoadResult (Constant *P, Type *Ty) {
212212 // If this memory location has been recently stored, use the stored value: it
213213 // 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+ };
215217
216- if (Constant *Val = findMemLoc (P))
218+ if (Constant *Val = TryFindMemLoc (P))
217219 return Val;
218220
219221 // Access it.
@@ -237,7 +239,7 @@ Constant *Evaluator::ComputeLoadResult(Constant *P, Type *Ty) {
237239 // If it hasn't, we may still be able to find a stored pointer by
238240 // introspecting the type.
239241 Constant *Val =
240- evaluateBitcastFromPtr (CE->getOperand (0 ), DL, TLI, findMemLoc );
242+ evaluateBitcastFromPtr (CE->getOperand (0 ), DL, TLI, TryFindMemLoc );
241243 if (!Val)
242244 Val = getInitializer (CE->getOperand (0 ));
243245 if (Val)
@@ -369,17 +371,25 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst, BasicBlock *&NextBB,
369371 // legal. If it's not, we can try introspecting the type to find a
370372 // legal conversion.
371373
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)) {
375385 Ptr = P;
376386 return FV;
377387 }
378388 return nullptr ;
379389 };
380390
381391 Constant *NewVal =
382- evaluateBitcastFromPtr (CE->getOperand (0 ), DL, TLI, castValTy );
392+ evaluateBitcastFromPtr (CE->getOperand (0 ), DL, TLI, TryCastValTy );
383393 if (!NewVal) {
384394 LLVM_DEBUG (dbgs () << " Failed to bitcast constant ptr, can not "
385395 " evaluate.\n " );
0 commit comments