mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
Fix LLVMSetMetadata and LLVMAddNamedMetadataOperand for single value MDNodes
Summary: MetadataAsValue uses a canonical format that strips the MDNode if it contains only a single constant value. This triggers an assertion when trying to cast the value to a MDNode. Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D7165 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227319 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9c49a6d449
commit
920382c5aa
@ -563,9 +563,23 @@ LLVMValueRef LLVMGetMetadata(LLVMValueRef Inst, unsigned KindID) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef MD) {
|
||||
MDNode *N =
|
||||
MD ? cast<MDNode>(unwrap<MetadataAsValue>(MD)->getMetadata()) : nullptr;
|
||||
// MetadataAsValue uses a canonical format which strips the actual MDNode for
|
||||
// MDNode with just a single constant value, storing just a ConstantAsMetadata
|
||||
// This undoes this canonicalization, reconstructing the MDNode.
|
||||
static MDNode *extractMDNode(MetadataAsValue *MAV) {
|
||||
Metadata *MD = MAV->getMetadata();
|
||||
assert((isa<MDNode>(MD) || isa<ConstantAsMetadata>(MD)) &&
|
||||
"Expected a metadata node or a canonicalized constant");
|
||||
|
||||
if (MDNode *N = dyn_cast<MDNode>(MD))
|
||||
return N;
|
||||
|
||||
return MDNode::get(MAV->getContext(), MD);
|
||||
}
|
||||
|
||||
void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef Val) {
|
||||
MDNode *N = Val ? extractMDNode(unwrap<MetadataAsValue>(Val)) : nullptr;
|
||||
|
||||
unwrap<Instruction>(Inst)->setMetadata(KindID, N);
|
||||
}
|
||||
|
||||
@ -795,7 +809,7 @@ void LLVMAddNamedMetadataOperand(LLVMModuleRef M, const char* name,
|
||||
return;
|
||||
if (!Val)
|
||||
return;
|
||||
N->addOperand(cast<MDNode>(unwrap<MetadataAsValue>(Val)->getMetadata()));
|
||||
N->addOperand(extractMDNode(unwrap<MetadataAsValue>(Val)));
|
||||
}
|
||||
|
||||
/*--.. Operations on scalar constants ......................................--*/
|
||||
|
2
test/Bindings/llvm-c/add_named_metadata_operand.ll
Normal file
2
test/Bindings/llvm-c/add_named_metadata_operand.ll
Normal file
@ -0,0 +1,2 @@
|
||||
; RUN: llvm-c-test --add-named-metadata-operand < /dev/null
|
||||
; This used to trigger an assertion
|
2
test/Bindings/llvm-c/set_metadata.ll
Normal file
2
test/Bindings/llvm-c/set_metadata.ll
Normal file
@ -0,0 +1,2 @@
|
||||
; RUN: llvm-c-test --set-metadata < /dev/null
|
||||
; This used to trigger an assertion
|
@ -41,6 +41,7 @@ add_llvm_tool(llvm-c-test
|
||||
include-all.c
|
||||
main.c
|
||||
module.c
|
||||
metadata.c
|
||||
object.c
|
||||
targets.c
|
||||
)
|
||||
|
@ -27,6 +27,10 @@ int calc(void);
|
||||
// disassemble.c
|
||||
int disassemble(void);
|
||||
|
||||
// metadata.c
|
||||
int add_named_metadata_operand(void);
|
||||
int set_metadata(void);
|
||||
|
||||
// object.c
|
||||
int object_list_sections(void);
|
||||
int object_list_symbols(void);
|
||||
|
@ -65,6 +65,10 @@ int main(int argc, char **argv) {
|
||||
return disassemble();
|
||||
} else if (argc == 2 && !strcmp(argv[1], "--calc")) {
|
||||
return calc();
|
||||
} else if (argc == 2 && !strcmp(argv[1], "--add-named-metadata-operand")) {
|
||||
return add_named_metadata_operand();
|
||||
} else if (argc == 2 && !strcmp(argv[1], "--set-metadata")) {
|
||||
return set_metadata();
|
||||
} else {
|
||||
print_usage();
|
||||
}
|
||||
|
39
tools/llvm-c-test/metadata.c
Normal file
39
tools/llvm-c-test/metadata.c
Normal file
@ -0,0 +1,39 @@
|
||||
/*===-- object.c - tool for testing libLLVM and llvm-c API ----------------===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This file implements the --add-named-metadata-operand and --set-metadata *|
|
||||
|* commands in llvm-c-test. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#include "llvm-c-test.h"
|
||||
#include "llvm-c/Core.h"
|
||||
|
||||
int add_named_metadata_operand(void) {
|
||||
LLVMModuleRef m = LLVMModuleCreateWithName("Mod");
|
||||
LLVMValueRef values[] = { LLVMConstInt(LLVMInt32Type(), 0, 0) };
|
||||
|
||||
// This used to trigger an assertion
|
||||
LLVMAddNamedMetadataOperand(m, "name", LLVMMDNode(values, 1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_metadata(void) {
|
||||
LLVMBuilderRef b = LLVMCreateBuilder();
|
||||
LLVMValueRef values[] = { LLVMConstInt(LLVMInt32Type(), 0, 0) };
|
||||
|
||||
// This used to trigger an assertion
|
||||
LLVMSetMetadata(
|
||||
LLVMBuildRetVoid(b),
|
||||
LLVMGetMDKindID("kind", 4),
|
||||
LLVMMDNode(values, 1));
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user