Commit Graph

97453 Commits

Author SHA1 Message Date
pyos 5d4b44500a FIR CFA: remove direction from ControlFlowGraph.traverse.
If you care about direction, then you also care about labels.

3 out of 6 places that use `traverse` are incorrect, by the way.
Node order does not correspond to scoping boundaries.
2023-01-10 15:40:53 +02:00
pyos de105e602d FIR CFA: remove redundant entries from followingCfgNodes
Edges to subgraphs should now be correctly added, so there's no need to
look at them separately.
2023-01-10 15:40:52 +02:00
pyos da018e9d06 FIR CFA: align reading of labels with the way they're generated
UncaughtExceptionPath label out of a finally block matches every label
that is not handled by another edge, and a labeled edge from the middle
of a finally block aborts the jump and so should merge all available
data.
2023-01-10 15:40:52 +02:00
pyos d655147c8c FIR CFA: remove a redundant wrapper around PersistentMap 2023-01-10 15:40:52 +02:00
pyos 065ed46495 FIR CFA: require path awareness in fixed point iteration
It really doesn't make sense to collect control flow data without
checking paths, since that'll produce incorrect results for try-catch.
2023-01-10 15:40:52 +02:00
pyos 63ab9119f8 FIR: do not use CFG in FirPropertyInitializationChecker 2023-01-10 15:40:52 +02:00
pyos e86b87fe0b Test: FIR CFA: fix the names of some nodes 2023-01-10 15:40:52 +02:00
pyos fbd0908f0c FIR DFA: add smartcast invalidation for init block assignments 2023-01-10 15:40:51 +02:00
pyos c185bf60f8 Add a test for data flow with reassignments in local classes 2023-01-10 15:40:51 +02:00
pyos 1aae586238 FIR DFA: don't erase statements when entering non-call-in-place lambda
Instead, rely on the variable assignment analyzer to properly restrict
smart casts. This makes error messages more consistent, but otherwise
should have no effect.
2023-01-10 15:40:51 +02:00
pyos 5a79017879 FIR CFA: remove some redundant node stacks
Honestly the amount of mutable state in the builder makes me somewhat
uneasy.
2023-01-10 15:40:51 +02:00
pyos 60662663be FIR CFA: remove the id parameter from nodes 2023-01-10 15:40:51 +02:00
pyos dca6caaafa FIR CFA: add a hack for enum classes and LL API
No clue what's going on there.
2023-01-10 15:40:51 +02:00
pyos 377b7bdf5e FIR CFA: remove top-level graph
It should never have contained any nodes because it was not attached
to anything.
2023-01-10 15:40:50 +02:00
pyos b548473544 FIR CFA: automatically compute node levels 2023-01-10 15:40:50 +02:00
pyos 0dd949bb36 FIR DFA: route data flow through anonymous objects
^KT-44515 Fixed
2023-01-10 15:40:50 +02:00
pyos 17ee8f3a7b FIR CFA: put primary constructor before other class members 2023-01-10 15:40:50 +02:00
pyos c6e9afb788 FIR CFA: remove class initializer part nodes
Instead, attach subgraphs directly to the class enter node.
2023-01-10 15:40:50 +02:00
pyos b9f366af05 FIR CFA: remove infinite loops from toposort
Finally, no more tests getting stuck on `orderNodes`. Only took me what,
75 commits to fix enough things to make this actually work?
2023-01-10 15:40:50 +02:00
pyos 54f32a6fba Test: FIR CFA: index nodes in rendering order 2023-01-10 15:40:49 +02:00
pyos a9397b7b23 Test: FIR CFA: don't output two node fill colors 2023-01-10 15:40:49 +02:00
pyos 3887c80816 FIR CFA: ensure on API level that graphs have enter & exit
What's going on with script graphs?..
2023-01-10 15:40:49 +02:00
pyos e710edbd77 FIR CFA: use a common fake node for annotation calls and contracts
The graphs for both will be completely discarded and should never be
visited.
2023-01-10 15:40:49 +02:00
pyos 4bb7b1ac9f FIR DFA: use class enter node as data flow source for members
Also fix graphs for enums with specialized entries - since we don't
create property subgraphs for FirEnumEntry, there is no body to insert
AnonymousObjectEnterNode, AnonymousObjectExitNode, and
AnonymousObjectExpressionExitNode into.
2023-01-10 15:40:49 +02:00
pyos e6819e1295 FIR CFA: refactor handling of classes a bit
As usual, I'm leaving TODOs wherever I go...
2023-01-10 15:40:49 +02:00
pyos 4c6eff9174 FIR CFA: compute subgraph relationships automatically
No more `addSubGraph`. Also no more `owner` in graphs.

