mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-18 02:43:40 +00:00
bdabaf5dc94de3b405d11e2db71d34932224b6ff
11 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
cb1da20600 |
Stop ancestor imports "shadowing" unused local imports.
compiler/make_hlds_passes.m:
We used to add all modules imported by an ancestor of the current module
to the set of used modules. Once upon a time, this was meant to stop
the compiler generating misleading warnings about imports being unused
when the import wasn't even done by the current module. However, since
we introduced structured representations of import- and use_module
declarations and taught unused_imports.m to use them, that has not been
an issue. However, a bad side-effect remained, which was that if
a module A imported a module B but did not use it, or it imported
module B in its interface but did not use in its interface, then
any warning we could generate about that import being unused was
suppressed by any import of module B in any of module A's ancestors.
(The "shadowing" mentioned above.)
Fix the problem by adding modules imported by ancestors of the
current module NOT to the set of used modules, but to a new field
in the module_info.
compiler/hlds_module.m:
Add this new field. As it happens, it is not needed right now,
but it may be needed later.
Update some documentation.
Note an only-tangentially-related problem.
compiler/unused_imports.m:
Fix a bug that was hiding behind the shadowing, which was that whether
the text of the warning message we generated for an unused local import-
or use_module declaration could be affected by the presence of an
import- or use_module declaration in an ancestor module.
Improve debugging infrastructure.
Make a predicate name more descriptive.
NEWS:
Announce the bugfix.
compiler/add_pragma_tabling.m:
compiler/add_solver.m:
compiler/add_type.m:
compiler/parse_string_format.m:
compiler/recompilation.usage.m:
compiler/recompilation.used_file.m:
library/io.call_system.m:
library/io.text_read.m:
library/random.sfc32.m:
library/random.sfc64.m:
library/random.system_rng.m:
library/string.parse_runtime.m:
library/string.parse_util.m:
library/string.to_string.m:
library/thread.closeable_channel.m:
mdbcomp/feedback.automatic_parallelism.m:
Delete imports that the fixed compiler now generates unused import
warnings for.
|
||
|
|
06f81f1cf0 |
Add end_module declarations ...
.. to modules which did not yet have them. |
||
|
|
d4861d739d |
Allow formatting of sized integers.
library/string.m:
Add {i,u}{8.16,32,64} as function symbols in the poly_type type,
each with a single argument containing an integer with the named
signedness and size.
The idea is that each of these poly_type values works exactly
the same way as the i(_) poly_type (if signed) or the u(_) poly_type
(if unsigned), with the exception that the value specified by the call
is cast to int or uint before being processed.
library/string.parse_runtime.m:
Parse the new kinds of poly_types. Change the representation of the result
of the parsing to allow recording of the sizes of ints and uints.
Put the code that does the parsing into a predicate of its own.
library/string.format.m:
Do a cast to int or uint if the size information recorded in the
specification of a signed or unsigned integer value calls for it.
Provide functions to do the casting that do not require the import
of {int,uint}{8,16,32,64}.m. This is to allow the compiler to generate
calls to do such casts without having to implicitly import those modules.
Abort if a 64 bit number is being cast to a 32 bit word.
compiler/parse_string_format.m:
Make the same changes as in string.parse_runtime.m, mutatis mutandis.
compiler/format_call.m:
Handle the new kinds of poly_types by adding a cast to int or uint
if necessary, using the predicates added to library/string.format.m.
Use a convenience function to make code creating instmap deltas
more readable.
library/io.m:
library/pprint.m:
library/string.parse_util.m:
tests/invalid/string_format_bad.m:
tests/invalid/string_format_unknown.m:
Conform to the changes above.
tests/string_format/string_format_d.m:
tests/string_format/string_format_u.m:
Test the printing of some of the new poly_types.
tests/string_format/string_format_d.exp2:
tests/string_format/string_format_u.exp2:
Update the expected output of these tests on 64-bit platforms.
tests/string_format/string_format_lib.m:
Update programming style.
|
||
|
|
f697c69d13 |
Improve specifier/polytype mismatch messages.
library/string.parse_util.m:
When we find a mismatch between a format specifier char and the
corresponding polytype, list the specifier chars that are applicable
to the given polytype.
tests/invalid/string_format_bad.err_exp:
tests/invalid/string_format_unknown.err_exp:
Update the expected mismatch messages.
|
||
|
|
9528f326d2 |
Formatting of uints using string.format etc.
Extend the operations that perform formatted conversion, such as string.format/2, to be able to handle values of type uint directly. We have always supported formatting values of type int as unsigned values, but currently the only way to format uint values is by explicitly casting them to an int. This addresses Mantis issue #502. library/string.m: Add a new alternative to the poly_type/0 type that wraps uint values. Update the documentation for string.format. uint values may now be formatted using the u, x, X, o or p conversion specifiers. library/string.format.m: Add the necessary machinery for handling formatting of uint values. library/string.parse_runtime.m: library/string.parse_util.m: Handle uint poly_types. library/io.m:a Handle uint values in the write_many predicates. library/pprint.m: Handle uint values in the poly/1 function. compiler/format_call.m: compiler/parse_string_format.m: Conform to the above changes. compiler/options.m: Add a way to detect if a compiler supports this change. NEWS: Announce the above changes. tests/hard_coded/stream_format.{m,exp}: Extend this test to cover uints. tests/invalid/string_format_bad.m: tests/invalid/string_format_unknown.m: Conform to the above changes. tests/string_format/Mmakefile: tests/string_format/string_format_uint_o.{m,exp,exp2}: tests/string_format/string_format_uint_u.{m,exp,exp2}: tests/string_format/string_format_uint_x.{m,exp,exp2}: Add tests of string.format with uints. |
||
|
|
5f63c4ce0d | Delete unused imports. | ||
|
|
ae4b736fdd |
Implement warnings for suspicious recursion.
compiler/simplify_goal_call.m:
If the --warn-suspicious-recursion option is set, and if the warning
isn't disabled, generate warnings for two different kinds of suspicious
recursion. They are both related to, but separate from, the warning
we have long generated for infinite recursion, which occurs when
the input args of a recursive call are the same as the corresponding
args in the clause head.
Both kinds suspicious recursion look at the input args of a recursive call
that are NOT the same as the corresponding args in the clause head.
Both require these args to have non-unique modes. (If they have unique
modes, then the depth of the recursion may be controlled by state outside
the view of the Mercury compiler, which means that a warning would be
likely to be misleading.)
The first kind is when all these args use state variable notation.
Most of the time, we use state var notation to denote the data structures
updated by the recursive code; having variables using such notation
*controlling* the recursion is much less common, and much more likely
to be unintended. The motivation for the new option was this infinitely
looping code, which resulted from neglecting to s/[X | Xs]/Xs/ after
cutting-and-pasting the clause head to the recursive call.
p([X | Xs], !S) :-
...,
p([X | Xs], !S).
The other kind of suspicious recursive call we warn about involve
input arguments where the base names of the input arguments (the part
before any numeric suffixes) seem be switched between the clause head
and the recursive call, as here:
q(As0, Bs0, ...) :-
...,
q(Bs1, As, ...).
compiler/mercury_compile_main.m:
Disable style warnings when invoked with --make-optimization-interface
or its transitive variant. Without this, warnings about suspicious
recursion would get reported in such invocations.
Move a test from a callee to a caller to allow the callee to be
less indented.
compiler/options.m:
Export functionality to mercury_compile_main.m to make the above possible.
library/string.m:
Add a predicate to convert a string to *reverse* char list directly.
Note a discrepancy between the documentation and the implementation
of the old predicate the new one is based on (which converts a string
to a forward char list).
NEWS:
Note the new predicate in string.m.
compiler/cse_detection.m:
compiler/ctgc.selector.m:
compiler/dead_proc_elim.m:
compiler/deforest.m:
compiler/dep_par_conj.m:
compiler/det_analysis.m:
compiler/distance_granularity.m:
compiler/frameopt.m:
compiler/inst_util.m:
compiler/lp_rational.m:
compiler/matching.m:
compiler/modes.m:
compiler/old_type_constraints.m:
compiler/rbmm.points_to_analysis.m:
compiler/rbmm.region_arguments.m:
compiler/recompilation.usage.m:
compiler/stratify.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.indirect.m:
compiler/typeclasses.m:
compiler/use_local_vars.m:
deep_profiler/callgraph.m:
deep_profiler/canonical.m:
library/bit_buffer.read.m:
library/bit_buffer.write.m:
library/calendar.m:
library/diet.m:
library/lexer.m:
library/parser.m:
library/parsing_utils.m:
library/ranges.m:
library/set_ctree234.m:
library/set_tree234.m:
library/string.parse_util.m:
library/tree234.m:
library/varset.m:
mdbcomp/program_representation.m:
mdbcomp/rtti_access.m:
profiler/demangle.m:
Avoid warnings for suspicious recursion. In most cases, do this by
wrapping disable_warning scopes around the affected recursive calls;
in a few cases, do this by changing the code.
tests/warnings/suspicious_recursion.{m,exp}:
A test case for the new warnings.
tests/warnings/Mercury.options:
tests/warnings/Mmakefile:
Enable the new test case.
|
||
|
|
d465fa53cb |
Update the COPYING.LIB file and references to it.
Discussion of these changes can be found on the Mercury developers
mailing list archives from June 2018.
COPYING.LIB:
Add a special linking exception to the LGPL.
*:
Update references to COPYING.LIB.
Clean up some minor errors that have accumulated in copyright
messages.
|
||
|
|
62ec97d443 |
Report imports shadowed by other imports.
If a module has two or more import_module or use_module declarations
for the same module, (typically, but not always, one being in its interface
and one in its implementation), generate an informational message about
each redundant declaration if --warn-unused-imports is enabled.
compiler/hlds_module.m:
We used to record the set of imported/used modules, and the set of
modules imported/used in the interface of the current module. However,
these sets
- did not record the distinction between imports and uses;
- did not allow distinction between single and multiple imports/uses;
- did not record the locations of the imports/uses.
The first distinction was needed only by module_qual.m, which *did*
pay attention to it; the other two were not needed at all.
To generate messages for imports/uses shadowing other imports/uses,
we need all three, so change the data structure storing such information
for *direct* imports to one that records all three of the above kinds
of information. (For imports made by read-in interface and optimization
files, the old set of modules approach is fine, and this diff leaves
the set of thus *indirectly* imported module names alone.)
compiler/unused_imports.m:
Use the extra information now available to generate a
severity_informational message about any import or use that is made
redundant by an earlier, more general import or use.
Fix two bugs in the code that generated warnings for just plain unused
modules.
(1) It did not consider that a use of the builtin type char justified
an import of char.m, but without that import, the type is not visible.
(2) It scanned cons_ids in goals in procedure bodies, but did not scan
cons_ids that have been put into the const_struct_db. (I did not update
the code here when I added the const_struct_db.)
Also, add a (hopefully temporary) workaround for a bug in
make_hlds_passes.m, which is noted below.
However, there are at least three problems that prevent us from enabling
--warn-unused-imports by default.
(1) In some places, the import of a module is used only by clauses for
a predicate that also has foreign procs. When compiled in a grade that
selects one of those foreign_procs as the implementation of the predicate,
the clauses are discarded *without* being added to the HLDS at all.
This leads unused_imports.m to generate an uncalled-for warning in such
cases. To fix this, we would need to preserve the Mercury clauses for
*all* predicates, even those with foreign procs, and do all the semantic
checks on them before throwing them away. (I tried to do this once, and
failed, but the task should be easier after the item list change.)
(2) We have two pieces of code to generate import warnings. The one in
unused_imports.m operates on the HLDS after type and mode checking,
while module_qual.m operates on the parse tree before the creation of
the HLDS. The former is more powerful, since it knows e.g. what types and
modes are used in the bodies of predicates, and hence can generate warnings
about an import being unused *anywhere* in a module, as opposed to just
unused in its interface.
If --warn-unused-imports is enabled, we will get two separate set of
reports about an interface import being unused in the interface,
*unless* we get a type or mode error, in which case unused_imports.m
won't be invoked. But in case we do get such errors, we don't want to
throw away the warnings from module_qual.m. We could store them and
throw them away only after we know we won't need them, or just get
the two modules to generate identical error_specs for each warning,
so that the sort_and_remove_dups of the error specs will do the
throwing away for us for free, if we get that far.
(3) The valid/bug100.m test case was added as a regression test for a bug
that was fixed in module_qual.m. However the bug is still present in
unused_imports.m.
compiler/make_hlds_passes.m:
Give hlds_module.m the extra information it now needs for each item_avail.
Add an XXX for a bug that cannot be fixed right now: the setting of
the status of abstract instances to abstract_imported. (The "abstract"
part is correct; the "imported" part may not be.)
compiler/intermod.m:
compiler/try_expand.m:
compiler/xml_documentation.m:
Conform to the change in hlds_module.m.
compiler/module_qual.m:
Update the documentation of the relationship of this module
with unused_imports.m.
compiler/hlds_data.m:
Document a problem with the status of instance definitions.
compiler/hlds_out_module.m:
Update the code that prints out the module_info to conform to the change
to hlds_module.m.
Print status information about instances, which was needed to diagnose
one of the bugs in unused_imports.m. Format the output for instances
nicer.
compiler/prog_item.m:
Add a convenience predicate.
compiler/prog_data.m:
Remove a type synonym that makes things harder to understand, not easier.
compiler/modules.m:
Delete an XXX that asks for the feature this diff implements.
Add another XXX about how that feature could be improved.
compiler/Mercury.options.m:
Add some more modules to the list of modules on which the compiler
should be invoked with --no-warn-unused-imports.
compiler/*.m:
library/*.m:
mdbcomp/*.m:
browser/*.m:
deep_profiler/*.m:
mfilterjavac/*.m:
Delete unneeded imports. Many of these shadow other imports, and some
are just plain unneeded, as shown by --warn-unused-imports. In a few
modules, there were a *lot* of unneeded imports, but most had just
one or two.
In a few cases, removing an import from a module, because it *itself*
does not need it, required adding that same import to those of its
submodules which *do* need it.
In a few cases, conform to other changes above.
tests/invalid/Mercury.options:
Test the generation of messages about import shadowing on the existing
import_in_parent.m test case (although it was also tested very thoroughly
when giving me the information needed for the deletion of all the
unneeded imports above).
tests/*/*.{m,*exp}:
Delete unneeded imports, and update any expected error messages
to expect the now-smaller line numbers.
|
||
|
|
37d20a771a | Fix spaces in an error message. | ||
|
|
a9208b47a8 |
Specialize ALL calls to string.format and io.format.
Previously, we specialized calls to string.format and io.format only if
the format string specified no flags, widths, precisions or non-default
bases for any conversion. We now specialize calls to those predicates
regardless of the format string. To make this possible, we now have two
copies of the code to parse format strings.
library/string.parse_runtime.m:
This new module, carved out out library/string.format.m, contains
one of those copies. As the name suggests, this copy is used by
the runtime system.
compiler/parse_string_format.m:
This new module contains the other copy. As its location suggests,
this copy is used by the compiler. The separate copy is necessary
because the compiler's parsing needs are different from the runtime's.
The main reason for the separation is that the compiler needs to be
able to handle cases where widths and predicates are given by manifest
constants, as well as when they are given by the values of variables
at runtime (when the format string contains conversion specifiers
such as "%*d"). Having the runtime handle this extra complexity
would have inevitably increased the runtime's format string interpretation
overhead, which is undesirable.
The other reason is that compiler can afford to postprocess the result
of the parsing in order to avoid having to concatenate two or more
constant strings at runtime.
library/string.parse_util.m:
Types and predicates that are common to the library and compiler copies
of the format string parsing code.
compiler/format_call.m:
We used to check whether format strings match the supplied list
of values to be printed by invoking string.format on dummy inputs
of the supplied types, and seeing whether you got an exception.
We now call parse_string_format.m instead. Not only does this
avoid shenanigans with exceptions (which the deep profiler cannot
yet handle), but it also allows us to specialize all calls
to string.format and io.format. We therefore do so.
We used to specialize calls to io.format by creating a single string
to be printed (using the machinery needed to specialize calls to
string.format), and then printing that. This did unnecessary memory
allocations to hold the intermediate strings. We now simply print
each component one after the other, which avoids this overhead.
library/string.format.m:
Add versions of the predicates that print chars, strings, ints and floats
that are specialized to each possible situation about whether the caller
specifies a width and/or a precision. This means that format_call.m
doesn't have to generate code that allocates cells on the heap.
Remove the code that was moved to new submodules of string.m.
compiler/simplify_proc.m:
List the predicates in string.format.m that the compiler
may generate calls to in the list of such predicates that we maintain
to prevent dead_pred_elim from deleting them before format_call.m
gets a chance to do its work.
compiler/module_imports.m:
If the code of the module calls a predicate named "format" that
may refer to string.format or io.format, then implicitly import
the modules that contain the types and predicates that the code
generated by format_call.m will refer to. Note that since this
module_imports.m works on Mercury code that has not been module
qualified yet, we have to use a conservative approximation.
Reorganize the way we discover what library modules we have to
implicitly import. Instead of a separate boolean for each piece
of functionality that needs an implicit import, put them together
into a structure. Due to Peter's work on argument packing some
years back, this is now more efficient as well as more convenient
that passing around a bunch of booleans. Also switch to passing
around the structure as an accumulator, instead of having to do
bool.ors all over the place.
Since the code for computing the list of modules to be implicitly
imported can sometimes add a library module to the list twice,
sort that list and remove any duplicates.
To make this possible, remove the version of the main predicate
that appends the implicitly imported module names to a list of
module names passed by our caller, since we don't want to sort
THAT list of module names.
Give the remaining version of that predicate that does this
a name that better matches the names of related predicates.
compiler/modules.m:
Conform to the change in module_imports.m. Mark some suspicious code
with XXXs.
Remove some redundant comments.
compiler/options.m:
doc/user_guide.texi:
Add a new option that tells format_call.m what it should do
when it finds more than one problem with a format string: whether
it should print a message only for the first problem, or for all
the problems. (The default is the latter.)
library/MODULES_DOC:
A list of the all the Mercury source files in the library that
should be included in the user guide.
library/MODULES_UNDOC:
A list of the all the Mercury source files in the library that
should NOT be included in the user guide.
library/library.m:
Include the new publicly visible new submodule of string.m,
(string.parse_util). And both string.parse_util and string.parse_runtime
(which is NOT visible from outside string.m) to the list of modules
in the Mercury standard library.
Update the rules for where new library modules should be documented
to account for non-publically-visible submodules, which we haven't had
before. Document the need to include new modules in either MODULES_DOC
or MODULES_UNDOC.
mdbcomp/builtin_modules.m:
Provide convenient access for format_call.m to the names of the
submodules of string.m that it needs access to.
library/Mmakefile:
Add a new target, check_doc_undoc, which checks whether any source files
are missing from MODULES_DOC or MODULES_UNDOC.
doc/Mmakefile:
Read the list of modules to be documented from MODULES_DOC. This replaces
old code that tried to list all the undocumented modules, but missed one:
it referred to erlang_conf.m instead of erlang_builtin.m.
When creating the library documentation, filter out any lines that
contain the string NOTE_TO_IMPLEMENTORS. We now use this mechanism
to include reminders to implementors in what would otherwise be a
publically visible part of string.m.
tools/bootcheck:
Copy MODULES_DOC and MODULES_UNDOC to the stage 2 and 3 library
directories, since the check_doc_undoc target, which is invoked by
"make all" in the library directory, needs them.
compiler/hlds_out_module.m:
When dumping out the table of types, dump out discriminated union types
in a style that follows our recommended coding style.
|