Skip to content

Commit 0bd5130

Browse files
authored
[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`.
1 parent 82e314e commit 0bd5130

File tree

4 files changed

+57
-3
lines changed

4 files changed

+57
-3
lines changed

llvm/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@ Changes to the C API
189189
Because of backwards compatibility, ``LLVMIsAtomicSingleThread`` and
190190
``LLVMSetAtomicSingleThread`` continue to work with any instruction type.
191191

192+
* The `LLVMSetPersonalityFn` and `LLVMSetInitializer` APIs now support clearing the
193+
personality function and initializer respectively by passing a null pointer.
194+
192195

193196
Changes to the CodeGen infrastructure
194197
-------------------------------------

llvm/lib/IR/Core.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2261,8 +2261,8 @@ LLVMValueRef LLVMGetInitializer(LLVMValueRef GlobalVar) {
22612261
}
22622262

22632263
void LLVMSetInitializer(LLVMValueRef GlobalVar, LLVMValueRef ConstantVal) {
2264-
unwrap<GlobalVariable>(GlobalVar)
2265-
->setInitializer(unwrap<Constant>(ConstantVal));
2264+
unwrap<GlobalVariable>(GlobalVar)->setInitializer(
2265+
ConstantVal ? unwrap<Constant>(ConstantVal) : nullptr);
22662266
}
22672267

22682268
LLVMBool LLVMIsThreadLocal(LLVMValueRef GlobalVar) {
@@ -2445,7 +2445,8 @@ LLVMValueRef LLVMGetPersonalityFn(LLVMValueRef Fn) {
24452445
}
24462446

24472447
void LLVMSetPersonalityFn(LLVMValueRef Fn, LLVMValueRef PersonalityFn) {
2448-
unwrap<Function>(Fn)->setPersonalityFn(unwrap<Constant>(PersonalityFn));
2448+
unwrap<Function>(Fn)->setPersonalityFn(
2449+
PersonalityFn ? unwrap<Constant>(PersonalityFn) : nullptr);
24492450
}
24502451

24512452
unsigned LLVMGetIntrinsicID(LLVMValueRef Fn) {

llvm/unittests/IR/FunctionTest.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "llvm/IR/Function.h"
10+
#include "llvm-c/Core.h"
1011
#include "llvm/AsmParser/Parser.h"
1112
#include "llvm/IR/Module.h"
1213
#include "llvm/Support/SourceMgr.h"
@@ -601,4 +602,29 @@ TEST(FunctionTest, UWTable) {
601602
EXPECT_FALSE(F.hasUWTable());
602603
EXPECT_TRUE(F.getUWTableKind() == UWTableKind::None);
603604
}
605+
606+
TEST(FunctionTest, Personality) {
607+
LLVMContext Ctx;
608+
Module M("test", Ctx);
609+
Type *Int8Ty = Type::getInt8Ty(Ctx);
610+
FunctionType *FTy = FunctionType::get(Int8Ty, false);
611+
Function *F = Function::Create(FTy, GlobalValue::ExternalLinkage, "F", &M);
612+
Function *PersonalityFn =
613+
Function::Create(FTy, GlobalValue::ExternalLinkage, "PersonalityFn", &M);
614+
615+
EXPECT_FALSE(F->hasPersonalityFn());
616+
F->setPersonalityFn(PersonalityFn);
617+
EXPECT_TRUE(F->hasPersonalityFn());
618+
EXPECT_EQ(F->getPersonalityFn(), PersonalityFn);
619+
F->setPersonalityFn(nullptr);
620+
EXPECT_FALSE(F->hasPersonalityFn());
621+
622+
EXPECT_FALSE(LLVMHasPersonalityFn(wrap(F)));
623+
LLVMSetPersonalityFn(wrap(F), wrap(PersonalityFn));
624+
EXPECT_TRUE(LLVMHasPersonalityFn(wrap(F)));
625+
EXPECT_EQ(LLVMGetPersonalityFn(wrap(F)), wrap(PersonalityFn));
626+
LLVMSetPersonalityFn(wrap(F), nullptr);
627+
EXPECT_FALSE(LLVMHasPersonalityFn(wrap(F)));
628+
}
629+
604630
} // end namespace

llvm/unittests/IR/ValueTest.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "llvm/IR/Value.h"
10+
#include "llvm-c/Core.h"
1011
#include "llvm/AsmParser/Parser.h"
1112
#include "llvm/IR/Function.h"
1213
#include "llvm/IR/IntrinsicInst.h"
@@ -391,4 +392,27 @@ TEST(ValueTest, replaceUsesOutsideBlockDbgVariableRecord) {
391392
EXPECT_TRUE(DVR2->getVariableLocationOp(0) == cast<Value>(B));
392393
}
393394

395+
TEST(GlobalTest, Initializer) {
396+
LLVMContext Ctx;
397+
Module M("test", Ctx);
398+
Type *Int8Ty = Type::getInt8Ty(Ctx);
399+
Constant *Int8Null = Constant::getNullValue(Int8Ty);
400+
401+
GlobalVariable *GV = new GlobalVariable(
402+
M, Int8Ty, false, GlobalValue::ExternalLinkage, nullptr, "GV");
403+
404+
EXPECT_FALSE(GV->hasInitializer());
405+
GV->setInitializer(Int8Null);
406+
EXPECT_TRUE(GV->hasInitializer());
407+
EXPECT_EQ(GV->getInitializer(), Int8Null);
408+
GV->setInitializer(nullptr);
409+
EXPECT_FALSE(GV->hasInitializer());
410+
411+
EXPECT_EQ(LLVMGetInitializer(wrap(GV)), nullptr);
412+
LLVMSetInitializer(wrap(GV), wrap(Int8Null));
413+
EXPECT_EQ(LLVMGetInitializer(wrap(GV)), wrap(Int8Null));
414+
LLVMSetInitializer(wrap(GV), nullptr);
415+
EXPECT_EQ(LLVMGetInitializer(wrap(GV)), nullptr);
416+
}
417+
394418
} // end anonymous namespace

0 commit comments

Comments
 (0)