^KT-40526 Obsolete
^KT-40582 Obsolete
2023-01-10 15:40:48 +02:00
pyos 7ff5ad1ad0 FIR CFA: remove modes
They are only used in one place that can just as well use kinds.

Especially considering that "the one place" used them incorrectly and
would not attach local functions in property accessors as subgraphs.
2023-01-10 15:40:48 +02:00
pyos cb8cb1f610 FIR CFA: attach accessors and nested classes as class subgraphs 2023-01-10 15:40:48 +02:00
pyos 5d4fb3ead8 FIR CFA: add control flow between default parameter values
function enter -> default 1 -> default 2 -> rest of function
                   \----------^ \----------^

This probably has no effect (in non-stupid code, at least), but it makes
graph construction more architecturally correct (now value parameters'
subgraphs get attached to a node).
2023-01-10 15:40:48 +02:00
pyos 74758278d7 FIR CFA: attach method graphs to class exit node
Even for non-local classes. This ensures that the CFG edges in this case
will only go to a subgraph, not to an unrelated graph.
2023-01-10 15:40:48 +02:00
pyos aadea0e26f FIR CFA: properly visit subgraphs in checkers
Interpretation: a graph A is a subgraph of B if information available at
nodes of A depends on the paths taken in B. For example, local classes
are subgraphs of a graph in which they are declared, and members of
those classes are subgraphs of the local class itself - because these
members can reference captured values.

Consequences:

 * if graph G is a subgraph of node N, then G is a subgraph of N's
   owner;
 * `ControlFlowAnalysisDiagnosticComponent` will only visit root graphs;
 * `graph.traverse` will ignore subgraph boundaries, as if all subgraphs
   are inlined into one huge root graph;
 * if a control flow checker needs information from a declaration to
   which a graph is attached, it must look at subgraphs explicitly.

For example, consider the `callsInPlace` checker. When a function
has a `callsInPlace` contract and a local declaration, the checker must
visit that local declaration to ensure it does not capture the allegedly
called-in-place argument - hence `graph.traverse` will look at the
nodes. However, the local declaration can also be a function with its
own `callsInPlace` contracts, so the checker should also run for it in
isolation. If that sounds quadratic, that's because unfortunately it is.
2023-01-10 15:40:48 +02:00
pyos 5180e1f4a4 FIR DFA: fix mismatched calls to enter/exitProperty
Otherwise the graph stack becomes incorrect.
2023-01-10 15:40:48 +02:00
pyos bcc54deb64 FIR CFA: fix deadness of various nodes
* `do { continue } while (x)`: block exit is dead, condition is not;

 * `try { a?.incomplete() } catch (e) { x }`: when the call is completed
   and found to return `Nothing`, the safe call exit node is still live
   because `a` could still be null;

 * `f(a@{ g { return@a } }, x)`: if call to `g` is not completed, there
   should not be a dead data flow edge from the lambda to `f` because
   there's no such thing as a dead data flow edge (DeadForward is CF+DF).
2023-01-10 15:40:47 +02:00
pyos e7e5569539 FIR CFA: do not remove provideDelegate subgraphs when rolling back
The receiver of the provideDelegate call is the same FirExpression as
the delegate itself, so there's only one copy of the nodes in the first
place; trying to remove subgraphs completely detaches objects inside it
from the parent graph, which is not great for checkers.

