[llvm] [LLVM][C API] Clearing initializer and personality by passing NULL. (PR #105521)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 21 06:14:45 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-ir

Author: Tim Besard (maleadt)

<details>
<summary>Changes</summary>

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

---
Full diff: https://github.com/llvm/llvm-project/pull/105521.diff


3 Files Affected:

- (modified) llvm/lib/IR/Core.cpp (+10-5) 
- (modified) llvm/unittests/IR/FunctionTest.cpp (+26) 
- (modified) llvm/unittests/IR/ValueTest.cpp (+24) 


``````````diff
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index 7665385025bd91..9b4e3301c96750 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -1328,8 +1328,12 @@ LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count) {
   return LLVMMDNodeInContext(LLVMGetGlobalContext(), Vals, Count);
 }
 
-LLVMValueRef LLVMMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD) {
-  return wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD)));
+LLVMValueRef LLVMMetadataAsValue(LLVMContextRef C, LLVMMetadataRef Metadata) {
+  auto *MD = unwrap(Metadata);
+  if (auto *VAM = dyn_cast<ValueAsMetadata>(MD))
+    return wrap(VAM->getValue());
+  else
+    return wrap(MetadataAsValue::get(*unwrap(C), MD));
 }
 
 LLVMMetadataRef LLVMValueAsMetadata(LLVMValueRef Val) {
@@ -2261,8 +2265,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 +2449,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

``````````

</details>


https://github.com/llvm/llvm-project/pull/105521


More information about the llvm-commits mailing list