[opaque pointer type] Explicit pointee type for call instruction
authorDavid Blaikie <dblaikie@gmail.com>
Fri, 17 Apr 2015 06:40:14 +0000 (06:40 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Fri, 17 Apr 2015 06:40:14 +0000 (06:40 +0000)
Use an extra bit in the CCInfo to flag the newer version of the
instructiont hat includes the type explicitly.

Tested the newer error cases I added, but didn't add tests for the finer
granularity improvements to existing error paths.

llvm-svn: 235160

llvm/lib/Bitcode/Reader/BitcodeReader.cpp
llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
llvm/test/Bitcode/Inputs/invalid-call-mismatched-explicit-type.bc [new file with mode: 0644]
llvm/test/Bitcode/Inputs/invalid-call-non-function-explicit-type.bc [new file with mode: 0644]
llvm/test/Bitcode/invalid.test

index 5366f5f..e37e8f4 100644 (file)
@@ -299,9 +299,9 @@ private:
       // have.
       ResVal = getFnValueByID(ValNo, nullptr);
       return ResVal == nullptr;
-    } else if (Slot == Record.size()) {
-      return true;
     }
+    if (Slot == Record.size())
+      return true;
 
     unsigned TypeNo = (unsigned)Record[Slot++];
     ResVal = getFnValueByID(ValNo, getTypeByID(TypeNo));
@@ -4168,19 +4168,32 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
       if (Record.size() < 3)
         return Error("Invalid record");
 
-      AttributeSet PAL = getAttributes(Record[0]);
-      unsigned CCInfo = Record[1];
+      unsigned OpNum = 0;
+      AttributeSet PAL = getAttributes(Record[OpNum++]);
+      unsigned CCInfo = Record[OpNum++];
+
+      FunctionType *FTy = nullptr;
+      if (CCInfo >> 15 & 1 &&
+          !(FTy = dyn_cast<FunctionType>(getTypeByID(Record[OpNum++]))))
+        return Error("Explicit call type is not a function type");
 
-      unsigned OpNum = 2;
       Value *Callee;
       if (getValueTypePair(Record, OpNum, NextValueNo, Callee))
         return Error("Invalid record");
 
       PointerType *OpTy = dyn_cast<PointerType>(Callee->getType());
-      FunctionType *FTy = nullptr;
-      if (OpTy) FTy = dyn_cast<FunctionType>(OpTy->getElementType());
-      if (!FTy || Record.size() < FTy->getNumParams()+OpNum)
-        return Error("Invalid record");
+      if (!OpTy)
+        return Error("Callee is not a pointer type");
+      FunctionType *PFTy = dyn_cast<FunctionType>(OpTy->getElementType());
+      if (!PFTy)
+        return Error("Callee is not of pointer to function type");
+      if (!FTy)
+        FTy = PFTy;
+      if (PFTy != FTy)
+        return Error("Explicit call type does not match pointee type of "
+                     "callee operand");
+      if (Record.size() < FTy->getNumParams() + OpNum)
+        return Error("Insufficient operands to call");
 
       SmallVector<Value*, 16> Args;
       // Read the fixed params.
index aa4a6a4..bfcaac1 100644 (file)
@@ -1935,14 +1935,14 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
     break;
   case Instruction::Call: {
     const CallInst &CI = cast<CallInst>(I);
-    PointerType *PTy = cast<PointerType>(CI.getCalledValue()->getType());
-    FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
+    FunctionType *FTy = CI.getFunctionType();
 
     Code = bitc::FUNC_CODE_INST_CALL;
 
     Vals.push_back(VE.getAttributeID(CI.getAttributes()));
     Vals.push_back((CI.getCallingConv() << 1) | unsigned(CI.isTailCall()) |
-                   unsigned(CI.isMustTailCall()) << 14);
+                   unsigned(CI.isMustTailCall()) << 14 | 1 << 15);
+    Vals.push_back(VE.getTypeID(FTy));
     PushValueAndType(CI.getCalledValue(), InstID, Vals, VE);  // Callee
 
     // Emit value #'s for the fixed parameters.
diff --git a/llvm/test/Bitcode/Inputs/invalid-call-mismatched-explicit-type.bc b/llvm/test/Bitcode/Inputs/invalid-call-mismatched-explicit-type.bc
new file mode 100644 (file)
index 0000000..802d28e
Binary files /dev/null and b/llvm/test/Bitcode/Inputs/invalid-call-mismatched-explicit-type.bc differ
diff --git a/llvm/test/Bitcode/Inputs/invalid-call-non-function-explicit-type.bc b/llvm/test/Bitcode/Inputs/invalid-call-non-function-explicit-type.bc
new file mode 100644 (file)
index 0000000..d080689
Binary files /dev/null and b/llvm/test/Bitcode/Inputs/invalid-call-non-function-explicit-type.bc differ
index 9cab227..5c6e280 100644 (file)
@@ -18,6 +18,10 @@ RUN: not llvm-dis -disable-output %p/Inputs/invalid-load-mismatched-explicit-typ
 RUN:   FileCheck --check-prefix=MISMATCHED-EXPLICIT-LOAD %s
 RUN: not llvm-dis -disable-output %p/Inputs/invalid-gep-operator-mismatched-explicit-type.bc 2>&1 | \
 RUN:   FileCheck --check-prefix=MISMATCHED-EXPLICIT-GEP-OPERATOR %s
+RUN: not llvm-dis -disable-output %p/Inputs/invalid-call-mismatched-explicit-type.bc 2>&1 | \
+RUN:   FileCheck --check-prefix=MISMATCHED-EXPLICIT-CALL %s
+RUN: not llvm-dis -disable-output %p/Inputs/invalid-call-non-function-explicit-type.bc 2>&1 | \
+RUN:   FileCheck --check-prefix=NON-FUNCTION-EXPLICIT-CALL %s
 
 INVALID-ENCODING: Invalid encoding
 BAD-ABBREV: Abbreviation starts with an Array or a Blob
@@ -29,6 +33,8 @@ BAD-ALIGN: Invalid alignment value
 MISMATCHED-EXPLICIT-GEP: Explicit gep type does not match pointee type of pointer operand
 MISMATCHED-EXPLICIT-LOAD: Explicit load type does not match pointee type of pointer operand
 MISMATCHED-EXPLICIT-GEP-OPERATOR: Explicit gep operator type does not match pointee type of pointer operand
+MISMATCHED-EXPLICIT-CALL: Explicit call type does not match pointee type of callee operand
+NON-FUNCTION-EXPLICIT-CALL: Explicit call type is not a function type
 
 RUN: not llvm-dis -disable-output %p/Inputs/invalid-extractval-array-idx.bc 2>&1 | \
 RUN:   FileCheck --check-prefix=EXTRACT-ARRAY %s