|
1 | 1 | module dscanner.analysis.base; |
2 | 2 |
|
3 | 3 | import dparse.ast; |
4 | | -import dparse.lexer : IdType, str, Token, tok; |
| 4 | +import dparse.lexer : IdType, str, tok, Token; |
5 | 5 | import dscanner.analysis.nolint; |
6 | 6 | import dsymbol.scope_ : Scope; |
7 | 7 | import std.array; |
@@ -639,12 +639,13 @@ public: |
639 | 639 | { |
640 | 640 | // case and default statements always open new scopes and close |
641 | 641 | // previous case scopes |
642 | | - bool close = switchStack.length && switchStack[$ - 1].inCase; |
643 | | - bool b = switchStack[$ - 1].inCase; |
644 | | - switchStack[$ - 1].inCase = true; |
| 642 | + bool wasInCase = switchStack.length && switchStack[$ - 1].inCase; |
| 643 | + if (switchStack.length) |
| 644 | + switchStack[$ - 1].inCase = true; |
645 | 645 | scope (exit) |
646 | | - switchStack[$ - 1].inCase = b; |
647 | | - if (close) |
| 646 | + if (switchStack.length) |
| 647 | + switchStack[$ - 1].inCase = wasInCase; |
| 648 | + if (wasInCase) |
648 | 649 | { |
649 | 650 | popScope(); |
650 | 651 | pushScope(); |
@@ -897,3 +898,52 @@ unittest |
897 | 898 | auto isOldScope = void; |
898 | 899 | }); |
899 | 900 | } |
| 901 | + |
| 902 | +// test previous segfault |
| 903 | +unittest |
| 904 | +{ |
| 905 | + import dparse.lexer : getTokensForParser, LexerConfig, StringCache; |
| 906 | + import dparse.parser : parseModule; |
| 907 | + import dparse.rollback_allocator : RollbackAllocator; |
| 908 | + |
| 909 | + StringCache cache = StringCache(4096); |
| 910 | + LexerConfig config; |
| 911 | + RollbackAllocator rba; |
| 912 | + auto tokens = getTokensForParser(q{ |
| 913 | + module derp; |
| 914 | + |
| 915 | + void main(string[] args) |
| 916 | + { |
| 917 | + foreach |
| 918 | + switch (x) |
| 919 | + { |
| 920 | + case 1: |
| 921 | + if (y) { |
| 922 | + continue; |
| 923 | + } |
| 924 | + break; |
| 925 | + default: |
| 926 | + break; |
| 927 | + } |
| 928 | + } |
| 929 | + }, config, &cache); |
| 930 | + auto m = parseModule(tokens, "stdin", &rba); |
| 931 | + |
| 932 | + class TestScopedAnalyzer : ScopedBaseAnalyzer |
| 933 | + { |
| 934 | + this() |
| 935 | + { |
| 936 | + super(BaseAnalyzerArguments("stdin")); |
| 937 | + } |
| 938 | + |
| 939 | + override protected void pushScope() |
| 940 | + { |
| 941 | + } |
| 942 | + |
| 943 | + override protected void popScope() |
| 944 | + { |
| 945 | + } |
| 946 | + } |
| 947 | + |
| 948 | + new TestScopedAnalyzer().visit(m); |
| 949 | +} |
0 commit comments