Commit ac43b521 authored by Hans Wennborg's avatar Hans Wennborg
Browse files

Merging r227319:

------------------------------------------------------------------------
r227319 | bsteinbr | 2015-01-28 08:35:59 -0800 (Wed, 28 Jan 2015) | 10 lines

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
------------------------------------------------------------------------

llvm-svn: 227475
parent 81f37c0d
Loading
Loading
Loading
Loading
+18 −4
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
; RUN: llvm-c-test --add-named-metadata-operand < /dev/null
; This used to trigger an assertion
+2 −0
Original line number Diff line number Diff line
; RUN: llvm-c-test --set-metadata < /dev/null
; This used to trigger an assertion
+1 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ add_llvm_tool(llvm-c-test
  include-all.c
  main.c
  module.c
  metadata.c
  object.c
  targets.c
  )
+4 −0
Original line number Diff line number Diff line
@@ -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);
Loading