Index: lib/IR/Core.cpp =================================================================== --- lib/IR/Core.cpp +++ lib/IR/Core.cpp @@ -563,9 +563,23 @@ return nullptr; } -void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef MD) { - MDNode *N = - MD ? cast(unwrap(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(MD) || isa(MD)) && + "Expected a metadata node or a canonicalized constant"); + + if (MDNode *N = dyn_cast(MD)) + return N; + + return MDNode::get(MAV->getContext(), MD); +} + +void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef Val) { + MDNode *N = Val ? extractMDNode(unwrap(Val)) : nullptr; + unwrap(Inst)->setMetadata(KindID, N); } @@ -795,7 +809,7 @@ return; if (!Val) return; - N->addOperand(cast(unwrap(Val)->getMetadata())); + N->addOperand(extractMDNode(unwrap(Val))); } /*--.. Operations on scalar constants ......................................--*/ Index: test/Bindings/llvm-c/add_named_metadata_operand.ll =================================================================== --- /dev/null +++ test/Bindings/llvm-c/add_named_metadata_operand.ll @@ -0,0 +1,2 @@ +; RUN: llvm-c-test --add-named-metadata-operand < /dev/null +; This used to trigger an assertion Index: test/Bindings/llvm-c/set_metadata.ll =================================================================== --- /dev/null +++ test/Bindings/llvm-c/set_metadata.ll @@ -0,0 +1,2 @@ +; RUN: llvm-c-test --set-metadata < /dev/null +; This used to trigger an assertion Index: tools/llvm-c-test/CMakeLists.txt =================================================================== --- tools/llvm-c-test/CMakeLists.txt +++ tools/llvm-c-test/CMakeLists.txt @@ -41,6 +41,7 @@ include-all.c main.c module.c + metadata.c object.c targets.c ) Index: tools/llvm-c-test/llvm-c-test.h =================================================================== --- tools/llvm-c-test/llvm-c-test.h +++ tools/llvm-c-test/llvm-c-test.h @@ -27,6 +27,10 @@ // 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); Index: tools/llvm-c-test/main.c =================================================================== --- tools/llvm-c-test/main.c +++ tools/llvm-c-test/main.c @@ -65,6 +65,10 @@ 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(); } Index: tools/llvm-c-test/metadata.c =================================================================== --- tools/llvm-c-test/metadata.c +++ tools/llvm-c-test/metadata.c @@ -1,4 +1,4 @@ -/*===-- llvm-c-test.h - tool for testing libLLVM and llvm-c API -----------===*\ +/*===-- object.c - tool for testing libLLVM and llvm-c API ----------------===*\ |* *| |* The LLVM Compiler Infrastructure *| |* *| @@ -7,31 +7,32 @@ |* *| |*===----------------------------------------------------------------------===*| |* *| -|* Header file for llvm-c-test *| +|* This file implements the --set-metadata command in llvm-c-test. *| |* *| \*===----------------------------------------------------------------------===*/ -#ifndef LLVM_C_TEST_H -#define LLVM_C_TEST_H -// helpers.c -void tokenize_stdin(void (*cb)(char **tokens, int ntokens)); +#include "llvm-c-test.h" +#include "llvm-c/Core.h" -// module.c -int module_dump(void); -int module_list_functions(void); -int module_list_globals(void); +int add_named_metadata_operand(void) { + LLVMModuleRef m = LLVMModuleCreateWithName("Mod"); + LLVMValueRef values[] = { LLVMConstInt(LLVMInt32Type(), 0, 0) }; -// calc.c -int calc(void); + // This used to trigger an assertion + LLVMAddNamedMetadataOperand(m, "name", LLVMMDNode(values, 1)); -// disassemble.c -int disassemble(void); + return 0; +} -// object.c -int object_list_sections(void); -int object_list_symbols(void); +int set_metadata(void) { + LLVMBuilderRef b = LLVMCreateBuilder(); + LLVMValueRef values[] = { LLVMConstInt(LLVMInt32Type(), 0, 0) }; -// targets.c -int targets_list(void); + // This used to trigger an assertion + LLVMSetMetadata( + LLVMBuildRetVoid(b), + LLVMGetMDKindID("kind", 4), + LLVMMDNode(values, 1)); -#endif + return 0; +}