diff --git a/TypeCobol.Analysis.Test/BasicCfgInstrs/ExtendedPerformProc3Recursive0.diag b/TypeCobol.Analysis.Test/BasicCfgInstrs/ExtendedPerformProc3Recursive0.diag index 37f27f57b..622d6201a 100644 --- a/TypeCobol.Analysis.Test/BasicCfgInstrs/ExtendedPerformProc3Recursive0.diag +++ b/TypeCobol.Analysis.Test/BasicCfgInstrs/ExtendedPerformProc3Recursive0.diag @@ -1,3 +1,2 @@ --- Diagnostics --- -Line 28[15,29] <37, Warning, General> - Warning: A recursive loop has been encountered while analyzing 'PERFORM pararec', recursive instruction is ' perform pararec2'. Line 29[15,57] <37, Warning, General> - Warning: Unreachable code detected diff --git a/TypeCobol.Analysis.Test/BasicCfgInstrs/ExtendedPerformProc4Recursive0.diag b/TypeCobol.Analysis.Test/BasicCfgInstrs/ExtendedPerformProc4Recursive0.diag index 16afa8351..309bfd115 100644 --- a/TypeCobol.Analysis.Test/BasicCfgInstrs/ExtendedPerformProc4Recursive0.diag +++ b/TypeCobol.Analysis.Test/BasicCfgInstrs/ExtendedPerformProc4Recursive0.diag @@ -1,5 +1,2 @@ --- Diagnostics --- -Line 31[15,29] <37, Warning, General> - Warning: A recursive loop has been encountered while analyzing 'PERFORM pararec', recursive instruction is ' perform pararec2'. Line 32[15,57] <37, Warning, General> - Warning: Unreachable code detected -Line 57[15,64] <37, Warning, General> - Warning: A recursive loop has been encountered while analyzing 'PERFORM pararec4', recursive instruction is ' perform pararec4 varying n from 1 by 1 until n > 5'. -Line 57[15,64] <37, Warning, General> - Warning: A recursive loop has been encountered while analyzing 'PERFORM pararec4', recursive instruction is ' perform pararec3 test after varying n from 1 by 1 until n'. diff --git a/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformIdentity.diag b/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformIdentity.diag deleted file mode 100644 index 0449f56a9..000000000 --- a/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformIdentity.diag +++ /dev/null @@ -1,2 +0,0 @@ ---- Diagnostics --- -Line 6[12,23] <37, Warning, General> - Warning: A recursive loop has been encountered while analyzing 'PERFORM main', recursive instruction is ' PERFORM main'. diff --git a/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProc1Recursive0.diag b/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProc1Recursive0.diag deleted file mode 100644 index 7a1c41c0c..000000000 --- a/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProc1Recursive0.diag +++ /dev/null @@ -1,2 +0,0 @@ ---- Diagnostics --- -Line 16[15,29] <37, Warning, General> - Warning: A recursive loop has been encountered while analyzing 'PERFORM pararec', recursive instruction is ' perform pararec'. diff --git a/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProc2Recursive0.diag b/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProc2Recursive0.diag deleted file mode 100644 index c5163b4b7..000000000 --- a/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProc2Recursive0.diag +++ /dev/null @@ -1,2 +0,0 @@ ---- Diagnostics --- -Line 27[15,29] <37, Warning, General> - Warning: A recursive loop has been encountered while analyzing 'PERFORM pararec', recursive instruction is ' perform pararec2'. diff --git a/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProc3Recursive0.diag b/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProc3Recursive0.diag deleted file mode 100644 index 18ede9f54..000000000 --- a/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProc3Recursive0.diag +++ /dev/null @@ -1,2 +0,0 @@ ---- Diagnostics --- -Line 28[15,29] <37, Warning, General> - Warning: A recursive loop has been encountered while analyzing 'PERFORM pararec', recursive instruction is ' perform pararec2'. diff --git a/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProc4Recursive0.diag b/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProc4Recursive0.diag deleted file mode 100644 index 6953076dc..000000000 --- a/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProc4Recursive0.diag +++ /dev/null @@ -1,4 +0,0 @@ ---- Diagnostics --- -Line 31[15,29] <37, Warning, General> - Warning: A recursive loop has been encountered while analyzing 'PERFORM pararec', recursive instruction is ' perform pararec2'. -Line 57[15,64] <37, Warning, General> - Warning: A recursive loop has been encountered while analyzing 'PERFORM pararec4', recursive instruction is ' perform pararec4 varying n from 1 by 1 until n > 5'. -Line 57[15,64] <37, Warning, General> - Warning: A recursive loop has been encountered while analyzing 'PERFORM pararec4', recursive instruction is ' perform pararec3 test after varying n from 1 by 1 until n'. diff --git a/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProcIterativeAfterRecursive0.diag b/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProcIterativeAfterRecursive0.diag deleted file mode 100644 index 0189177ad..000000000 --- a/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProcIterativeAfterRecursive0.diag +++ /dev/null @@ -1,2 +0,0 @@ ---- Diagnostics --- -Line 16[15,64] <37, Warning, General> - Warning: A recursive loop has been encountered while analyzing 'PERFORM pararec', recursive instruction is ' perform pararec varying n from 1 by 1 until n > 5'. diff --git a/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProcIterativeAfterRecursive1.diag b/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProcIterativeAfterRecursive1.diag deleted file mode 100644 index c0376cafa..000000000 --- a/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProcIterativeAfterRecursive1.diag +++ /dev/null @@ -1,2 +0,0 @@ ---- Diagnostics --- -Line 16[15,72] <37, Warning, General> - Warning: A recursive loop has been encountered while analyzing 'PERFORM pararec', recursive instruction is ' perform pararec test after varying n from 1 by 1 until n>5'. diff --git a/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProcIterativeAfterRecursive2.diag b/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProcIterativeAfterRecursive2.diag deleted file mode 100644 index c0376cafa..000000000 --- a/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProcIterativeAfterRecursive2.diag +++ /dev/null @@ -1,2 +0,0 @@ ---- Diagnostics --- -Line 16[15,72] <37, Warning, General> - Warning: A recursive loop has been encountered while analyzing 'PERFORM pararec', recursive instruction is ' perform pararec test after varying n from 1 by 1 until n>5'. diff --git a/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProcIterativeRecursive0.diag b/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProcIterativeRecursive0.diag deleted file mode 100644 index 0189177ad..000000000 --- a/TypeCobol.Analysis.Test/BasicCfgInstrs/PerformProcIterativeRecursive0.diag +++ /dev/null @@ -1,2 +0,0 @@ ---- Diagnostics --- -Line 16[15,64] <37, Warning, General> - Warning: A recursive loop has been encountered while analyzing 'PERFORM pararec', recursive instruction is ' perform pararec varying n from 1 by 1 until n > 5'. diff --git a/TypeCobol.Analysis.Test/BasicCfgInstrs/SG102A.diag b/TypeCobol.Analysis.Test/BasicCfgInstrs/SG102A.diag index aa0cf7dc4..06af16610 100644 --- a/TypeCobol.Analysis.Test/BasicCfgInstrs/SG102A.diag +++ b/TypeCobol.Analysis.Test/BasicCfgInstrs/SG102A.diag @@ -15,10 +15,6 @@ Line 242[13,46] <37, Warning, General> - Warning: "end-if" is missing Line 250[12,37] <37, Warning, General> - Warning: "end-if" is missing Line 266[12,43] <37, Warning, General> - Warning: "end-if" is missing Line 267[12,42] <37, Warning, General> - Warning: "end-if" is missing -Line 269[41,66] <37, Warning, General> - Warning: A recursive loop has been encountered while analyzing 'PERFORM WRITE-LINE', recursive instruction is ' PERFORM WRT-LN'. -Line 269[41,66] <37, Warning, General> - Warning: A recursive loop has been encountered while analyzing 'PERFORM WRITE-LINE', recursive instruction is ' PERFORM WRT-LN 2 TIMES'. -Line 269[41,66] <37, Warning, General> - Warning: A recursive loop has been encountered while analyzing 'PERFORM WRITE-LINE', recursive instruction is ' PERFORM WRT-LN'. -Line 269[41,66] <37, Warning, General> - Warning: A recursive loop has been encountered while analyzing 'PERFORM WRITE-LINE', recursive instruction is ' PERFORM WRT-LN'. Line 276[12,43] <37, Warning, General> - Warning: "end-if" is missing Line 277[12,38] <37, Warning, General> - Warning: "end-if" is missing Line 293[12,16] <37, Warning, General> - Warning: ALTER should not be used diff --git a/TypeCobol.Analysis/Cfg/ControlFlowGraphBuilder.BasicBlockForNodeGroup.cs b/TypeCobol.Analysis/Cfg/ControlFlowGraphBuilder.BasicBlockForNodeGroup.cs index 33d588ffc..f3445407e 100644 --- a/TypeCobol.Analysis/Cfg/ControlFlowGraphBuilder.BasicBlockForNodeGroup.cs +++ b/TypeCobol.Analysis/Cfg/ControlFlowGraphBuilder.BasicBlockForNodeGroup.cs @@ -63,17 +63,6 @@ internal bool IsAfterIterativeGroup set; } - /// - /// To detect recursivity on PERFORM Procedure calls. - /// This is a bit array of GroupIndex encountered during the workflow - /// call of other PERFORM. - /// - internal BitArray RecursivityGroupSet - { - get; - set; - } - /// /// Constructor. /// diff --git a/TypeCobol.Analysis/Cfg/ControlFlowGraphBuilder.cs b/TypeCobol.Analysis/Cfg/ControlFlowGraphBuilder.cs index ffbbb741c..c9932a22e 100644 --- a/TypeCobol.Analysis/Cfg/ControlFlowGraphBuilder.cs +++ b/TypeCobol.Analysis/Cfg/ControlFlowGraphBuilder.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Linq; using TypeCobol.Analysis.Graph; @@ -1070,16 +1069,6 @@ void StoreSentences() { isPerform = true; //To avoid a second dynamic cast - //Is there a recursion in the graph ? - if (group.RecursivityGroupSet.Get(group0.GroupIndex) && !group0.HasFlag(BasicBlock.Flags.Recursive)) - { - //Flag group and store recursive perform - group0.SetFlag(BasicBlock.Flags.Recursive, true); - Node offendingInstruction = group0.Instructions.Last.Value; - System.Diagnostics.Debug.Assert(offendingInstruction != null); - this.Cfg.AddRecursivePerform(p, offendingInstruction); - } - var clonedGroup0 = clonedPerforms .Select(t => t.Item3) .SingleOrDefault(g => g.GroupIndex == group0.GroupIndex); @@ -1115,9 +1104,6 @@ void StoreSentences() clonedGroup.Group = new LinkedList>(); clonedGroup.TerminalBlocks = null; - group.RecursivityGroupSet.Set(clonedGroup.GroupIndex, true); - clonedGroup.RecursivityGroupSet = new BitArray(group.RecursivityGroupSet); - var originalPerform = this.CurrentProgramCfgBuilder.PendingPERFORMProcedures .Single(t => t.Item3 == block); clonedPerforms.Add(new Tuple(originalPerform.Item1, originalPerform.Item2, clonedGroup)); @@ -1192,8 +1178,6 @@ private void ResolvePendingPERFORMProcedures() //First pass: resolve targets of PERFORMs, some new groups may be created during this foreach (var item in this.CurrentProgramCfgBuilder.PendingPERFORMProcedures) { - item.Item3.RecursivityGroupSet = new BitArray(GroupCounter + 1); - item.Item3.RecursivityGroupSet.Set(item.Item3.GroupIndex, true); ResolvePendingPERFORMProcedure(item, clonedPerforms); } @@ -1211,13 +1195,11 @@ private void ResolvePendingPERFORMProcedures() { BasicBlockForNodeGroup group = item.Item3; groupOrder[group.GroupIndex] = group; - group.RecursivityGroupSet = null; } foreach (var item in clonedPerforms) { BasicBlockForNodeGroup group = item.Item3; groupOrder[group.GroupIndex] = group; - group.RecursivityGroupSet = null; } //Extend groups according to the current building mode @@ -1439,28 +1421,6 @@ private void CreateOptionalDiagnostics() AddDiagnostic(d); } } - - //RecursiveBlockOnPerformProcedure - if (_compilerOptions.CheckRecursivePerforms.IsActive && this.CurrentProgramCfgBuilder.Cfg.RecursivePerforms != null) - { - foreach (var recursivePerform in this.CurrentProgramCfgBuilder.Cfg.RecursivePerforms) - { - var perform = recursivePerform.Key; - SymbolReference procedureReference = perform.CodeElement.Procedure; - SymbolReference throughProcedureReference = perform.CodeElement.ThroughProcedure; - foreach (var offendingInstruction in recursivePerform.Value) - { - string performTarget = throughProcedureReference != null - ? $"{procedureReference} THRU {throughProcedureReference}" - : procedureReference.ToString(); - System.Diagnostics.Debug.Assert(offendingInstruction.CodeElement != null); - string offendingStatement = offendingInstruction.CodeElement.SourceText; - Diagnostic d = new Diagnostic(_compilerOptions.CheckRecursivePerforms.GetMessageCode(), perform.CodeElement.Position(), - string.Format(Resource.RecursiveBlockOnPerformProcedure, performTarget, offendingStatement)); - AddDiagnostic(d); - } - } - } } /// diff --git a/TypeCobol.Analysis/Graph/BasicBlock.cs b/TypeCobol.Analysis/Graph/BasicBlock.cs index aa83fa2ca..e5e924a06 100644 --- a/TypeCobol.Analysis/Graph/BasicBlock.cs +++ b/TypeCobol.Analysis/Graph/BasicBlock.cs @@ -81,8 +81,7 @@ public enum Flags : uint Declaratives = 0x01 << 2, //Flag if this basic block is inside a declaratives section. Start = 0x01 << 3, //Flag for a start node. End = 0x01 << 4, //Flag for a end node. - GroupGrafted = 0x01 << 5, //Flag a Grafted Group. - Recursive = 0x01 << 6 //Flag a recursive block + GroupGrafted = 0x01 << 5 //Flag a Grafted Group. } /// diff --git a/TypeCobol.Analysis/Graph/ControlFlowGraph.cs b/TypeCobol.Analysis/Graph/ControlFlowGraph.cs index e3c7f3dd7..d8b70bf9a 100644 --- a/TypeCobol.Analysis/Graph/ControlFlowGraph.cs +++ b/TypeCobol.Analysis/Graph/ControlFlowGraph.cs @@ -134,12 +134,6 @@ public BasicBlock RootBlock /// public Dictionary> WrongOrderPerformThrus { get; private set; } - /// - /// All recursive PERFORMs found in the program. Null if no such perform found. - /// Key is the recursive PERFORM statement, value is the list of all detected instructions that lead to recursion. - /// - public Dictionary> RecursivePerforms { get; private set; } - /// /// All unreachable blocks of this graph. The property may be null but not empty. /// @@ -243,28 +237,6 @@ internal void AddWrongOrderPerformThru(PerformProcedure performThru, N procedure WrongOrderPerformThrus.Add(performThru, new Tuple(procedure, throughProcedure)); } - /// - /// Register a recursive jump for a perform statement. - /// - /// Perform node - /// Recursive jump node - internal void AddRecursivePerform(PerformProcedure perform, N recursiveJump) - { - if (RecursivePerforms == null) - { - RecursivePerforms = new Dictionary>(); - } - - if (RecursivePerforms.TryGetValue(perform, out var nodes)) - { - nodes.Add(recursiveJump); - } - else - { - RecursivePerforms.Add(perform, new List() { recursiveJump }); - } - } - /// /// Register one unreachable block of this graph /// diff --git a/TypeCobol.Analysis/Resource.Designer.cs b/TypeCobol.Analysis/Resource.Designer.cs index 885a89a33..8b6faacb4 100644 --- a/TypeCobol.Analysis/Resource.Designer.cs +++ b/TypeCobol.Analysis/Resource.Designer.cs @@ -19,7 +19,7 @@ namespace TypeCobol.Analysis { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resource { @@ -86,14 +86,5 @@ internal static string BasicBlockGroupGoesBeyondTheLimit { return ResourceManager.GetString("BasicBlockGroupGoesBeyondTheLimit", resourceCulture); } } - - /// - /// Looks up a localized string similar to A recursive loop has been encountered while analyzing 'PERFORM {0}', recursive instruction is '{1}'.. - /// - internal static string RecursiveBlockOnPerformProcedure { - get { - return ResourceManager.GetString("RecursiveBlockOnPerformProcedure", resourceCulture); - } - } } } diff --git a/TypeCobol.Analysis/Resource.resx b/TypeCobol.Analysis/Resource.resx index 1cdc2c18a..b6baac30b 100644 --- a/TypeCobol.Analysis/Resource.resx +++ b/TypeCobol.Analysis/Resource.resx @@ -126,7 +126,4 @@ Statement '{0}' located at line {1}, column {2} prevents this PERFORM statement to reach its exit. - - A recursive loop has been encountered while analyzing 'PERFORM {0}', recursive instruction is '{1}'. - \ No newline at end of file diff --git a/TypeCobol/Compiler/Directives/TypeCobolOptions.cs b/TypeCobol/Compiler/Directives/TypeCobolOptions.cs index 2a61726cd..0f5da272a 100644 --- a/TypeCobol/Compiler/Directives/TypeCobolOptions.cs +++ b/TypeCobol/Compiler/Directives/TypeCobolOptions.cs @@ -81,11 +81,6 @@ public bool UseEuroInformationLegacyReplacingSyntax /// public TypeCobolCheckOption CheckPerformThruOrder { get; set; } - /// - /// Check that perform statement are not recursive, requires CFG. - /// - public TypeCobolCheckOption CheckRecursivePerforms { get; set; } - public TypeCobolOptions(TypeCobolConfiguration config) { HaltOnMissingCopy = config.HaltOnMissingCopyFilePath != null; @@ -104,7 +99,6 @@ public TypeCobolOptions(TypeCobolConfiguration config) CheckEndProgram = config.CheckEndProgram; CheckPerformPrematureExits = config.CheckPerformPrematureExits; CheckPerformThruOrder = config.CheckPerformThruOrder; - CheckRecursivePerforms = config.CheckRecursivePerforms; } public TypeCobolOptions() diff --git a/TypeCobol/Tools/Options-Config/TypeCobolConfiguration.cs b/TypeCobol/Tools/Options-Config/TypeCobolConfiguration.cs index 4ed96ab1c..e38c045e0 100644 --- a/TypeCobol/Tools/Options-Config/TypeCobolConfiguration.cs +++ b/TypeCobol/Tools/Options-Config/TypeCobolConfiguration.cs @@ -48,7 +48,6 @@ public class TypeCobolConfiguration : ITypeCobolCheckOptions public TypeCobolCheckOption CheckEndProgram { get; set; } public TypeCobolCheckOption CheckPerformPrematureExits { get; set; } public TypeCobolCheckOption CheckPerformThruOrder { get; set; } - public TypeCobolCheckOption CheckRecursivePerforms { get; set; } public List Copies = new List(); public List Dependencies = new List(); @@ -246,7 +245,6 @@ public interface ITypeCobolCheckOptions TypeCobolCheckOption CheckEndProgram { get; set; } TypeCobolCheckOption CheckPerformPrematureExits { get; set; } TypeCobolCheckOption CheckPerformThruOrder { get; set; } - TypeCobolCheckOption CheckRecursivePerforms { get; set; } } public static class TypeCobolCheckOptionsInitializer @@ -257,7 +255,6 @@ public static void SetDefaultValues(ITypeCobolCheckOptions checkOptions) checkOptions.CheckEndProgram = new TypeCobolCheckOption(Severity.Error); checkOptions.CheckPerformPrematureExits = new TypeCobolCheckOption(Severity.Warning); checkOptions.CheckPerformThruOrder = new TypeCobolCheckOption(Severity.Warning); - checkOptions.CheckRecursivePerforms = new TypeCobolCheckOption(Severity.Warning); } } @@ -293,7 +290,6 @@ public static OptionSet GetCommonTypeCobolOptions(TypeCobolConfiguration typeCob { "diag.cep|diagnostic.checkEndProgram=", "Indicate level of check end program: warning, error, info, ignore.", v => typeCobolConfig.CheckEndProgram = TypeCobolCheckOption.Parse(v) }, { "diag.cppe|diagnostic.checkPerformPrematureExits=", "Indicate level of check perform premature exits: warning, error, info, ignore.", v => typeCobolConfig.CheckPerformPrematureExits = TypeCobolCheckOption.Parse(v) }, { "diag.cpto|diagnostic.checkPerformThruOrder=", "Indicate level of check perform thru procedure order: warning, error, info, ignore.", v => typeCobolConfig.CheckPerformThruOrder = TypeCobolCheckOption.Parse(v) }, - { "diag.crp|diagnostic.checkRecursivePerforms=", "Indicate level of check recursive performs: warning, error, info, ignore.", v => typeCobolConfig.CheckRecursivePerforms = TypeCobolCheckOption.Parse(v) }, { "log|logfilepath=", "{PATH} to TypeCobol.CLI.log log file", v => typeCobolConfig.LogFile = Path.Combine(v, TypeCobolConfiguration.DefaultLogFileName)}, { "cfg|cfgbuild=", "CFG build option, recognized values are: None/0, Standard/1, Extended/2, WithDfa/3.", v => typeCobolConfig.RawCfgBuildingMode = v }, { "cob|cobol", "Indicate that it's a pure Cobol85 input file.", v => typeCobolConfig.IsCobolLanguage = true },