Check that element type correct in vector insert element.

Fixes bug where pnacl-sz was not checking if the inserted type matched
the element type of the corresponding vector. Also fixes operand look
up (within a function) to error recover rather than always die with a
fatal error.

BUG= https://code.google.com/p/nativeclient/issues/detail?id=4313
R=stichnot@chromium.org

Review URL: https://codereview.chromium.org/1357273004 .
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp
index ac9698e..449332a 100644
--- a/src/PNaClTranslator.cpp
+++ b/src/PNaClTranslator.cpp
@@ -2037,7 +2037,11 @@
     std::string Buffer;
     raw_string_ostream StrBuf(Buffer);
     StrBuf << "Value index " << Index << " not defined!";
-    Fatal(StrBuf.str());
+    Error(StrBuf.str());
+    // Recover and return some value.
+    if (!LocalOperands.empty())
+      return LocalOperands.front();
+    return Context->getGlobalConstantByID(0);
   }
 };
 
@@ -2288,6 +2292,16 @@
       appendErrorInstruction(Elt->getType());
       return;
     }
+    if (Ice::typeElementType(VecType) != Elt->getType()) {
+      std::string Buffer;
+      raw_string_ostream StrBuf(Buffer);
+      StrBuf << "Insertelement: Element type "
+             << Ice::typeString(Elt->getType()) << " doesn't match vector type "
+             << Ice::typeString(VecType);
+      Error(StrBuf.str());
+      appendErrorInstruction(Elt->getType());
+      return;
+    }
     CurrentNode->appendInst(Ice::InstInsertElement::create(
         Func.get(), getNextInstVar(VecType), Vec, Elt, Index));
     return;
diff --git a/tests_lit/parse_errs/Inputs/insertelt-wrong-type.tbc b/tests_lit/parse_errs/Inputs/insertelt-wrong-type.tbc
new file mode 100644
index 0000000..8eb6f65
--- /dev/null
+++ b/tests_lit/parse_errs/Inputs/insertelt-wrong-type.tbc
@@ -0,0 +1,33 @@
+65535,8,2;
+1,1;
+65535,17,2;
+1,6;
+7,1;
+12,16,0;
+7,8;
+2;
+21,0,3,1;
+7,32;
+65534;
+8,4,0,0,0;
+65535,19,2;
+5,0;
+65534;
+65535,14,2;
+1,0,102;
+65534;
+65535,12,2;
+1,1;
+65535,11,2;
+1,0;
+4,3;
+1,2;
+4,2;
+1,5;
+4,0;
+65534;
+2,2,2,0;
+7,5,3,2;
+10;
+65534;
+65534;
diff --git a/tests_lit/parse_errs/insertelt-wrong-type.test b/tests_lit/parse_errs/insertelt-wrong-type.test
new file mode 100644
index 0000000..326ec34
--- /dev/null
+++ b/tests_lit/parse_errs/insertelt-wrong-type.test
@@ -0,0 +1,32 @@
+; Tests that we check if the element being inserted into a vector is of the
+; right type.
+
+; REQUIRES: no_minimal_build
+
+; RUN: not %pnacl_sz -bitcode-as-text \
+; RUN:     %p/Inputs/insertelt-wrong-type.tbc \
+; RUN:     -bitcode-format=pnacl -notranslate -build-on-read 2>&1 \
+; RUN:   | FileCheck %s
+
+; CHECK: Insertelement: Element type i8 doesn't match vector type <16 x i1>
+
+; RUN: pnacl-bcfuzz -bitcode-as-text \
+; RUN:     %p/Inputs/insertelt-wrong-type.tbc -output - \
+; RUN:   | not pnacl-bcdis -no-records | FileCheck -check-prefix=ASM %s
+
+; ASM:   function void @f0(<16 x i1> %p0) {  // BlockID = 12
+; ASM:     blocks 1;
+; ASM:     constants {  // BlockID = 11
+; ASM:       i1:
+; ASM:         %c0 = i1 1;
+; ASM:       i8:
+; ASM:         %c1 = i8 1;
+; ASM:       i32:
+; ASM:         %c2 = i32 0;
+; ASM:       }
+; ASM:   %b0:
+; ASM:     %v0 = add i8 %c1, %c1;
+; ASM:     %v1  =  insertelement <16 x i1> %p0, i8 %c1, i32 %c2;
+; ASM: Error(128:0): insertelement: Illegal element type i8. Expected: i1
+; ASM:     ret void;
+; ASM:   }