mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-17 06:47:17 +00:00
Estimated hours taken: 16
Branches: main
Give the compiler the capability of detecting errors that manifest themselves
as mismatches between the format string and the list of values to be printed
in calls to string.format and io.format.
This capability is controlled through two new options:
--warn-known-bad-format-calls
--warn-unknown-format-calls
The first (which will default to "on" once this change has bootstrapped)
controls whether the compiler emits warnings for statically known mismatches.
The second (which will default to "off") controls whether the compiler emits
warnings in cases where either the format string or the structure of the list
of values to be printed is not available statically to be checked.
NEWS:
Mention the new capability.
compiler/options.m:
Add the two new options.
doc/user_guide.texi:
Document the new options.
compiler/format_call.m:
New module to implement the new capability.
compiler/notes/compiler_structure.html:
Document the new module.
compiler/check_hlds.m:
Include the new module.
compiler/simplify.m:
Invoke the new module if the procedure being processed contains calls
to string.format or io.format.
Fix an old bug: we could generate warnings or even errors when
simplifying predicate bodies imported from other modules via
intermodule optimization.
Don't export get/set predicates that do not need to be exported.
compiler/det_report.m:
Add new kinds of error specifications for the errors detected by the
new module.
Separate out the context of each error specification, in order
to allow the error messages to be sorted by context; this makes
the output much easier to read.
compiler/common.m:
compiler/det_analysis.m:
compiler/simplify.m:
Conform to the change to det_report.m.
mdbcomp/prim_data.m:
Add a utility function for forming the possibly qualified names of
library modules (such as "io" and "string").
library/Mercury.options:
compiler/Mercury.options:
Add the lines that disable the new checks in the modules that need them
disabled. The new lines are commented out until installed compilers all
understand them, at which point in time we will add the requirement to
understand the option to configure.in.
compiler/fact_table.m:
compiler/mlds_to_il.m:
Fix three bugs reported by the new check that have apparently escaped
detection all this time.
library/rtti_implementation.m:
Change some code to avoid a spurious warning from the new checks.
library/string.m:
Rename a predicate to avoid an unnecessary and confusing overloading of
its name.
Replace __ with . as module qualifier connective.
compiler/handle_options.m:
library/pprint.m:
Misc cleanups.
tests/invalid/string_format_bad.{m,err_exp}:
tests/invalid/string_format_unknown.{m,err_exp}:
New test cases to test the new warnings.
tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
Enable the new test cases.
tests/general/string_format_test*.exp*:
Update any expected abort messages to expect . instead of __ as module
qualifier connective.
tests/invalid/det_errors_cc.err_exp:
tests/invalid/erroneous_throw_promise.err_exp:
tests/warnings/simple_code.exp:
Expect the same error messages in program context order.
63 lines
1.3 KiB
Mathematica
63 lines
1.3 KiB
Mathematica
% vim: ts=4 sw=4 expandtab ft=mercury
|
|
|
|
:- module string_format_bad.
|
|
|
|
:- interface.
|
|
|
|
:- import_module io.
|
|
|
|
:- pred main(io::di, io::uo) is det.
|
|
|
|
:- implementation.
|
|
|
|
:- import_module bool.
|
|
:- import_module float.
|
|
:- import_module int.
|
|
:- import_module list.
|
|
:- import_module string.
|
|
|
|
main(!IO) :-
|
|
S1 = string.format("", [s("x1")]),
|
|
io.write_string(S1, !IO),
|
|
S2 = string.format("%d", [s("x2")]),
|
|
io.write_string(S2, !IO),
|
|
io.stdout_stream(OutputStream, !IO),
|
|
io.format("%d", [s("x3")], !IO),
|
|
io.format(OutputStream, "%d", [s("x4")], !IO),
|
|
io.format("%w", [i(5)], !IO),
|
|
io.write_string(p(s("five")), !IO),
|
|
F6 = "%s %f",
|
|
make_bool(6, T6),
|
|
(
|
|
T6 = yes,
|
|
V6A = i(6)
|
|
->
|
|
V6 = [s("six"), V6A],
|
|
io.format(OutputStream, F6, V6, !IO),
|
|
make_bool(7, T7),
|
|
F7 = "%d %s %d",
|
|
(
|
|
T7 = yes,
|
|
io.format(OutputStream, F7, [f(7.0) | V6], !IO)
|
|
;
|
|
T7 = no
|
|
)
|
|
;
|
|
true
|
|
).
|
|
|
|
:- pred make_bool(int::in, bool::out) is det.
|
|
|
|
make_bool(_, yes).
|
|
|
|
:- func t(string) = string.
|
|
|
|
t(S) = S.
|
|
|
|
:- func p(string.poly_type) = string.
|
|
|
|
p(s(S)) = t(string.format("%s", [s(S)])).
|
|
p(c(C)) = t(string.format("%c", [c(C)])).
|
|
p(i(I)) = t(string.format("%d", [i(I)])).
|
|
p(f(F)) = t(string.format("%f", [f(F)])).
|