From 84aa5e555ff1b51ffd4ca3acc1c04505aa3f7b96 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Wed, 26 Mar 2014 20:41:15 +0000 Subject: [PATCH] Fix problem with r204836 In CallInst, op_end() points at the callee, which we don't want to iterate over when just iterating over arguments. Now take this into account when returning a iterator_range from arg_operands. Similar reasoning for InvokeInst. Also adds a unit test to verify this actually works as expected. llvm-svn: 204851 --- llvm/include/llvm/IR/Instructions.h | 10 ++++++---- llvm/unittests/IR/InstructionsTest.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h index e1dd34568123..06d7287ea164 100644 --- a/llvm/include/llvm/IR/Instructions.h +++ b/llvm/include/llvm/IR/Instructions.h @@ -1297,12 +1297,14 @@ public: /// arg_operands - iteration adapter for range-for loops. iterator_range arg_operands() { - return iterator_range(op_begin(), op_end()); + // The last operand in the op list is the callee - it's not one of the args + // so we don't want to iterate over it. + return iterator_range(op_begin(), op_end() - 1); } /// arg_operands - iteration adapter for range-for loops. iterator_range arg_operands() const { - return iterator_range(op_begin(), op_end()); + return iterator_range(op_begin(), op_end() - 1); } /// \brief Wrappers for getting the \c Use of a call argument. @@ -2954,12 +2956,12 @@ public: /// arg_operands - iteration adapter for range-for loops. iterator_range arg_operands() { - return iterator_range(op_begin(), op_end()); + return iterator_range(op_begin(), op_end() - 3); } /// arg_operands - iteration adapter for range-for loops. iterator_range arg_operands() const { - return iterator_range(op_begin(), op_end()); + return iterator_range(op_begin(), op_end() - 3); } /// \brief Wrappers for getting the \c Use of a invoke argument. diff --git a/llvm/unittests/IR/InstructionsTest.cpp b/llvm/unittests/IR/InstructionsTest.cpp index 962c07eea149..94065289e2ea 100644 --- a/llvm/unittests/IR/InstructionsTest.cpp +++ b/llvm/unittests/IR/InstructionsTest.cpp @@ -14,11 +14,14 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/MDBuilder.h" +#include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" #include "gtest/gtest.h" +#include namespace llvm { namespace { @@ -47,6 +50,29 @@ TEST(InstructionsTest, ReturnInst) { delete r1; } +TEST(InstructionsTest, CallInst) { + LLVMContext &C(getGlobalContext()); + std::unique_ptr M(new Module("MyModule", C)); + + Type *ArgTypes[] = {Type::getInt8Ty(C), Type::getInt32Ty(C), + Type::getInt64Ty(C)}; + FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), ArgTypes, false); + Function *F = Function::Create(FTy, Function::ExternalLinkage, "", M.get()); + + Value *Args[] = {ConstantInt::get(Type::getInt8Ty(C), 20), + ConstantInt::get(Type::getInt32Ty(C), 9999), + ConstantInt::get(Type::getInt64Ty(C), 42)}; + CallInst *Call = CallInst::Create(F, Args); + + // Make sure iteration over a call's arguments works as expected. + unsigned Idx = 0; + for (Value *Arg : Call->arg_operands()) { + EXPECT_EQ(ArgTypes[Idx], Arg->getType()); + EXPECT_EQ(Call->getArgOperand(Idx)->getType(), Arg->getType()); + Idx++; + } +} + TEST(InstructionsTest, BranchInst) { LLVMContext &C(getGlobalContext());