1

Closed

Bitwise ops on enums given Dummy type

description

The type of a binary numeric operation with non-primitive arguments is computed incorrectly. Specifically, this occurs for bitwise operations involving enum values.
 
I believe the incorrect logic is in the method Microsoft.Cci.IlToCodeModel.TypeInferencer.GetBinaryNumericOperationType at TypeInferencer.cs:46.
 
Here is a test case which displays the bug:
 
Actual output:
 
Target type: System.Windows.Forms.Keys
Source type: Microsoft.Cci.DummyTypeReference
Source operand types: System.Windows.Forms.Keys and System.Int32
 
 
Expected output:
 
Target type: System.Windows.Forms.Keys
Source type: System.Windows.Forms.Keys
Source operand types: System.Windows.Forms.Keys and System.Int32
 
 
Example.cs:
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
 
using Microsoft.Cci;
using Microsoft.Cci.Immutable;
 
namespace Examples
{
class Example
{
    public static void Main(String[] args)
    {
        // Hardcoded path to the .exe file of this.
        string path = "Example.exe";
 
        // Load Assembly
        var host = new PeReader.DefaultHost();
        IUnit unit = host.LoadUnitFrom(path);
        if (unit is Microsoft.Cci.Dummy)
        {
            throw new Exception("Failed to load from " + path);
        }
        var assembly = Microsoft.Cci.ILToCodeModel.Decompiler
            .GetCodeModelFromMetadataModel(host, unit as IAssembly, null);
 
        // Drill down to where the bug is...
        var testMethod = assembly.AllTypes
            .First(t => t.ToString().Equals("Examples.Example"))
            .Methods.First(m => m.Name.ToString().Equals("TestMethod"));
 
        var decl = (testMethod.Body as ISourceMethodBody)
            .Block.Statements
            .First(s => s is ILocalDeclarationStatement)
                as ILocalDeclarationStatement;
        var src = decl.InitialValue as IBitwiseOr;
        var target = decl.LocalVariable;
 
        // The assignment is with var, so these two should be the same...
        Console.WriteLine("Target type: " + target.Type);
        // ... but actually the source type is Dummy.
        Console.WriteLine("Source type: " + src.Type);
        Console.WriteLine("Source operand types: " + src.LeftOperand.Type
            + " and " + src.RightOperand.Type);
    }
 
    public static System.Windows.Forms.Keys GetKey()
    {
        return System.Windows.Forms.Keys.F4;
    }
    public static void TestMethod()
    {
        var modifiedKey = GetKey()
            | System.Windows.Forms.Keys.Alt;
        var otherKey = modifiedKey;
        Console.WriteLine(modifiedKey & otherKey);
    }
}
}
Closed Mar 19, 2012 at 10:54 PM by hermanv

comments

hermanv wrote Aug 10, 2011 at 5:19 PM

Revision 64626 will hopefully take care of the problem.