Note that currently if provideDelegate is not selected, there will be a
stray FunctionCallExit node in the control flow graph. This commit *does
not change that*. It has been there for a while. Don't @ me. I'll try to
fix that. No promises.
2023-01-10 15:40:47 +02:00
pyos ef2fa01a8d FIR CFA: remove redundant "uncaught exception path" edges
These are not real, and in fact tricked the compiler into thinking some
blocks that do not terminate do somehow terminate.
2023-01-10 15:40:47 +02:00
pyos fa0ea1504e FIR CFA: remove CFGNode.outgoingEdges
If it's symmetric with incomingEdges, then what's the point?..
2023-01-10 15:40:47 +02:00
pyos 7feeb7cd4e FIR CFA: remove edge kind merging
There shouldn't be any duplicate edges anymore. There probably weren't
any before, either.
2023-01-10 15:40:47 +02:00
pyos 069d99c5ea FIR CFA: rewrite handling of try-catch-finally
The result is the same, but it should now be much clearer what the
shortcomings of the current implementation are.
2023-01-10 15:40:47 +02:00
pyos a079010fad FIR CFA: clean up some utility functions 2023-01-10 15:40:46 +02:00
pyos faf0129a5d Test: FIR CFA: sort edges by style & target node id 2023-01-10 15:40:46 +02:00
pyos 7ee1b75e43 FIR: don't add T <: Unit constraints that will only remove errors
^KT-55693 Fixed
2023-01-10 15:40:46 +02:00
pyos b6653dd872 Minor: remove some duplicate test data
Apparently if you add an empty line at the start of the FIR file, that's
not enough of a difference for the test suite to complain about, but
enough for it to not add the FIR_IDENTICAL directive...
2023-01-10 15:40:46 +02:00
pyos 5e8591d61d FIR: use expected type for lambda return statements if possible 2023-01-10 15:40:46 +02:00
pyos 1eccb9aea1 FIR: assume a lambda returns Unit if it ends with a non-expression
While it is theoretically useful to know that `{ while(true) {} }`
returns Nothing, CFG node deadness is not precise enough to do that: if
the entire lambda is dead, it's no longer possible to find out whether
the loop is terminating. Besides, `while (true)` and `if (true)` are
pretty much the only constructs like that anyway.

Note that this commit does not affect resolution for lambdas that end in
a Nothing-returning expression, e.g. `throw`.
2023-01-10 15:40:46 +02:00
pyos 803abfeba8 FIR: rewrite lambda return type inference
* `return` should only be added to the last statement if the return
   type is not Unit

 * If there is a `return` without an argument, then the expected return
   type is Unit and the last expression is not a return argument (unless
   it's an incomplete call, in which case it is inferred to return Unit;
   this behavior is questionable, but inherited from K1)

 * There should be a constraint on return arguments even if the expected
   type is Unit, otherwise errors will be missed

 * When the expected type is known, using the call completion results
   writer is pointless (and probably subtly wrong).

^KT-54742 Fixed
2023-01-10 15:40:45 +02:00
pyos 544cf386af Add test for KT-54742 2023-01-10 15:40:45 +02:00
Yahor Berdnikau 0bce15b862 Mark all internal configuration as resolvable and non-consumable
^KT-55632 Fixed
2023-01-10 13:06:12 +00:00
Ilya Kirillov 20b81464be [Analysis API] fix IndexOutOfRangeException
Previously, the `KtFirUsualClassType.qualifiers` was empty for the local classes

The reason was a RawFirBuilder setting up a containingClassForLocalAttr
to the outer non-local class for the local class. It should be a null instead,
see the localClassType.kt as an example

^KT-55510 fixed
2023-01-10 12:54:18 +00:00
Ilya Kirillov 61d8b91c89 [Analysis API] add tests for checking KtType internals 2023-01-10 12:54:17 +00:00
Ilya Kirillov 2b94a33937 [Analysis API FE1.0] rename KtFe10Type.type -> KtFe10Type.fe10Type to disambiguatly ignore in testdata renderings 2023-01-10 12:54:17 +00:00