Fix problem with r204836
authorEli Bendersky <eliben@google.com>
Wed, 26 Mar 2014 20:41:15 +0000 (20:41 +0000)
committerEli Bendersky <eliben@google.com>
Wed, 26 Mar 2014 20:41:15 +0000 (20:41 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204851 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/Instructions.h
unittests/IR/InstructionsTest.cpp

index e1dd3456812325a78f0343f4faecdb35eb5a11f8..06d7287ea16469987c724cdea56702cb6417dfda 100644 (file)
@@ -1297,12 +1297,14 @@ public:
 
   /// arg_operands - iteration adapter for range-for loops.
   iterator_range<op_iterator> arg_operands() {
-    return iterator_range<op_iterator>(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_iterator>(op_begin(), op_end() - 1);
   }
 
   /// arg_operands - iteration adapter for range-for loops.
   iterator_range<const_op_iterator> arg_operands() const {
-    return iterator_range<const_op_iterator>(op_begin(), op_end());
+    return iterator_range<const_op_iterator>(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<op_iterator> arg_operands() {
-    return iterator_range<op_iterator>(op_begin(), op_end());
+    return iterator_range<op_iterator>(op_begin(), op_end() - 3);
   }
 
   /// arg_operands - iteration adapter for range-for loops.
   iterator_range<const_op_iterator> arg_operands() const {
-    return iterator_range<const_op_iterator>(op_begin(), op_end());
+    return iterator_range<const_op_iterator>(op_begin(), op_end() - 3);
   }
 
   /// \brief Wrappers for getting the \c Use of a invoke argument.
index 962c07eea149f9af34113ab419e1c2ca8c37287f..94065289e2ea37332f1c512da8258e52faaec788 100644 (file)
 #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 <memory>
 
 namespace llvm {
 namespace {
@@ -47,6 +50,29 @@ TEST(InstructionsTest, ReturnInst) {
   delete r1;
 }
 
+TEST(InstructionsTest, CallInst) {
+  LLVMContext &C(getGlobalContext());
+  std::unique_ptr<Module> 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());