[llvm] 0bd5130 - [LLVM][C API] Clearing initializer and personality by passing NULL (#105521)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 28 02:30:52 PDT 2024


Author: Tim Besard
Date: 2024-08-28T11:30:49+02:00
New Revision: 0bd513082540b2b00bfad1540812e3ea282e70ed

URL: https://github.com/llvm/llvm-project/commit/0bd513082540b2b00bfad1540812e3ea282e70ed
DIFF: https://github.com/llvm/llvm-project/commit/0bd513082540b2b00bfad1540812e3ea282e70ed.diff

LOG: [LLVM][C API] Clearing initializer and personality by passing NULL (#105521)

This is similar to how the C++ API supports passing `nullptr` to
`setPersonalityFn` or `setInitializer`.

Added: 
    

Modified: 
    llvm/docs/ReleaseNotes.rst
    llvm/lib/IR/Core.cpp
    llvm/unittests/IR/FunctionTest.cpp
    llvm/unittests/IR/ValueTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 2b68c54de8beb7..c2773c92498de9 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -189,6 +189,9 @@ Changes to the C API
     Because of backwards compatibility, ``LLVMIsAtomicSingleThread`` and
     ``LLVMSetAtomicSingleThread`` continue to work with any instruction type.
 
+* The `LLVMSetPersonalityFn` and `LLVMSetInitializer` APIs now support clearing the
+  personality function and initializer respectively by passing a null pointer.
+
 
 Changes to the CodeGen infrastructure
 -------------------------------------

diff  --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index 7665385025bd91..28f603b2c38c8a 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -2261,8 +2261,8 @@ LLVMValueRef LLVMGetInitializer(LLVMValueRef GlobalVar) {
 }
 
 void LLVMSetInitializer(LLVMValueRef GlobalVar, LLVMValueRef ConstantVal) {
-  unwrap<GlobalVariable>(GlobalVar)
-    ->setInitializer(unwrap<Constant>(ConstantVal));
+  unwrap<GlobalVariable>(GlobalVar)->setInitializer(
+      ConstantVal ? unwrap<Constant>(ConstantVal) : nullptr);
 }
 
 LLVMBool LLVMIsThreadLocal(LLVMValueRef GlobalVar) {
@@ -2445,7 +2445,8 @@ LLVMValueRef LLVMGetPersonalityFn(LLVMValueRef Fn) {
 }
 
 void LLVMSetPersonalityFn(LLVMValueRef Fn, LLVMValueRef PersonalityFn) {
-  unwrap<Function>(Fn)->setPersonalityFn(unwrap<Constant>(PersonalityFn));
+  unwrap<Function>(Fn)->setPersonalityFn(
+      PersonalityFn ? unwrap<Constant>(PersonalityFn) : nullptr);
 }
 
 unsigned LLVMGetIntrinsicID(LLVMValueRef Fn) {

diff  --git a/llvm/unittests/IR/FunctionTest.cpp b/llvm/unittests/IR/FunctionTest.cpp
index 402667931fbc5c..f6735fb55a6d52 100644
--- a/llvm/unittests/IR/FunctionTest.cpp
+++ b/llvm/unittests/IR/FunctionTest.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/IR/Function.h"
+#include "llvm-c/Core.h"
 #include "llvm/AsmParser/Parser.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/SourceMgr.h"
@@ -601,4 +602,29 @@ TEST(FunctionTest, UWTable) {
   EXPECT_FALSE(F.hasUWTable());
   EXPECT_TRUE(F.getUWTableKind() == UWTableKind::None);
 }
+
+TEST(FunctionTest, Personality) {
+  LLVMContext Ctx;
+  Module M("test", Ctx);
+  Type *Int8Ty = Type::getInt8Ty(Ctx);
+  FunctionType *FTy = FunctionType::get(Int8Ty, false);
+  Function *F = Function::Create(FTy, GlobalValue::ExternalLinkage, "F", &M);
+  Function *PersonalityFn =
+      Function::Create(FTy, GlobalValue::ExternalLinkage, "PersonalityFn", &M);
+
+  EXPECT_FALSE(F->hasPersonalityFn());
+  F->setPersonalityFn(PersonalityFn);
+  EXPECT_TRUE(F->hasPersonalityFn());
+  EXPECT_EQ(F->getPersonalityFn(), PersonalityFn);
+  F->setPersonalityFn(nullptr);
+  EXPECT_FALSE(F->hasPersonalityFn());
+
+  EXPECT_FALSE(LLVMHasPersonalityFn(wrap(F)));
+  LLVMSetPersonalityFn(wrap(F), wrap(PersonalityFn));
+  EXPECT_TRUE(LLVMHasPersonalityFn(wrap(F)));
+  EXPECT_EQ(LLVMGetPersonalityFn(wrap(F)), wrap(PersonalityFn));
+  LLVMSetPersonalityFn(wrap(F), nullptr);
+  EXPECT_FALSE(LLVMHasPersonalityFn(wrap(F)));
+}
+
 } // end namespace

diff  --git a/llvm/unittests/IR/ValueTest.cpp b/llvm/unittests/IR/ValueTest.cpp
index 33a86d510d45cb..a90438a078c62e 100644
--- a/llvm/unittests/IR/ValueTest.cpp
+++ b/llvm/unittests/IR/ValueTest.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/IR/Value.h"
+#include "llvm-c/Core.h"
 #include "llvm/AsmParser/Parser.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/IntrinsicInst.h"
@@ -391,4 +392,27 @@ TEST(ValueTest, replaceUsesOutsideBlockDbgVariableRecord) {
   EXPECT_TRUE(DVR2->getVariableLocationOp(0) == cast<Value>(B));
 }
 
+TEST(GlobalTest, Initializer) {
+  LLVMContext Ctx;
+  Module M("test", Ctx);
+  Type *Int8Ty = Type::getInt8Ty(Ctx);
+  Constant *Int8Null = Constant::getNullValue(Int8Ty);
+
+  GlobalVariable *GV = new GlobalVariable(
+      M, Int8Ty, false, GlobalValue::ExternalLinkage, nullptr, "GV");
+
+  EXPECT_FALSE(GV->hasInitializer());
+  GV->setInitializer(Int8Null);
+  EXPECT_TRUE(GV->hasInitializer());
+  EXPECT_EQ(GV->getInitializer(), Int8Null);
+  GV->setInitializer(nullptr);
+  EXPECT_FALSE(GV->hasInitializer());
+
+  EXPECT_EQ(LLVMGetInitializer(wrap(GV)), nullptr);
+  LLVMSetInitializer(wrap(GV), wrap(Int8Null));
+  EXPECT_EQ(LLVMGetInitializer(wrap(GV)), wrap(Int8Null));
+  LLVMSetInitializer(wrap(GV), nullptr);
+  EXPECT_EQ(LLVMGetInitializer(wrap(GV)), nullptr);
+}
+
 } // end anonymous namespace


        


More information about the llvm-commits mailing list