コード例 #1
0
        public void TestAccessAfterSendInCallee()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public int Value;
 
 public eUnit(int value)
  : base()
 {
  this.Value = value;
 }
}

class M : Machine
{
 MachineId Target;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  int value = 0;
  this.Target = this.CreateMachine(typeof(M));
  this.Foo(value);
 }

 void Foo(int value)
 {
  this.Send(this.Target, new eUnit(value));
  value = 1;
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "No static analysis errors detected.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
コード例 #2
0
        public void TestPublicFieldVisibility()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class M : Machine
{
 public int Num;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  this.Num = 1;
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            ErrorReporter.ShowWarnings = true;
            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '0' errors and '1' warning.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            Console.WriteLine(IO.GetOutput());

            var error = "Warning: Field 'int Num' of machine 'Foo.M' is declared as " +
                        "'public'.   at 'public int Num;' in Program.cs:line 7";

            Assert.AreEqual(error.Replace(Environment.NewLine, string.Empty),
                            IO.GetOutput().Replace(Environment.NewLine, string.Empty));

            IO.StopWritingToMemory();
        }
コード例 #3
0
        public void TestBasicLoop()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class M : Machine
{
 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  int k = 10;
  for (int i = 0; i < k; i++) { k = 2; }
  k = 3;
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "No static analysis errors detected.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
コード例 #4
0
        public void TestMemberVisibility()
        {
            var test = @"
namespace Foo {
class M : Machine
{
 int Num;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  this.Num = 1;
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "No static analysis errors detected.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
コード例 #5
0
        public void TestComplexAccessesInCall10Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

class OtherClass
{
 internal Letter Letter;

 public void Foo(Letter letter)
 {
  this.Letter = letter;
 }
}

class M : Machine
{
 MachineId Target;
 Letter Letter;
 OtherClass OC;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  this.Target = this.CreateMachine(typeof(M));
  Letter letter = new Letter(""London"");
  var oc = new OtherClass();
  oc.Foo(letter);
  this.OC = oc;
  this.Send(this.Target, new eUnit(letter)); // ERROR
 }
}
}";

            var configuration = base.GetConfiguration();

            configuration.DoStateTransitionAnalysis = false;

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '1' error.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            var error = "Error: Method 'FirstOnEntryAction' of machine 'Foo.M' sends " +
                        "'letter', which contains data from field 'letter'.";
            var actual = IO.GetOutput();

            Assert.AreEqual(error.Replace(Environment.NewLine, string.Empty),
                            actual.Substring(0, actual.IndexOf(Environment.NewLine)));

            IO.StopWritingToMemory();
        }
コード例 #6
0
        public void TestComplexAccessesInCall1Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Envelope Envelope;
 
 public eUnit(Envelope envelope)
  : base()
 {
  this.Envelope = envelope;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

struct Envelope
{
 public Letter Letter;
 public string Address;
 public int Id;

 public Envelope(string address, int id)
 {
  this.Letter = new Letter("""");
  this.Address = address;
  this.Id = id;
 }
}

class M : Machine
{
 MachineId Target;
 Letter Letter;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  this.Target = this.CreateMachine(typeof(M));
  Envelope envelope = new Envelope(""London"", 0);
  Envelope otherEnvelope = envelope;

  this.Foo(otherEnvelope);

  this.Send(this.Target, new eUnit(envelope));

  this.Bar(otherEnvelope.Letter);
  otherEnvelope.Letter.Text = ""text"";  // ERROR

  envelope = new Envelope();
  this.FooBar(envelope, otherEnvelope.Letter);
 }

 void Foo(Envelope envelope)
 {
  this.Letter = envelope.Letter;  // ERROR
 }

 void Bar(Letter letter)
 {
  letter.Text = ""text2"";  // ERROR
 }

 void FooBar(Envelope envelope, Letter letter)
 {
  string str = letter.Text;  // ERROR
  envelope.Id = 5;
 }
}
}";

            var configuration = base.GetConfiguration();

            configuration.DoStateTransitionAnalysis = false;

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '4' errors.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
コード例 #7
0
        public void TestFieldSendAlias()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;
 public int Num;

 public Letter(string text, int num)
 {
  this.Text = text;
  this.Num = num;
 }
}

class M : Machine
{
 MachineId Target;
 Letter Letter;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  var letter = new Letter(""test"", 0);
  this.Target = this.CreateMachine(typeof(M));
  var otherLetter = letter;
  letter = this.Foo(letter);
  this.Send(this.Target, new eUnit(otherLetter));
 }

 Letter Foo(Letter letter)
 {
   return this.Bar(letter);
 }

 Letter Bar(Letter letter)
 {
  Letter otherLetter = new Letter(""test"", 0);
  otherLetter = this.Letter;
  return otherLetter;
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "No static analysis errors detected.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
コード例 #8
0
        public void TestSwitchStatement()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

class M : Machine
{
 MachineId Target;
 int Num;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  this.Target = this.CreateMachine(typeof(M));
  var letter = new Letter(""London"");

  this.Send(this.Target, new eUnit(letter));

  switch (this.Num)
  {
   case 0:
   case 1:
    letter = new Letter(""Taipei"");
    break;

   case 2:
    letter = new Letter(""Redmond"");
    break;

   default:
    letter = new Letter(""Bangalore"");
    break;
  }

  letter.Text = ""text"";
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "No static analysis errors detected.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
コード例 #9
0
ファイル: ResetAfterSendTests.cs プロジェクト: rekoder/PSharp
        public void TestResetGivenUpReferenceAfterSend1()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

class M : Machine
{
 MachineId Target;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  this.Target = this.CreateMachine(typeof(M));
  var letter = new Letter(""London"");
  this.Send(this.Target, new eUnit(letter));
  letter = new Letter(""Bangalore"");
  var text = letter.Text;
 }
}
}";

            var configuration = base.GetConfiguration();

            configuration.ProjectName             = "Test";
            configuration.ThrowInternalExceptions = true;
            configuration.Verbose          = 2;
            configuration.AnalyzeDataRaces = true;

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "No static analysis errors detected.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
コード例 #10
0
        public void TestWriteAccessAfterSendInCallee3Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;
 public int Num;

 public Letter(string text, int num)
 {
  this.Text = text;
  this.Num = num;
 }
}

class M : Machine
{
 MachineId Target;
 Letter Letter;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  var letter = new Letter(""test"", 0);
  this.Target = this.CreateMachine(typeof(M));
  this.Send(this.Target, new eUnit(letter));
  this.Foo(letter);
 }

 void Foo(Letter letter)
 {
  this.Letter = letter;                // ERROR
  letter = new Letter(""test2"", 2);
  this.Letter.Num = 1;                 // ERROR
  int num = this.Letter.Num;           // ERROR
  letter.Text = ""Bangalore"";
  this.Letter.Text = ""Taipei"";       // ERROR
 }
}
}";

            var configuration = base.GetConfiguration();

            configuration.DoStateTransitionAnalysis = false;

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '7' errors.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
コード例 #11
0
        public void TestAccessInVirtualMethod()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

internal class Envelope
{
 internal Letter Letter;

 internal virtual void Foo(Letter letter) { }
}

internal class SuperEnvelope : Envelope
{
 internal override void Foo(Letter letter)
 {
  letter.Text = ""Bangalore"";
 }
}

class M : Machine
{
 MachineId Target;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  var letter = new Letter(""London"");
  this.Target = this.CreateMachine(typeof(M));

  Envelope envelope = new Envelope();

  this.Send(this.Target, new eUnit(letter));

  envelope.Foo(letter);
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "No static analysis errors detected.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
コード例 #12
0
        public void TestWriteAccessAfterSendInLoop9Fail()
        {
            var test = @"
using System.Collection.Generic;
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

class M : Machine
{
 MachineId Target;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  var letter = new Letter(""London"");
  this.Target = this.CreateMachine(typeof(M));

  List<int> dummies = new List<int>();
  foreach (var dummy in dummies)
  {
    letter.Text = ""Bangalore""; // ERROR
    this.Send(this.Target, new eUnit(letter)); // ERROR
  }
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '2' errors and '1' warning.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
コード例 #13
0
        public void TestFieldGivenUpOwnership1Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

class M : Machine
{
 MachineId Target;
 Letter Letter;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  var letter = new Letter(""test"");
  this.Target = this.CreateMachine(typeof(M));
  this.Send(this.Target, new eUnit(letter));
  this.Letter = letter;
 }
}
}";

            var configuration = base.GetConfiguration();

            configuration.DoStateTransitionAnalysis = false;

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '1' error.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            var error = "Error: Method 'FirstOnEntryAction' of machine 'Foo.M' assigns " +
                        "'letter' to field 'Foo.M.Letter' after giving up its ownership.";
            var actual = IO.GetOutput();

            Assert.AreEqual(error.Replace(Environment.NewLine, string.Empty),
                            actual.Substring(0, actual.IndexOf(Environment.NewLine)));

            IO.StopWritingToMemory();
        }
コード例 #14
0
        public void TestFieldAccessAfterGivenUpOwnership2Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public MachineId Target;
 public Letter Letter;
 
 public eUnit(MachineId target, Letter letter)
  : base()
 {
  this.Target = target;
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;
 public int Num;

 public Letter(string text, int num)
 {
  this.Text = text;
  this.Num = num;
 }
}

class M : Machine
{
 MachineId Target;
 Letter Letter;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  this.Target = this.CreateMachine(typeof(M));
  this.Send(this.Target, new eUnit(this.Id, this.Letter));
  int num = this.Letter.Num;
  this.Letter.Text = ""London"";
 }
}
}";

            var configuration = base.GetConfiguration();

            configuration.DoStateTransitionAnalysis = false;

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '3' errors.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
コード例 #15
0
        public void TestAccessInVirtualMethod9Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

internal class Envelope
{
 internal Letter Letter;

 internal virtual void Foo(Letter letter) { }
}

internal class SuperEnvelope : Envelope
{
 internal override void Foo(Letter letter)
 {
  Letter = letter; // ERROR
  base.Letter.Text = ""Bangalore""; // ERROR
 }
}

class M : Machine
{
 MachineId Target;
 bool Check;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  this.Target = this.CreateMachine(typeof(M));
  var letter = new Letter(""London"");
  Envelope envelope = this.Foo();

  this.Send(this.Target, new eUnit(letter));

  this.Bar(envelope, letter);
 }

 Envelope Foo()
 {
  Envelope someEnvelope = new SuperEnvelope();
  Envelope anotherEnvelope;
  anotherEnvelope = new Envelope();
  anotherEnvelope = someEnvelope;

  if (this.Check)
  {
   return new Envelope();
  }
  else
  {
   return anotherEnvelope;
  }
 }

 void Bar(Envelope envelope, Letter letter)
 {
  this.FooBar(envelope, letter);
 }

 void FooBar(Envelope envelope, Letter letter)
 {
  envelope.Foo(letter);
 }
}
}";

            var configuration = base.GetConfiguration();

            configuration.DoStateTransitionAnalysis = false;

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '3' errors.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
コード例 #16
0
        public void TestAccessInVirtualMethod7Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

internal class Envelope
{
 internal Letter Letter;

 internal virtual void Foo(Letter letter) { }

 internal virtual void Bar(Letter letter) { }
}

internal class SuperEnvelope : Envelope
{
 internal override void Foo(Letter letter)
 {
  letter.Text = ""Bangalore"";
 }

 internal override void Bar(Letter letter)
 {
  base.Letter.Text = ""Bangalore"";
 }
}

class M : Machine
{
 MachineId Target;
 bool Check;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  var letter = new Letter(""London"");
  this.Target = this.CreateMachine(typeof(M));

  Envelope envelope = this.Foo();

  this.Send(this.Target, new eUnit(letter));

  envelope.Foo(letter); // ERROR
 }

 Envelope Foo()
 {
  Envelope envelope = new SuperEnvelope();
  Envelope anotherEnvelope = new Envelope();
  anotherEnvelope = envelope;

  if (this.Check)
  {
   return new Envelope();
  }
  else
  {
   return anotherEnvelope;
  }
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '1' error.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            var error = "Error: Method 'FirstOnEntryAction' of machine 'Foo.M' accesses " +
                        "'letter' after giving up its ownership.";
            var actual = IO.GetOutput();

            Assert.AreEqual(error.Replace(Environment.NewLine, string.Empty),
                            actual.Substring(0, actual.IndexOf(Environment.NewLine)));

            IO.StopWritingToMemory();
        }
コード例 #17
0
        public void TestComplexAccessesInCall11Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

class OtherClass
{
 AnotherClass AC;

 public void Foo(Letter letter)
 {
  var ac = new AnotherClass(letter);
  this.AC = ac;
  this.AC.Bar();
 }
}

class AnotherClass
{
 internal Letter Letter;

 public AnotherClass(Letter letter)
 {
  this.Letter = letter;
 }

 public void Bar()
 {
  this.Letter.Text = ""Test""; // ERROR
 }
}

class M : Machine
{
 MachineId Target;
 Letter Letter;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  this.Target = this.CreateMachine(typeof(M));
  Letter letter = new Letter(""London"");
  var oc = new OtherClass();
  this.Send(this.Target, new eUnit(letter));
  oc.Foo(letter);
 }
}
}";

            var configuration = base.GetConfiguration();

            configuration.DoStateTransitionAnalysis = false;

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '2' errors.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
コード例 #18
0
ファイル: AccessInLoopTests.cs プロジェクト: rekoder/PSharp
        public void TestWriteAccessAfterSendInLoop2()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

class M : Machine
{
 MachineId Target;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  var letter = new Letter(""London"");
  this.Target = this.CreateMachine(typeof(M));

  int k = 10;
  for (int i = 0; i < k; i++)
  {
    continue;
    letter.Text = ""Bangalore"";
    this.Send(this.Target, new eUnit(letter));
  }
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "No static analysis errors detected.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
コード例 #19
0
        public void TestFieldSendAlias6Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;
 public int Num;

 public Letter(string text, int num)
 {
  this.Text = text;
  this.Num = num;
 }
}

class M : Machine
{
 MachineId Target;
 Object Obj;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  this.Target = this.CreateMachine(typeof(M));
  this.Obj = (this.ReceivedEvent as eUnit).Letter;
  this.Send(this.Target, new eUnit((this.ReceivedEvent as eUnit).Letter));
 }
}
}";

            var configuration = base.GetConfiguration();

            configuration.DoStateTransitionAnalysis = false;

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '1' error.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            var error = "Error: Method 'FirstOnEntryAction' of machine 'Foo.M' sends " +
                        "'ReceivedEvent', which contains data from field 'Foo.M.Obj'.";
            var actual = IO.GetOutput();

            Assert.AreEqual(error.Replace(Environment.NewLine, string.Empty),
                            actual.Substring(0, actual.IndexOf(Environment.NewLine)));

            IO.StopWritingToMemory();
        }
コード例 #20
0
        public void TestWriteAccessAfterSendInLoop1Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

class M : Machine
{
 MachineId Target;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  var letter = new Letter(""London"");
  this.Target = this.CreateMachine(typeof(M));

  int k = 10;
  for (int i = 0; i < k; i++)
  {
    this.Send(this.Target, new eUnit(letter)); // ERROR
  }
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '1' error.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            var error = "Error: Method 'FirstOnEntryAction' of machine 'Foo.M' sends " +
                        "'letter', the ownership of which has already been given up.";
            var actual = IO.GetOutput();

            Assert.AreEqual(error.Replace(Environment.NewLine, string.Empty),
                            actual.Substring(0, actual.IndexOf(Environment.NewLine)));

            IO.StopWritingToMemory();
        }
コード例 #21
0
        public void TestReturnAliasAccess8Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Envelope Envelope;
 
 public eUnit(Envelope envelope)
  : base()
 {
  this.Envelope = envelope;
 }
}

struct Envelope
{
 public Letter Letter;

 public Envelope(Letter letter)
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;
 public int Num;

 public Letter(string text, int num)
 {
  this.Text = text;
  this.Num = num;
 }
}

class M : Machine
{
 MachineId Target;
 Letter Letter;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  this.Target = this.CreateMachine(typeof(M));
  this.Foo();
 }

 void Foo()
 {
   var letter = new Letter(""test"", 0);
   var envelope = new Envelope(letter);
   envelope.Letter = this.Bar();
   this.Send(this.Target, new eUnit(envelope));
 }

 Letter Bar()
 {
  return this.Letter;
 }
}
}";

            var configuration = base.GetConfiguration();

            configuration.DoStateTransitionAnalysis = false;

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '1' error.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            var error = "Error: Method 'Foo' of machine 'Foo.M' sends 'envelope', " +
                        "which contains data from field 'Foo.M.Letter'.";
            var actual = IO.GetOutput();

            Assert.AreEqual(error.Replace(Environment.NewLine, string.Empty),
                            actual.Substring(0, actual.IndexOf(Environment.NewLine)));

            IO.StopWritingToMemory();
        }
コード例 #22
0
        public void TestIfStatement8Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

class eReq : Event
{
 public int Value;
 
 public eReq(int value)
  : base()
 {
  this.Value = value;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

class M : Machine
{
 MachineId Target;
 Letter Letter;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  int num = (this.ReceivedEvent as eReq).Value;

  this.Target = this.CreateMachine(typeof(M));
  Letter letter = new Letter(""London"");
  Letter otherLetter = new Letter(""Bangalore"");

  this.Letter = letter;

  if (num == 0)
  {
   otherLetter = new Letter(""Redmond"");
  }
  else
  {
   otherLetter = letter;
  }

  this.Send(this.Target, new eUnit(otherLetter));

  this.Letter.Text = ""text"";
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '2' errors.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
コード例 #23
0
        public void TestWriteAccessAfterSendInCallee5Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;
 public int Num;

 public Letter(string text, int num)
 {
  this.Text = text;
  this.Num = num;
 }

 public int Get() { return 0; }
}

class M : Machine
{
 MachineId Target;
 Letter Letter;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  var letter = new Letter(""test"", 0);
  this.Target = this.CreateMachine(typeof(M));
  this.Send(this.Target, new eUnit(letter));
  this.Foo(letter);
 }

 void Foo(Letter letter)
 {
  var k = letter.Get(); // ERROR
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '1' error.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            var error = "Error: Method 'FirstOnEntryAction' of machine 'Foo.M' " +
                        "accesses 'letter' after giving up its ownership.";
            var actual = IO.GetOutput();

            Assert.AreEqual(error.Replace(Environment.NewLine, string.Empty),
                            actual.Substring(0, actual.IndexOf(Environment.NewLine)));

            IO.StopWritingToMemory();
        }
コード例 #24
0
        public void TestExternalLibraryCallFail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

class M : Machine
{
 MachineId Target;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  this.Target = this.CreateMachine(typeof(M));
  Letter letter = new Letter(""London"");
  this.Send(this.Target, new eUnit(letter));
  System.Console.WriteLine(letter.Text);
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();
            ErrorReporter.ShowWarnings = true;

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '0' errors and '1' warning.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            var error = "Warning: Method 'FirstOnEntryAction' of machine 'Foo.M' calls a " +
                        "method with unavailable source code, which might be a source of errors.";
            var actual = IO.GetOutput();

            Assert.AreEqual(error.Replace(Environment.NewLine, string.Empty),
                            actual.Substring(0, actual.IndexOf(Environment.NewLine)));

            ErrorReporter.ShowWarnings = false;
            IO.StopWritingToMemory();
        }