mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-18 10:35:55 +00:00
Pull in r292133 from upstream llvm trunk (by Hal Finkel):
Fix use-after-free bug in AffectedValueCallbackVH::allUsesReplacedWith When transferring affected values in the cache from an old value, identified by the value of the current callback, to the specified new value we might need to insert a new entry into the DenseMap which constitutes the cache. Doing so might delete the current callback object. Move the copying logic into a new function, a member of the assumption cache itself, so that we don't run into UB should the callback handle itself be removed mid-copy. Differential Revision: https://reviews.llvm.org/D28749 This should fix crashes when building lld (as part of the llvmXY ports). Reported by: jbeich PR: 216117
This commit is contained in:
parent
2714e44c8b
commit
9b1870035a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/clang400-import/; revision=312308
@ -68,7 +68,10 @@ class AssumptionCache {
|
||||
AffectedValuesMap AffectedValues;
|
||||
|
||||
/// Get the vector of assumptions which affect a value from the cache.
|
||||
SmallVector<WeakVH, 1> &getAffectedValues(Value *V);
|
||||
SmallVector<WeakVH, 1> &getOrInsertAffectedValues(Value *V);
|
||||
|
||||
/// Copy affected values in the cache for OV to be affected values for NV.
|
||||
void copyAffectedValuesInCache(Value *OV, Value *NV);
|
||||
|
||||
/// \brief Flag tracking whether we have scanned the function yet.
|
||||
///
|
||||
|
@ -24,7 +24,7 @@
|
||||
using namespace llvm;
|
||||
using namespace llvm::PatternMatch;
|
||||
|
||||
SmallVector<WeakVH, 1> &AssumptionCache::getAffectedValues(Value *V) {
|
||||
SmallVector<WeakVH, 1> &AssumptionCache::getOrInsertAffectedValues(Value *V) {
|
||||
// Try using find_as first to avoid creating extra value handles just for the
|
||||
// purpose of doing the lookup.
|
||||
auto AVI = AffectedValues.find_as(V);
|
||||
@ -98,7 +98,7 @@ void AssumptionCache::updateAffectedValues(CallInst *CI) {
|
||||
}
|
||||
|
||||
for (auto &AV : Affected) {
|
||||
auto &AVV = getAffectedValues(AV);
|
||||
auto &AVV = getOrInsertAffectedValues(AV);
|
||||
if (std::find(AVV.begin(), AVV.end(), CI) == AVV.end())
|
||||
AVV.push_back(CI);
|
||||
}
|
||||
@ -111,20 +111,27 @@ void AssumptionCache::AffectedValueCallbackVH::deleted() {
|
||||
// 'this' now dangles!
|
||||
}
|
||||
|
||||
void AssumptionCache::copyAffectedValuesInCache(Value *OV, Value *NV) {
|
||||
auto &NAVV = getOrInsertAffectedValues(NV);
|
||||
auto AVI = AffectedValues.find(OV);
|
||||
if (AVI == AffectedValues.end())
|
||||
return;
|
||||
|
||||
for (auto &A : AVI->second)
|
||||
if (std::find(NAVV.begin(), NAVV.end(), A) == NAVV.end())
|
||||
NAVV.push_back(A);
|
||||
}
|
||||
|
||||
void AssumptionCache::AffectedValueCallbackVH::allUsesReplacedWith(Value *NV) {
|
||||
if (!isa<Instruction>(NV) && !isa<Argument>(NV))
|
||||
return;
|
||||
|
||||
// Any assumptions that affected this value now affect the new value.
|
||||
|
||||
auto &NAVV = AC->getAffectedValues(NV);
|
||||
auto AVI = AC->AffectedValues.find(getValPtr());
|
||||
if (AVI == AC->AffectedValues.end())
|
||||
return;
|
||||
|
||||
for (auto &A : AVI->second)
|
||||
if (std::find(NAVV.begin(), NAVV.end(), A) == NAVV.end())
|
||||
NAVV.push_back(A);
|
||||
AC->copyAffectedValuesInCache(getValPtr(), NV);
|
||||
// 'this' now might dangle! If the AffectedValues map was resized to add an
|
||||
// entry for NV then this object might have been destroyed in favor of some
|
||||
// copy in the grown map.
|
||||
}
|
||||
|
||||
void AssumptionCache::scanFunction() {
|
||||
|
Loading…
Reference in New Issue
Block a user