diff --git a/src/Compiler/src/Compiler/XSharpCodeAnalysis/Preprocessor/XSharpPreprocessor.cs b/src/Compiler/src/Compiler/XSharpCodeAnalysis/Preprocessor/XSharpPreprocessor.cs index d9a3bd9050..a24b1c08a6 100644 --- a/src/Compiler/src/Compiler/XSharpCodeAnalysis/Preprocessor/XSharpPreprocessor.cs +++ b/src/Compiler/src/Compiler/XSharpCodeAnalysis/Preprocessor/XSharpPreprocessor.cs @@ -2620,7 +2620,15 @@ private bool doProcessTranslates(IList line, out IList var rule = _transRules.FindMatchingRule(temp, out var matchInfo); if (rule != null) { + var prevTemp = temp; temp = doReplace(temp, rule, matchInfo); + if (isResultUnchanged(prevTemp, temp)) + { + // the replacement did not change the tokens, so stop to prevent an endless loop + result.AddRange(temp); + temp.Clear(); + break; + } if (usedRules.HasRecursion(rule, temp)) { // duplicate, so exit now @@ -2686,7 +2694,13 @@ private bool doProcessCommands(IList line, out IList r // nothing to do, so exit. Leave changed the way it is. This does not have to be the first iteration break; } + var prevResult = result; result = doReplace(result, rule, matchInfo); + if (isResultUnchanged(prevResult, result)) + { + // the replacement did not change the tokens, so stop to prevent an endless loop + break; + } if (usedRules.HasRecursion(rule, result)) { // duplicate so exit now @@ -2796,5 +2810,19 @@ private List doReplace(IList line, PPRule rule, PPMatc #endif return result; } + + private static bool isResultUnchanged(IList input, IList output) + { + if (input.Count != output.Count) + return false; + for (int i = 0; i < input.Count; i++) + { + if (!string.Equals(input[i].Text, output[i].Text, StringComparison.OrdinalIgnoreCase)) + { + return false; + } + } + return true; + } } } diff --git a/src/Runtime/MacroCompiler/Preprocessor/XSharpPreprocessor.cs b/src/Runtime/MacroCompiler/Preprocessor/XSharpPreprocessor.cs index 5d5a1083dc..393928f54f 100644 --- a/src/Runtime/MacroCompiler/Preprocessor/XSharpPreprocessor.cs +++ b/src/Runtime/MacroCompiler/Preprocessor/XSharpPreprocessor.cs @@ -2540,7 +2540,15 @@ private bool doProcessTranslates(IList line, out IList var rule = _transRules.FindMatchingRule(temp, out var matchInfo); if (rule != null) { + var prevTemp = temp; temp = doReplace(temp, rule, matchInfo); + if (isResultUnchanged(prevTemp, temp)) + { + // the replacement did not change the tokens, so stop to prevent an endless loop + result.AddRange(temp); + temp.Clear(); + break; + } if (usedRules.HasRecursion(rule, temp)) { // duplicate, so exit now @@ -2606,7 +2614,13 @@ private bool doProcessCommands(IList line, out IList r // nothing to do, so exit. Leave changed the way it is. This does not have to be the first iteration break; } + var prevResult = result; result = doReplace(result, rule, matchInfo); + if (isResultUnchanged(prevResult, result)) + { + // the replacement did not change the tokens, so stop to prevent an endless loop + break; + } if (usedRules.HasRecursion(rule, result)) { // duplicate so exit now @@ -2716,5 +2730,19 @@ private List doReplace(IList line, PPRule rule, PPMatc #endif return result; } + + private static bool isResultUnchanged(IList input, IList output) + { + if (input.Count != output.Count) + return false; + for (int i = 0; i < input.Count; i++) + { + if (!string.Equals(input[i].Text, output[i].Text, StringComparison.OrdinalIgnoreCase)) + { + return false; + } + } + return true; + } } }