MSIL (or CIL) uses a stack based model. To make sure that Type-safe code to be secure, it can only access the meory locations it is authorized to acess.
We verify the type on the stack. If the data type on the stack does not match the expection of an opcode, we will treat it as unverifiable code. Take below code as an example
.method public static void foo() cil managed
L_0000: ldc.r4 0
L_0005: ldc.i4 0
The opcode "add" expects the two numbers on the stack of the same type. Since they are not (r4 and i4 are pushed on the stack), at runtime JIT will throw exception, unless SkipVerification is specified.
The PEVerify output looks like this
[IL]: Error: [xxx.dll : Test::foo][mdToken=0x6000001][offset 0x0000000A][found Double][expected Int32] Unexpected type on the stack.(Error: 0x80131854)