public void TestUsingDeclaration() { var test = "using System.Text;"; var configuration = Configuration.Create(); configuration.Verbose = 2; var context = CompilationContext.Create(configuration).LoadSolution(test); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree(); var expected = @" using Microsoft.PSharp; using System.Text;"; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), syntaxTree.ToString().Replace("\n", string.Empty)); }
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 TestNoStatementsWithLoop() { var test = @" using Microsoft.PSharp; namespace Foo { class M : Machine { [Start] [OnEntry(nameof(FirstOnEntryAction))] class First : MachineState { } void FirstOnEntryAction() { for (int i = 0; i < 2; i++) { } } } }"; 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 TestMachineFieldDeclaration() { var test = @" namespace Foo { machine M { machine N; start state S { } } }"; var configuration = Configuration.Create(); configuration.Verbose = 2; var context = CompilationContext.Create(configuration).LoadSolution(test); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree(); var expected = @" using Microsoft.PSharp; namespace Foo { class M : Machine { MachineId N; [Microsoft.PSharp.Start] class S : MachineState { } } }"; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), syntaxTree.ToString().Replace("\n", string.Empty)); }
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 bool Parse(string expressionString, out IExpression parsedExpression) { string[] operandStrings = expressionString.SplitWord('-', _stringSplitOptions); if (operandStrings.Length <= 1) { parsedExpression = default; return(false); } parsedExpression = new Subtraction(ParsingEngine.Parse(operandStrings[1]), ParsingEngine.Parse(operandStrings[0])); return(true); }
public bool Parse(string expressionString, out IExpression parsedExpression) { string[] operandStrings = expressionString.Split('*', 2); if (operandStrings.Length <= 1) { parsedExpression = default; return(false); } parsedExpression = new Multiplication(ParsingEngine.Parse(operandStrings[0]), ParsingEngine.Parse(operandStrings[1])); return(true); }
public void TestEventRaiseStatementWithPSharpAPI() { var test = @" using Microsoft.PSharp; namespace Foo { class e1 : Event { public e1() : base() { } } class M : Machine { [Microsoft.PSharp.Start] [OnEntry(nameof(psharp_S1_on_entry_action))] [OnEventGotoState(typeof(e1), typeof(S2))] class S1 : MachineState { } class S2 : MachineState { } protected void psharp_S1_on_entry_action() { this.Raise(new e1()); } } }"; var configuration = Configuration.Create(); configuration.Verbose = 2; var context = CompilationContext.Create(configuration).LoadSolution(test, "cs"); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); var syntaxTree = context.GetProjects()[0].CSharpPrograms[0].GetSyntaxTree(); var expected = @" using Microsoft.PSharp; namespace Foo { class e1 : Event { public e1() : base() { } } class M : Machine { [Microsoft.PSharp.Start] [OnEntry(nameof(psharp_S1_on_entry_action))] [OnEventGotoState(typeof(e1), typeof(S2))] class S1 : MachineState { } class S2 : MachineState { } protected void psharp_S1_on_entry_action() { { this.Raise(new e1());return; } } } }"; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), syntaxTree.ToString().Replace(Environment.NewLine, string.Empty)); }
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 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 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 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 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 TestMachineNestedGroups() { var test = @" namespace Foo { machine M { group G1 { start state S1 { entry { jump(G3.S2); } } group G3 { state S2 { entry { jump(S1); } } state S3 { entry { jump(S2); } } } } } }"; var configuration = Configuration.Create(); configuration.Verbose = 2; var context = CompilationContext.Create(configuration).LoadSolution(test); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree(); var expected = @" using Microsoft.PSharp; namespace Foo { class M : Machine { class G1 : StateGroup { public class G3 : StateGroup { [OnEntry(nameof(psharp_G1_G3_S2_on_entry_action))] public class S2 : MachineState { } [OnEntry(nameof(psharp_G1_G3_S3_on_entry_action))] public class S3 : MachineState { } } [Microsoft.PSharp.Start] [OnEntry(nameof(psharp_G1_S1_on_entry_action))] public class S1 : MachineState { } } protected void psharp_G1_S1_on_entry_action(){ { this.Goto(typeof(G1.G3.S2));return; } } protected void psharp_G1_G3_S2_on_entry_action(){ { this.Goto(typeof(G1.S1));return; } } protected void psharp_G1_G3_S3_on_entry_action(){ { this.Goto(typeof(G1.G3.S2));return; } } } } "; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty).Replace("\n", string.Empty), syntaxTree.ToString().Replace("\n", string.Empty)); }
public void TestCreateNamedMachineStatementWithDoublePayload() { var test = @" namespace Foo { event e1 (k:int, s:string); machine M { machine Target; start state S { entry { string s = ""hello""; create(M, ""NamedMachine"", e1, 10, s); } } } }"; var configuration = Configuration.Create(); configuration.Verbose = 2; var context = CompilationContext.Create(configuration).LoadSolution(test); ParsingEngine.Create(context).Run(); RewritingEngine.Create(context).Run(); var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree(); var expected = @" using Microsoft.PSharp; namespace Foo { class e1 : Event { public int k; public string s; public e1(int k, string s) : base() { this.k = k; this.s = s; } } class M : Machine { MachineId Target; [Microsoft.PSharp.Start] [OnEntry(nameof(psharp_S_on_entry_action))] class S : MachineState { } protected void psharp_S_on_entry_action() { string s = ""hello""; this.CreateMachine(typeof(M),""NamedMachine"",new e1(10, s)); } } }"; Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), syntaxTree.ToString().Replace("\n", string.Empty)); }
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 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 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 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 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 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 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 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 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(); }
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 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 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 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(); }