diff options
author | lolloz98 <lorenzocarpaneto@yahoo.it> | 2024-05-21 19:51:21 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-21 11:51:21 -0700 |
commit | 67ae86d700b899979db39883f4063257513498d5 (patch) | |
tree | 915ce4d261f0d8e005aaccfb9e432fe20eb7de97 /clang/lib/CodeGen/CodeGenModule.cpp | |
parent | 8cb19ebd219668ef8efa9ffb4a72e39b18dd91d4 (diff) | |
download | llvm-67ae86d700b899979db39883f4063257513498d5.zip llvm-67ae86d700b899979db39883f4063257513498d5.tar.gz llvm-67ae86d700b899979db39883f4063257513498d5.tar.bz2 |
[clang] Fix crash passing function pointer without prototype. (#90255)
Fixes use-after-free iterating over the uses of the function.
Closes #88917
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 227813a..60ef28a 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -5740,15 +5740,17 @@ CodeGenModule::getLLVMLinkageVarDefinition(const VarDecl *VD) { static void replaceUsesOfNonProtoConstant(llvm::Constant *old, llvm::Function *newFn) { // Fast path. - if (old->use_empty()) return; + if (old->use_empty()) + return; llvm::Type *newRetTy = newFn->getReturnType(); - SmallVector<llvm::Value*, 4> newArgs; + SmallVector<llvm::Value *, 4> newArgs; + + SmallVector<llvm::CallBase *> callSitesToBeRemovedFromParent; for (llvm::Value::use_iterator ui = old->use_begin(), ue = old->use_end(); - ui != ue; ) { - llvm::Value::use_iterator use = ui++; // Increment before the use is erased. - llvm::User *user = use->getUser(); + ui != ue; ui++) { + llvm::User *user = ui->getUser(); // Recognize and replace uses of bitcasts. Most calls to // unprototyped functions will use bitcasts. @@ -5760,8 +5762,9 @@ static void replaceUsesOfNonProtoConstant(llvm::Constant *old, // Recognize calls to the function. llvm::CallBase *callSite = dyn_cast<llvm::CallBase>(user); - if (!callSite) continue; - if (!callSite->isCallee(&*use)) + if (!callSite) + continue; + if (!callSite->isCallee(&*ui)) continue; // If the return types don't match exactly, then we can't @@ -5830,6 +5833,10 @@ static void replaceUsesOfNonProtoConstant(llvm::Constant *old, if (callSite->getDebugLoc()) newCall->setDebugLoc(callSite->getDebugLoc()); + callSitesToBeRemovedFromParent.push_back(callSite); + } + + for (auto *callSite : callSitesToBeRemovedFromParent) { callSite->eraseFromParent(); } } |