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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }