[clang] [clang] solve crash due to function overloading. (PR #90255)

via cfe-commits cfe-commits at lists.llvm.org
Mon May 20 12:35:28 PDT 2024


https://github.com/lolloz98 updated https://github.com/llvm/llvm-project/pull/90255

>From 0d473873057b094c8cf112f7075c4a578e54a4f5 Mon Sep 17 00:00:00 2001
From: lolloz98 <lorenzocarpaneto at yahoo.it>
Date: Fri, 26 Apr 2024 20:31:32 +0100
Subject: [PATCH 1/3] [clang] solve crash due to function overloading.

---
 clang/lib/CodeGen/CodeGenModule.cpp          | 16 ++++++++++++----
 clang/test/CodeGen/function_overload_crash.c |  7 +++++++
 2 files changed, 19 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/CodeGen/function_overload_crash.c

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 0c447b20cef40..bed5669861392 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -5702,13 +5702,16 @@ 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; ) {
+       ui != ue;) {
     llvm::Value::use_iterator use = ui++; // Increment before the use is erased.
     llvm::User *user = use->getUser();
 
@@ -5722,7 +5725,8 @@ static void replaceUsesOfNonProtoConstant(llvm::Constant *old,
 
     // Recognize calls to the function.
     llvm::CallBase *callSite = dyn_cast<llvm::CallBase>(user);
-    if (!callSite) continue;
+    if (!callSite)
+      continue;
     if (!callSite->isCallee(&*use))
       continue;
 
@@ -5792,6 +5796,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/function_overload_crash.c b/clang/test/CodeGen/function_overload_crash.c
new file mode 100644
index 0000000000000..094b56030d7ae
--- /dev/null
+++ b/clang/test/CodeGen/function_overload_crash.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm < %s
+
+int b();
+int main() { return b(b); }
+int b(int (*f)()){
+  return 0;
+}
\ No newline at end of file

>From 85270dc7c6e5bfb629a91d5a17d85d47dce15a2f Mon Sep 17 00:00:00 2001
From: lolloz98 <lorenzocarpaneto at yahoo.it>
Date: Thu, 2 May 2024 22:17:10 +0100
Subject: [PATCH 2/3] avoid early increment in loop

---
 clang/lib/CodeGen/CodeGenModule.cpp | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index bed5669861392..0b93220e0b00c 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -5711,9 +5711,8 @@ static void replaceUsesOfNonProtoConstant(llvm::Constant *old,
   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.
@@ -5727,7 +5726,7 @@ static void replaceUsesOfNonProtoConstant(llvm::Constant *old,
     llvm::CallBase *callSite = dyn_cast<llvm::CallBase>(user);
     if (!callSite)
       continue;
-    if (!callSite->isCallee(&*use))
+    if (!callSite->isCallee(&*ui))
       continue;
 
     // If the return types don't match exactly, then we can't

>From 5c0d09e595b581d7ecb116ec681bf4fbe2d08fbb Mon Sep 17 00:00:00 2001
From: lolloz98 <lorenzocarpaneto at yahoo.it>
Date: Mon, 20 May 2024 20:34:33 +0100
Subject: [PATCH 3/3] Fix test and put it in an existent test

---
 clang/test/CodeGen/function_overload_crash.c |  7 -------
 clang/test/CodeGen/functions.c               | 12 ++++++++++++
 2 files changed, 12 insertions(+), 7 deletions(-)
 delete mode 100644 clang/test/CodeGen/function_overload_crash.c

diff --git a/clang/test/CodeGen/function_overload_crash.c b/clang/test/CodeGen/function_overload_crash.c
deleted file mode 100644
index 094b56030d7ae..0000000000000
--- a/clang/test/CodeGen/function_overload_crash.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: %clang_cc1 -emit-llvm < %s
-
-int b();
-int main() { return b(b); }
-int b(int (*f)()){
-  return 0;
-}
\ No newline at end of file
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