-
Notifications
You must be signed in to change notification settings - Fork 86
TUM Practical Course Summer 2023: Termination Analyses #1093
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 227 commits
Commits
Show all changes
419 commits
Select commit
Hold shift + click to select a range
af61d92
Merge branch 'recursion' of https://github.com/serenita/goblint-analy…
c6f37b2
added weird test case + merging
566ae50
Fix indentation
6cf3d12
Small changes
cfaf417
added location to recursion Warning
f309afd
Merge branch 'recursion' of https://github.com/serenita/goblint-analy…
b562cac
Merge branch 'master' into lagemann-dev
LageTs cb8d719
Merge branch 'recursion' into lagemann-dev
LageTs a4991e0
Adapted update_suite.rb and tests to termination output
LageTs 7a6b18c
reverted test case
4a402ca
reverted test case
f35c116
pulled master
79ac4ba
fixed error that for only one function the analysis was not executed:…
6a4105d
Added SKIP/TODO functionality for loop termination
LageTs 3e6ffcc
Merge branch 'recursion' into lagemann-dev
LageTs 6f39218
Adapted TODO comments to current state
LageTs 0f3dbdc
Comment out unused loop_heads function
1a09057
Answer queries with false when multi-threaded
524f0cb
Change comments
72062a6
Added requested test cases
LageTs 05cb3f7
Merge branch 'master' of https://github.com/serenita/goblint-analyzer
2f9f697
Skip crashing tests
LageTs 178c1ac
Merge branch 'master' into lagemann-dev
LageTs e250557
reverted test case 55 01
cf96d59
merging
4e66fd2
make recursion analysis optional (depending if loop ana is activated)
f467bab
Merge branch 'master' of https://github.com/serenita/goblint-analyzer…
d2fce9b
Merge branch 'master' of https://github.com/serenita/goblint-analyzer
4b4be5b
work-in-progress on svcomp integration
62d260f
handled warnings during make
3707652
indentation
f7dab71
indentation
5b0d72f
Indentation with ocp-indent
LageTs 8a320eb
added sv-comp compatability
5bb821c
revert testchanges in option.schema.json
5d3f25c
Fix indentation
a6a1526
Merge redefinition of old termination with new loop/recursion termina…
LageTs fa71e4e
Merge remote-tracking branch 'upstream/master'
8603177
Fix indentation
d987f1a
Restore signs analysis tutorial
b1930ab
Simplify src/framework/analyses.ml
serenita a3fd8d0
Fix indentation
ba596d7
Remove build_testing.yml
fbef208
No skipping
LageTs 13f369a
New non terminating for loop
LageTs d681158
Folder Renaming
LageTs 541e49b
Enable polyhedra; Removed unnecessary TODOs
LageTs 1b5db9c
patched loop termination check position to right after the loop head
e6ba559
removed temporary comment
30ecae7
Merge branch 'master' into lagemann-dev
LageTs 16b8c37
removed outdated code
1cefa96
Removed unnecessary TODOs
LageTs 2430f3f
Renamed LOCAL_TERM to TERM
LageTs 1ec6bd6
Merge branch 'master' into lagemann-dev
LageTs 2c73948
Reformat
LageTs 7f484cb
Skip crashing tests
LageTs a91e716
Rename loop termination analysis
8483cec
Removed Todos
LageTs 11122b3
Merge branch 'master' into lagemann-dev
LageTs 91f18ef
Adapted tests to current state
LageTs 1c43039
Adapted tests to current state
LageTs c890d5b
No skipping
LageTs 569fefd
New non terminating for loop
LageTs aca1ec5
Folder Renaming
LageTs 70bad4c
Enable polyhedra; Removed unnecessary TODOs
LageTs e70761c
Removed unnecessary TODOs
LageTs ee93929
Renamed LOCAL_TERM to TERM
LageTs d05da3a
Reformat
LageTs 036dd17
Skip crashing tests
LageTs 4cb5da0
Removed Todos
LageTs fec0d62
Adapted tests to current state
LageTs 68b01af
Adapted tests to current state
LageTs 529d70e
Merge remote-tracking branch 'upstream/master'
b7c6ec5
Restore apronAnalysis.apron.ml
432e92d
Explicitly use () as the abstract local state
2953242
Change let-in clause to sequential statements
c2c69cf
Update src/framework/constraints.ml
serenita d18d8fe
Update src/framework/constraints.ml
serenita 0d77172
Remove unnecessary semicola
serenita 76230f4
Restore 01-simple-cases.c from white space change
7706ac3
Merge branch 'master'
6e62041
adapted changes from pull request: 1. using a module for tuple; 2. de…
9c8d128
changed the order in C_Printable
c776d8c
changed naming for SV-Comp specification from NoTermination to Termin…
b1da8e2
renamed termination in control to termination_enabled; added comment …
1ace9d6
Add description to loop/goto termination analysis
30b03ce
Introduce isEverMultiThreaded analysis
e8aec04
Finish and use everMultiThreaded analysis
f8fa8e3
Revert whitespace change
4f60156
added missing __goblint_bounded implementations
21f2f34
Temp. revert must_be_single_threaded_since_start
048de26
Patched inconsistency with nested loops
1421775
Merge remote-tracking branch 'upstream/master'
b67eacd
Rename loop termation analysis
22efd12
changed name
4308bdb
Merge branch 'master' of https://github.com/serenita/goblint-analyzer
c5fe485
Remove unused code
094d564
Merge branch 'master' into lagemann-dev
LageTs b9a5c36
Tests adapted and new test 74/35
LageTs 7e12cb5
Tests is now passing
LageTs bc7bef7
Restrict boundedness checking to postsolving
08ad8d0
Revert "Restrict boundedness checking to postsolving"
2e05e9e
Restrict boundedness checking to postsolving (fix)
0d79d2a
Widen recursion test
LageTs 4459239
Merge branch 'lagemann-dev'
LageTs 1190d63
Adapted test parameter
LageTs dbe3684
inlined Groupable C to Map
73b4f89
Merge branch 'master' of https://github.com/serenita/goblint-analyzer
5f11a50
Merge remote-tracking branch 'upstream/master'
68bf103
Rename query MustTermProg to MustTermAllLoops
fbc2966
Test moved and renamed
LageTs 4a6714c
added comments to explain why test 74/28 does fail and why 30 and 35 …
852d065
Merge branch 'master' of https://github.com/serenita/goblint-analyzer
cb13d14
Tests moved
LageTs c6e36e4
cleaned module G from an unnecessary function; addded missing comment…
ff42a19
Merge branch 'lagemann-dev'
LageTs 9d66846
Complex test adapted
LageTs ed01412
Merge branch 'master' into lagemann-dev
LageTs 09ee872
moved warnings to loop analysis
83e31fc
Merge branch 'master' of https://github.com/serenita/goblint-analyzer
d6c11b6
Test refactoring & parameter correction
LageTs 1faf729
added autoTune for termination analysis in mainGoblint.ml
d58f6c7
Merge branch 'master' of https://github.com/serenita/goblint-analyzer
43bf64d
temporarly removed sem.int.signed_overflow assume_none autotuning
5ef2664
Test indentation
LageTs d394d95
Merge branch 'master' into lagemann-dev
LageTs 71b1eb2
Execute termination tests in CI even if skipped.
LageTs 472a76c
added warning for multithreaded case
4af911a
Revert "added warning for multithreaded case"
32a654b
addedd the possibly non-terminating warning for multi threaded programs
d0fc53f
Merge remote-tracking branch 'upstream/master'
53c3c1c
Enable use of everMultiThreaded analysis
76486c9
Make struct for V anonymous
ba9d35a
indentation
a98f503
Test goal and comments changed
LageTs 98c062a
Test indentation
LageTs 4dd330c
Execute termination tests in CI even if skipped.
LageTs 7e6ac43
Merge remote-tracking branch 'origin/lagemann-dev' into lagemann-dev
LageTs 12ce13d
Merge remote-tracking branch 'upstream/master'
LageTs 6c8152d
Merge branch 'master' into lagemann-dev
LageTs 5f98417
Test explanation && new test case termination 43
LageTs 76f540f
Test explanation && new test case termination 43
LageTs 40ea15c
Added special function --Still work in progress
392c919
Merge branch 'master' of https://github.com/serenita/goblint-analyzer
30692fc
Test for code line detection
LageTs dc0a284
changed __goblint_bounded constructor from Assert to Bounded
c1153f7
Merge remote-tracking branch 'upstream/master'
1f499e9
Use special function instead of variable indicator
b9a5b3f
Clean up, make things look nicer
6146c76
Wrap always_single_threaded in let-in clause
847ea36
Remove PreProcessing exception
4087dfb
removed the trick to make C groupable due to #1112; deleted printXML …
bd58dc5
Merge remote-tracking branch 'upstream/master'
2f31211
Merge remote-tracking branch 'upstream/master'
0a9c5d4
Fix indentation
10260bd
Added more recursive tests
LageTs f8a2e53
Merge branch 'lagemann-dev'
LageTs 4e36511
removed exit-indikator variable
d47e88e
removed debug print; Might solve cram tests
021ddad
Remove debug output
47440a3
Code style optimization
LageTs 91d331d
Indentation
LageTs fc427bc
Fix indentation
3fb5d14
Test case 48
LageTs 97d9c80
Merge branch 'master' of https://github.com/serenita/goblint-analyzer
8c2b4e0
Merge remote-tracking branch 'upstream/master'
601698f
Remove unused code; introduce basic error-handling
ed58098
Merge branch 'lagemann-dev'
LageTs 66115b1
Annotate tests with skip as Apron ist used
LageTs ed97494
Merge remote-tracking branch 'upstream/master'
3c31cb7
Revert src/analyses/termination.ml
LageTs 912431d
Merge remote-tracking branch 'upstream/master'
a9c9c7d
changed initial value of lcv to min int; swaped sequence of increment…
782b21c
Fix indentation
c53f0b8
Polish comments
cd8fae0
Merge remote-tracking branch 'upstream/master'
c52cf47
Remove runningGob.sh
867e6ca
Restore indentation; remove unused include Printf
0f94aaa
More indentation restoring
f4fd0c2
Fix a typo
1be8c9c
Remove goto stuff from loopTermination analysis
cf594b6
Add goto-fundec list in cilfacade.ml
eabf6b7
add gotos with their respective function to new list in Cilfacade
19addab
added code for control to only print upjumping goto message when goto…
7444dc9
Merge branch 'master' of https://github.com/serenita/goblint-analyzer
72e2e22
now everything should work :), now iterating over live_lines
6090c62
now without prints :)))
e96433b
Handle skipped (NON-)TERM-Tests other than TODO
LageTs e1f8319
Set sv-comp flag for upjumping gotos
michael-schwarz b832f31
Increase indentation in switch-case in update_suite.rb.
jerhard a6e4af4
Rename must_be_single_threaded_since_start to must_always_be_single_t…
jerhard 7ba0fd3
Merge branch 'master' into term
michael-schwarz 8be0343
Merge branch 'master' into term
michael-schwarz 44b4492
Issue non-termination warning for `longjmp` calls
michael-schwarz ea38918
Include termination tests into `coverage` and `unlocked`
michael-schwarz e284953
Simplify global invariant
michael-schwarz 7f3cadf
Adapt comments to simplified global invariant
michael-schwarz 515a8bd
Simplify cycle detection
michael-schwarz b3016ff
Failwith meaningful message for invaliud calls to `__goblint_bounded`
michael-schwarz 14c3ead
Merge branch 'master' into term
michael-schwarz 5844552
Cleanup termination property
michael-schwarz 7cca2cf
LTL for termination is `F end`
michael-schwarz 268d86d
Merge branch 'master' into term
michael-schwarz a7d02c4
Simplify warning
michael-schwarz cf22550
Delete old termination analysis
michael-schwarz 67cc037
Rm old Termination also from `goblint_lib.ml`
michael-schwarz dff7be0
Make `do_preprocess_cil` more efficient
michael-schwarz 2d8fe09
Remove outdated TODO
michael-schwarz e690d9a
Prioritze termination warnings in `update_suite.rb`
michael-schwarz f024fd9
Merge branch 'master' into term
michael-schwarz fb92abc
Rename NonTerminating -> Termination
michael-schwarz aad465c
Autotune for Termination
michael-schwarz 2ff979b
Simplify variable names
michael-schwarz b49356c
Deduplicate preprocessing
michael-schwarz 490203d
Move `everMultiThreaded` to `threadflag`
michael-schwarz e25b708
Simplify `loopTermination`
michael-schwarz d4ab699
Fail when `termination` is active and incremental analysis is enabled
michael-schwarz 47d0f5d
Termination: set `is_write_only`
michael-schwarz 4417b9c
Reset `upjumping_gotos`
michael-schwarz de416ee
Cleanup upjumping_gotos
michael-schwarz e66cf56
Make type of variables used for loop termination analysis more easily…
jerhard e02801a
Remove redundant code for setting todo variable
jerhard 3d3c069
Add define min_int_exp depending on the signedness of the counter var…
jerhard 46b0f67
Change indentation in update_suite.rb back to reduce number of lines …
jerhard 21d405d
Change indentatation back.
jerhard bc126fa
Fix indentation of line.
jerhard 0e0986a
Use Z instead of Cilint
jerhard f18fe58
Change - to _ in name of variable introduced in terminationPreprocess…
jerhard aef46ce
Add LoopTermination and TerminationPreprocessing to goblint_lib
jerhard 72c14e2
Extract function find_loop, given a loop_counter.
jerhard ddfcaea
Rename x to loop_counter.
jerhard 7241324
Use increment_expression that takes the ikind of the counter variable…
jerhard 76751d4
Termination analysis: Insert only one increment statement, do not set…
jerhard 5d54827
Set regresion tests to todo that are now imprecise.
jerhard f81ca2c
Termination: Use unsigned long long for counter variables; reactivate…
jerhard 2728c2a
Termination: Update verdict to TODO for 78/35.
jerhard 8934a21
Autotuner: Activate termination analysis in autotuner.
jerhard d5662c5
Indicate that termination analysis is activated.
jerhard 245b438
Change wording from enabling to enabled for consistency.
jerhard cbe4ad0
Add termination to autotune for svcomp.json, but remove it from svcom…
jerhard a466650
Move LoopTermination in Goblint_lib to analyses/other section.
jerhard b57b9e4
Extract some loops into functions; this reduces runtime of analysis.
jerhard 70ef2d2
RelationalAnalysis: Assert type-bounds also for signed types when no-…
jerhard 8141869
Termination distribute loops into multiple functions to make analysis…
jerhard 1ef011c
Add test case that did not work when not asserting the type bounds fo…
jerhard d9f3910
Remove outdated comment.
jerhard 26d8012
Autotuner: Remove activateTerminationAnalysis, as there is already ot…
jerhard 28dca49
Add specification to activated settings for autotuner.
jerhard a4adabd
Call Autotune.focusOnSpecification before preprocessing, as terminati…
jerhard 41ee060
Do loop unrolling for loops with boundedness check.
jerhard File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,4 +27,8 @@ void __goblint_split_begin(int exp) { | |
|
|
||
| void __goblint_split_end(int exp) { | ||
|
|
||
| } | ||
|
|
||
| void __goblint_bounded() { | ||
|
|
||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| #!/bin/bash | ||
| make | ||
| make install | ||
| clear | ||
|
|
||
| # set options and file for apron execution | ||
| options_apron="--set ana.activated[+] apron --enable ana.int.interval --set ana.apron.domain polyhedra --enable warn.debug" #note: preprocessing first needs to be added to apron | ||
| options_signs="--set "ana.activated[+]" signs --enable warn.debug" | ||
| options_term="--set "ana.activated[+]" termination --enable warn.debug --set ana.activated[+] apron --enable ana.int.interval --set ana.apron.domain polyhedra" | ||
|
|
||
| cfile_loops="tests/regression/55-loop-unrolling/01-simple-cases.c" | ||
| cfile_signs="tests/regression/99-tutorials/01-first.c" | ||
| cfile_goto="tests/incremental/02-cfg-comparison/01-added-return-stmt.c" | ||
|
|
||
| # run analysis, write cil output to file and enable visualization via html | ||
| #./goblint $cfile_loops $options_apron --enable justcil > output.txt | ||
| #./goblint $cfile_loops $options_apron --html | ||
|
|
||
| # run analysis, write cil output to file and enable visualization via html | ||
| #./goblint -v $cfile_loops $options_term --enable justcil > output.txt | ||
| ./goblint $cfile_loops $options_term --html | ||
|
|
||
| # set up server to see visualizatino | ||
| python3 -m http.server --directory result 8080 | ||
| #./goblint --enable dbg.debug tests/regression/55-loop-unrolling/01-simple-cases.c --enable ana.int.interval --set "ana.activated[+]" signs --enable justcil > output.txt | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| (** Work in progress *) | ||
|
|
||
| open Analyses | ||
| open GoblintCil | ||
| open TerminationPreprocessing | ||
|
|
||
| exception PreProcessing of string | ||
|
|
||
| (* | ||
| let loop_heads () = | ||
| let module FileCfg = | ||
| struct | ||
| let file = !Cilfacade.current_file | ||
| module Cfg = (val !MyCFG.current_cfg) | ||
| end in | ||
| let module WitnessInvariant = WitnessUtil.Invariant (FileCfg) in | ||
| WitnessInvariant.loop_heads (* TODO: Unused *) | ||
| *) | ||
michael-schwarz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| (** Contains all loop counter variables (varinfo) and maps them to their corresponding loop statement. *) | ||
| let loop_counters : stmt VarToStmt.t ref = ref VarToStmt.empty | ||
|
|
||
| (** Contains the locations of the upjumping gotos *) | ||
| let upjumping_gotos : location list ref = ref [] | ||
|
|
||
| (** Indicates the place in the code, right after a loop is exited. *) | ||
| let loop_exit : varinfo ref = ref (makeVarinfo false "-error" Cil.intType) | ||
|
|
||
| let is_loop_counter_var (x : varinfo) = | ||
| VarToStmt.mem x !loop_counters | ||
|
|
||
| let is_loop_exit_indicator (x : varinfo) = | ||
| x = !loop_exit | ||
michael-schwarz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| let no_upjumping_gotos () = | ||
| upjumping_gotos.contents = [] | ||
|
|
||
| (** Checks whether a variable can be bounded *) | ||
| let check_bounded ctx varinfo = | ||
| let open IntDomain.IntDomTuple in | ||
| let exp = Lval (Var varinfo, NoOffset) in | ||
| match ctx.ask (EvalInt exp) with | ||
| | `Top -> false | ||
| | `Lifted v -> not (is_top_of (ikind v) v) | ||
| | `Bot -> raise (PreProcessing "Loop variable is Bot") | ||
michael-schwarz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| module UnitV = | ||
| struct | ||
| include Printable.Unit | ||
| include StdV | ||
| end | ||
|
|
||
| (** We want to record termination information of loops and use the loop | ||
| * statements for that. We use this lifting because we need to have a | ||
| * lattice. *) | ||
| module Statements = Lattice.Flat (CilType.Stmt) (Printable.DefaultNames) (* TODO: Use Basetype.CilStmt instead? *) | ||
|
|
||
| (** The termination analysis considering loops and gotos *) | ||
| module Spec : Analyses.MCPSpec = | ||
| struct | ||
|
|
||
| (** Provides some default implementations *) | ||
| include Analyses.IdentitySpec | ||
|
|
||
| let name () = "termination" | ||
|
|
||
| module D = Lattice.Unit | ||
| module C = D | ||
| module V = UnitV | ||
| module G = MapDomain.MapBot (Statements) (BoolDomain.MustBool) | ||
|
|
||
| let startstate _ = D.bot () | ||
michael-schwarz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| let exitstate = startstate | ||
|
|
||
| let assign ctx (lval : lval) (rval : exp) = | ||
| (* Detect assignment to loop counter variable *) | ||
michael-schwarz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| match lval, rval with | ||
| (Var y, NoOffset), Lval (Var x, NoOffset) when is_loop_exit_indicator y -> | ||
| (* Loop exit: Check whether loop counter variable is bounded *) | ||
| (* TODO: Move to special *) | ||
| let is_bounded = check_bounded ctx x in | ||
| let loop_statement = VarToStmt.find x !loop_counters in | ||
| let () = ctx.sideg () (G.add (`Lifted loop_statement) is_bounded (ctx.global ())) in | ||
| ctx.local | ||
michael-schwarz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| | _ -> ctx.local | ||
|
|
||
| let special ctx (lval : lval option) (f : varinfo) (arglist : exp list) = | ||
| (* TODO: Implement check for our special loop exit indicator function *) | ||
| ctx.local | ||
|
|
||
| (** Checks whether a new thread was spawned some time. We want to discard | ||
| * any knowledge about termination then (see query function) *) | ||
| let must_be_single_threaded_since_start ctx = | ||
| ctx.ask (Queries.MustBeSingleThreaded {since_start = true}) | ||
|
|
||
| (** Provides information to Goblint *) | ||
| let query ctx (type a) (q: a Queries.t): a Queries.result = | ||
| match q with | ||
| | Queries.MustTermLoop loop_statement -> | ||
| (match G.find_opt (`Lifted loop_statement) (ctx.global ()) with | ||
| Some b -> b | ||
| | None -> false) | ||
| && must_be_single_threaded_since_start ctx | ||
| | Queries.MustTermProg -> | ||
| G.for_all (fun _ term_info -> term_info) (ctx.global ()) | ||
| && no_upjumping_gotos () | ||
| && must_be_single_threaded_since_start ctx | ||
| | _ -> Queries.Result.top q | ||
|
|
||
| end | ||
|
|
||
| let () = | ||
| (* Register the preprocessing *) | ||
| Cilfacade.register_preprocess_cil (Spec.name ()) (new loopCounterVisitor loop_counters upjumping_gotos loop_exit); | ||
| (* Register this analysis within the master control program *) | ||
| MCP.register_analysis (module Spec : MCPSpec) | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.