[clang] 67ae86d - [clang] Fix crash passing function pointer without prototype. (#90255)
via cfe-commits
cfe-commits at lists.llvm.org
Tue May 21 11:51:25 PDT 2024
Author: lolloz98
Date: 2024-05-21T11:51:21-07:00
New Revision: 67ae86d700b899979db39883f4063257513498d5
URL: https://github.com/llvm/llvm-project/commit/67ae86d700b899979db39883f4063257513498d5
DIFF: https://github.com/llvm/llvm-project/commit/67ae86d700b899979db39883f4063257513498d5.diff
LOG: [clang] Fix crash passing function pointer without prototype. (#90255)
Fixes use-after-free iterating over the uses of the function.
Closes #88917
Added:
Modified:
clang/lib/CodeGen/CodeGenModule.cpp
clang/test/CodeGen/functions.c
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 227813ad44e8b..60ef28a0effaa 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();
}
}
diff --git a/clang/test/CodeGen/functions.c b/clang/test/CodeGen/functions.c
index 1bbaa80d653c4..0cc999aa4916e 100644
--- a/clang/test/CodeGen/functions.c
+++ b/clang/test/CodeGen/functions.c
@@ -61,3 +61,15 @@ static void test9_helper(void) {}
void test9(void) {
(void) test9_helper;
}
+
+// PR88917: don't crash
+int b();
+
+int main() {
+ return b(b);
+ // CHECK: call i32 @b(ptr noundef @b)
+}
+int b(int (*f)()){
+ return 0;
+}
+// CHECK-LABEL: define{{.*}} i32 @b(ptr noundef %f)
More information about the cfe-commits
mailing list