diff options
| author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2014-12-06 01:26:49 +0000 |
|---|---|---|
| committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2014-12-06 01:26:49 +0000 |
| commit | da41af9e9423eeb435bbf64f94649726569ae45b (patch) | |
| tree | 83c921701ee73320f6a6f0dfc313639105f22797 /llvm/lib/IR | |
| parent | 597dcc7a8deb329037175f79bd0bd406a2aa880b (diff) | |
| download | bcm5719-llvm-da41af9e9423eeb435bbf64f94649726569ae45b.tar.gz bcm5719-llvm-da41af9e9423eeb435bbf64f94649726569ae45b.zip | |
IR: Disallow complicated function-local metadata
Disallow complex types of function-local metadata. The only valid
function-local metadata is an `MDNode` whose sole argument is a
non-metadata function-local value.
Part of PR21532.
llvm-svn: 223564
Diffstat (limited to 'llvm/lib/IR')
| -rw-r--r-- | llvm/lib/IR/Metadata.cpp | 75 |
1 files changed, 27 insertions, 48 deletions
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp index 3a7c293bcdd..45d61a15a6b 100644 --- a/llvm/lib/IR/Metadata.cpp +++ b/llvm/lib/IR/Metadata.cpp @@ -185,43 +185,20 @@ static const Function *getFunctionForValue(Value *V) { return nullptr; } -#ifndef NDEBUG -static const Function *assertLocalFunction(const MDNode *N) { - if (!N->isFunctionLocal()) return nullptr; - - // FIXME: This does not handle cyclic function local metadata. - const Function *F = nullptr, *NewF = nullptr; - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { - if (Value *V = N->getOperand(i)) { - if (MDNode *MD = dyn_cast<MDNode>(V)) - NewF = assertLocalFunction(MD); - else - NewF = getFunctionForValue(V); - } - if (!F) - F = NewF; - else - assert((NewF == nullptr || F == NewF) && - "inconsistent function-local metadata"); - } - return F; -} -#endif - // getFunction - If this metadata is function-local and recursively has a // function-local operand, return the first such operand's parent function. // Otherwise, return null. getFunction() should not be used for performance- // critical code because it recursively visits all the MDNode's operands. const Function *MDNode::getFunction() const { -#ifndef NDEBUG - return assertLocalFunction(this); -#else - if (!isFunctionLocal()) return nullptr; - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (const Function *F = getFunctionForValue(getOperand(i))) - return F; - return nullptr; -#endif + if (!isFunctionLocal()) + return nullptr; + assert(getNumOperands() == 1 && + "Expected one operand for function-local metadata"); + assert(getOperand(0) && + "Expected non-null operand for function-local metadata"); + assert(!getOperand(0)->getType()->isMetadataTy() && + "Expected non-metadata as operand of function-local metadata"); + return getFunctionForValue(getOperand(0)); } /// \brief Check if the Value would require a function-local MDNode. @@ -260,6 +237,14 @@ MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Value*> Vals, break; } + if (isFunctionLocal) { + assert(Vals.size() == 1 && + "Expected exactly one operand for function-local metadata"); + assert(Vals[0] && "Expected non-null operand for function-local metadata"); + assert(!Vals[0]->getType()->isMetadataTy() && + "Expected non-metadata as operand of function-local metadata"); + } + // Coallocate space for the node and Operands together, then placement new. GenericMDNode *N = new (Vals.size()) GenericMDNode(Context, Vals, isFunctionLocal); @@ -323,6 +308,8 @@ void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) { // Handle this case by implicitly dropping the MDNode reference to null. // Likewise if the MDNode is function-local but for a different function. if (To && isFunctionLocalValue(To)) { + assert(!To->getType()->isMetadataTy() && + "Expected non-metadata as operand of function-local metadata"); if (!isFunctionLocal()) To = nullptr; else { @@ -338,6 +325,14 @@ void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) { if (From == To) return; + // If this MDValue was previously function-local but no longer is, clear + // its function-local flag. + if (isFunctionLocal() && !(To && isFunctionLocalValue(To))) { + assert(getNumOperands() == 1 && + "Expected function-local metadata to have exactly one operand"); + setValueSubclassData(getSubclassDataFromValue() & ~FunctionLocalBit); + } + // If this node is already not being uniqued (because one of the operands // already went to null), then there is nothing else to do here. if (isNotUniqued()) { @@ -377,22 +372,6 @@ void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) { N->Hash = Key.Hash; Store.insert(N); - - // If this MDValue was previously function-local but no longer is, clear - // its function-local flag. - if (isFunctionLocal() && !isFunctionLocalValue(To)) { - bool isStillFunctionLocal = false; - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { - Value *V = getOperand(i); - if (!V) continue; - if (isFunctionLocalValue(V)) { - isStillFunctionLocal = true; - break; - } - } - if (!isStillFunctionLocal) - setValueSubclassData(getSubclassDataFromValue() & ~FunctionLocalBit); - } } MDNode *MDNode::concatenate(MDNode *A, MDNode *B) { |

