aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dialyzer/src/dialyzer_typesig.erl
AgeCommit message (Collapse)Author
2018-02-07Merge branch 'hasse/no_get_stacktrace/OTP-14861'Hans Bolinder
* hasse/no_get_stacktrace/OTP-14861: erts: Update abstract format doc with stacktrace variable wx: Do not call erlang:get_stacktrace() tools: Do not call erlang:get_stacktrace() stdlib: Do not call erlang:get_stacktrace() sasl: Do not call erlang:get_stacktrace() runtime_tools: Do not call erlang:get_stacktrace() reltool: Do not call erlang:get_stacktrace() parsetools: Do not call erlang:get_stacktrace() observer: Do not call erlang:get_stacktrace() mnesia: Do not call erlang:get_stacktrace() (cont) mnesia: Do not call erlang:get_stacktrace() kernel: Do not call erlang:get_stacktrace() inets: Do not call erlang:get_stacktrace() eunit: Do not call erlang:get_stacktrace() et: Do not call erlang:get_stacktrace() dialyzer: Do not call erlang:get_stacktrace() debugger: Do not call erlang:get_stacktrace() debugger: Do not try to restore stacktrace common_test: Do not call erlang:get_stacktrace()
2018-02-06dialyzer: Assign a type to the primop build_stacktraceHans Bolinder
2018-02-05dialyzer: Do not call erlang:get_stacktrace()Hans Bolinder
2017-11-30Add syntax in try/catch to retrieve the stacktrace directlyBjörn Gustavsson
This commit adds a new syntax for retrieving the stacktrace without calling erlang:get_stacktrace/0. That allow us to deprecate erlang:get_stacktrace/0 and ultimately remove it. The problem with erlang:get_stacktrace/0 is that it can keep huge terms in a process for an indefinite time after an exception. The stacktrace can be huge after a 'function_clause' exception or a failed call to a BIF or operator, because the arguments for the call will be included in the stacktrace. For example: 1> catch abs(lists:seq(1, 1000)). {'EXIT',{badarg,[{erlang,abs, [[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20|...]], []}, {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,674}]}, {erl_eval,expr,5,[{file,"erl_eval.erl"},{line,431}]}, {shell,exprs,7,[{file,"shell.erl"},{line,687}]}, {shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]}, {shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}]}} 2> erlang:get_stacktrace(). [{erlang,abs, [[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22, 23,24|...]], []}, {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,674}]}, {erl_eval,expr,5,[{file,"erl_eval.erl"},{line,431}]}, {shell,exprs,7,[{file,"shell.erl"},{line,687}]}, {shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]}, {shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}] 3> We can extend the syntax for clauses in try/catch to optionally bind the stacktrace to a variable. Here is an example using the current syntax: try Expr catch C:E -> Stk = erlang:get_stacktrace(), . . . In the new syntax, it would look like: try Expr catch C:E:Stk -> . . . Only a variable (not a pattern) is allowed in the stacktrace position, to discourage matching of the stacktrace. (Matching would also be expensive, because the raw format of the stacktrace would have to be converted to the cooked form before matching.) Note that: try Expr catch E -> . . . is a shorthand for: try Expr catch throw:E -> . . . If the stacktrace is to be retrieved for a throw, the 'throw:' prefix must be explicitly included: try Expr catch throw:E:Stk -> . . .
2017-11-22dialyzer: Extend the map implementation's handling of ?unitHans Bolinder
The Maps implementation handles ?unit in more cases. Exactly when t_is_none_or_unit() is to be called is not clear to me. The added cases are about a map type being ?unit, but the key or the value of an association can also be ?unit, but that is not always checked.
2017-06-13dialyzer: Minor optimizationsHans Bolinder
Avoid some ETS-lookups. Marginal speed-ups.
2017-06-13dialyzer: Correct a mistakeHans Bolinder
The arguments of calls to a debug function are no longer evaluated.
2017-06-13dialyzer: Optimize by avoiding some table lookupsHans Bolinder
In typesig: do not look up the module's types unless it is necessary.
2017-06-09dialyzer: Improve handling of UnicodeHans Bolinder
2017-03-06Merge branch 'maint'Hans Bolinder
* maint: dialyzer: Improve a warning dialyzer: Fix a weird warning dialyzer: Fix an opaque bug dialyzer: Minor fix Conflicts: lib/dialyzer/src/dialyzer_dataflow.erl
2017-02-28dialyzer: Minor fixHans Bolinder
2017-02-06Merge branch 'hasse/dialyzer/memory_opt/OTP-14127'Hans Bolinder
* hasse/dialyzer/memory_opt/OTP-14127: dialyzer: Attempt to reduce memory consumption dialyzer: Do not spawn all workers at once dialyzer: Write PLT in subprocess dialyzer: Remove code for non-started workers dialyzer: Sort graphs topologically dialyzer: Compress some PLT tables dialyzer: Check return value of digrahp:add_edge() dialyzer: Use less memory for the PLT when analyzing typer: Fix a bug regarding the -T option dialyzer: Do not keep the code server's type info on the heap
2017-02-03Merge branch 'maint'Hans Bolinder
* maint: dialyzer: Fix a Dialyzer warning
2017-02-03dialyzer: Fix a Dialyzer warningHans Bolinder
2017-02-03dialyzer: Attempt to reduce memory consumptionHans Bolinder
The 'deps' field is reset when no longer used, which could possibly save some memory.
2017-02-03Merge branch 'maint'Hans Bolinder
* maint: dialyzer: Increase time limit for tests dialyzer: Optimize typesig dialyzer: Optimize evaluation of complex code dialyzer: Optimize collection of variables Conflicts: lib/dialyzer/src/dialyzer_typesig.erl
2017-02-01dialyzer: Optimize typesigHans Bolinder
dialyzer_typesig:traverse_scc() now resets the context for each element of the SCC. Since the results of traversing the elements are saved in the 'cmap' table, there is no need to create an SCC conjunction. For huge SCCs this saves quite some time: the lift_lists() function added one element at a time, which made the calculation of deps very slow.
2017-02-01dialyzer: Optimize evaluation of complex codeHans Bolinder
Improve the evaluation of long lists of constraints.
2017-01-12Merge branch 'maint'Hans Bolinder
* maint: dialyzer: Compact 'file' annotations in Core code dialyzer: Try to reduce memory usage dialyzer: Use less memory when translating contracts dialyzer: Use maps instaed of dict dialyzer: Use maps instead of dict for module contracts map dialyzer: Compress a few more ETS tables dialyzer: Optimize memory consumption dialyzer: Reduce memory consumption during 'remote' phase dialyzer: Update code for finding parallelism compiler: Do not spawn process when dialyzing dialyzer: Reduce ETS usage during the typesig phase dialyzer: Optimize graph condensation dialyzer: Do not send full PLTs as messages
2017-01-11dialyzer: Use maps instaed of dictHans Bolinder
2017-01-11dialyzer: Optimize memory consumptionHans Bolinder
Some SCC info is no longer cached. It reduces the peak memory consumption of workers during the typesig phase, and seems to cost very little time.
2016-11-23Correct copyright and license on dialyzer filesRichard Carlsson
2016-05-04dialyzer: Use maps instead of dictHans Bolinder
Optimization: A few dictionaries are maps instead of dicts.
2016-05-04dialyzer: Optimize the evaluation of SCC:s in module typesigHans Bolinder
The evaluation of a single SCC has been optimized. The parallelism when evaluating a single SCC has been removed.
2016-04-28dialyzer_typesig: Fix bad external typeMagnus Lång
28a4a5057ab9 mistakenly used the non-existing type cerl:tree() instead of cerl:cerl().
2016-04-28dialyzer: Fix another pattern literal bugMagnus Lång
dialyzer_typesig:traverse/3 would perform an unsafe optimisation when given a cons pattern that contained a map and could be folded into a literal with cerl:fold_literal/1. In this case, when traversing the map a type variable would be generated, but this variable would be dropped by the erl_types:t_cons/2 constructor by in turn calling t_sup(), producing the overapproximation any(). However, in this particular case, dialyzer_typesig:traverse/3 is not allowed to overapproximate, since its result is used in an EQ-constraint. Although erl_types:t_tuple/1 does not overapproximate like t_cons/2, which makes the bug unlikely to affect tuples too, the fix was nevertheless applied defensively to the case of tuples as well. Also, fix a bug where dialyzer_utils:refold_pattern/1 would generate syntax nodes with two {label, _} attributes.
2016-04-28dialyzer_typesig: Fix simplification bugMagnus Lång
mk_constraint_list/2 was simplifying (C OR TriviallyTrue) to (C), which is obviously wrong.
2016-04-28dialyzer: Unfold cerl patterns containing mapsMagnus Lång
Dialyzer relies heavily on the assumption that the type of a literal that is used as a pattern is the type of any value that can match that pattern. For maps, that is not true, and it was causing bad analysis results. A new help function dialyzer_utils:refold_pattern/1 identifies maps in literal patterns, and unfolds and labels them, allowing them to be properly analysed.
2016-04-28dialyzer_typesig: Add map supportMagnus Lång
2015-10-09Update DialyzerHans Bolinder
Record field types have been modified due to commit 8ce35b2: "Take out automatic insertion of 'undefined' from typed record fields".
2015-06-18Change license text to APLv2Bruce Yinhe
2015-05-05Fix a bug related to constraints generated for erlang:'*'/2Stavros Aronis
For Rst = A1 * A2, typesig for erlang:'*'/2 was constraining the arguments A1 and A2 in the 'reverse' direction by requiring that A2 is a subtype of Rst div A1, unless A1 is a hard zero. This is not correct: if for example both Rst and A1 are non_negative, such a constraint will first force A1 to be non-zero for the division to go through and then require A2 to be non_negative as non_negative div positive = non_negative, always (see commited test). In the fixed version, we are not constraining an argument if the other operand *may* be zero.
2015-03-10[dialyzer] Fix the conversion of forms to typesHans Bolinder
In particular fix handling of records.
2015-01-14dialyzer: Introduce module local suppression of warningsHans Bolinder
The -dialyzer() attribute can be used for suppressing warnings in a module by specifying functions or warning options. It can also be used for requesting warnings in a module.
2014-06-17[dialyzer] Fix handling of literal recordsHans Bolinder
This ticket is about records in Erlang code, and when to check the fields against the (optional) types given when defining records. Dialyzer operates on the Erlang Core format, where there are no trace of records. The fix implemented is a Real Hack: Given the new option 'dialyzer' erl_expand_records marks the line number of records in a way that is undone by v3_core, which in turn inserts annotations that can be recognized by Dialyzer.
2014-02-23Deprecate pre-defined built-in typesHans Bolinder
The types array(), dict(), digraph(), gb_set(), gb_tree(), queue(), set(), and tid() have been deprecated. They will be removed in OTP 18.0. Instead the types array:array(), dict:dict(), digraph:graph(), gb_set:set(), gb_tree:tree(), queue:queue(), sets:set(), and ets:tid() can be used. (Note: it has always been necessary to use ets:tid().) It is allowed in OTP 17.0 to locally re-define the types array(), dict(), and so on. New types array:array/1, dict:dict/2, gb_sets:set/1, gb_trees:tree/2, queue:queue/1, and sets:set/1 have been added.
2014-01-31Shut off a dialyzer unmatched return warningKostis Sagonas
Dialyzer does not like list comprehensions for which the result is not assigned to some variable (maybe anonymous). In this particular case, the comprehension, containing only a filter but no generator, was used to save some lines, but IMO this type of code, while "cute", is not so easy to comprehend.
2014-01-29dialyzer: Remove dead codeBjörn-Egil Dahlberg
2014-01-28dialyzer,hipe,stdlib: Add Maps understanding to DialyzerBjörn-Egil Dahlberg
2014-01-21[dialyzer] Re-work the handling of opaque typesHans Bolinder
It is now OK to inspect and modify the internals of opaque types within the scope of the module. The contracts are used for decorating types with opaqueness when it is harmless to do so. The opaqueness is propagated by the typesig module and also by the dataflow module. A lot of details have been fixed or updated. In particular the modules erl_types and erl_bif_types have been modified extensively. The version in vsn.mk has been updated to 2.7. The reason is a modification of #opaque{} in erl_types. Dialyzer seems to be about five percent slower than it used to be.
2013-04-08Minor refactoringsStavros Aronis
2013-04-08Fix an error in the type inference of bitstring dataStavros Aronis
Dialyzer was constraining bitstring data used in the construction of other bitstring values too much. These constraints have now been relaxed.
2013-02-22Update copyright yearsBjörn-Egil Dahlberg
2013-02-20Merge branch 'ks/dialyzer-R16B-final-fixes/OTP-10865'Fredrik Gustafsson
* ks/dialyzer-R16B-final-fixes/OTP-10865: Native code compilation changes Code simplification Simplify a case construct using inequality Simplify a case construct using a boolean operator Code simplifications + take out obsolete note
2013-02-19Code simplificationKostis Sagonas
2013-02-15Minor refactoringStavros Aronis
2012-08-21Add an undocumented option [--solver [v1 | v2]]Hans Bolinder
The original implementation of the type signature solver is called 'v1' and the newly introduced alternative implementation is called 'v2'. It is possible to run just the one of the solvers (in case there is a bug in for instance the v2 implementation) or both solvers ("--solver v1 --solver v2"). In the latter case an error is thrown if the outcome differ.
2012-08-21Add an alternative implmentation of the typesignature solverHans Bolinder
An alternative implementation of the solver in dialyzer_typesig has been introduced. It is faster than the original implementation. Note: there is code for "loop detection". Where a loop occurs, the evaluation is stopped and the current solution returned. This behaviour is consistent with how the original implementation works. There are a few known cases where the loop detection kicks in. They are due to bugs which will hopefully be fixed in a near future.
2012-06-01Bug fixes and improvements of dialyzer_typesigHans Bolinder
1. Sometimes the solver forgot that a list had entered the error state. The bug has been fixed by storing the atom 'error' in MapDict. An example where the bug occurred is io_lib_pretty:printable_bin(). The returned spec was weaker than it should have been, but the fix-point loop hid the bug (in this case). 2. lists:partition() has been substituted for lists:splitwith() in enumerate_constraints(). This fix together with 3. solves a problem with long execution times for deeply nested fun:s. An example which is now much faster is lib/compiler/test/lc_SUITE:deeply_nested/1 (included as dialyzer/test/small_SUITE_data/src/deep_lc.erl). 3. The calculation of components in enumerate_constraints() has been simplified and optimized. The important thing here is that _all_ of the simple constraints have been saturated before entering the complex part. 4. The pretty printing of constraints has been improved.
2012-05-21Regulate all kinds of running workers up to the number of schedulersStavros Aronis