Commit Graph

236 Commits

Author SHA1 Message Date
Zoltan Somogyi
713d541ada Small improvements in the code simplifying calls.
compiler/const_prop.m:
    Replace pairs and maybes with a semantically meaningful type.
    Restrict this type to the part we actually use.

    Optimize ubits_per_{int,uint} the same way we have long optimized
    bits_per_{int,uint}.

compiler/simplify_goal_call.m:
    Improve the wording of some warnings.

    When constructing those warnings, don't test the value of warn_simple_code
    twice.

compiler/uint_emu.m:
    Fix copy-and-paste typo.

tests/warnings/unsigned_zero_cmp.exp:
    Expect the updated text of the above warnings.
2023-04-17 17:35:25 +10:00
Julien Fischer
d04742542c Test format_call pragmas with multi-moded predicates.
tests/warnings/Mmakefile:
tests/warnings/format_call_multi.{m,exp}:
tests/warnings/m12.m:
     As above.
2023-01-08 16:09:28 +11:00
Zoltan Somogyi
50c3301737 Simplify some code in error_util.m.
compiler/error_util.m:
    Interpret each context just once per error_msg, not once per line.

    Add the fixed indent after the context, creating a prefix string,
    just once per error_msg, not once per line.

    Compute the length of the prefix directly from the prefix string,
    instead of counting the characters that go into its components.

    Don't print out the line-specific indent on blank lines.

    Replace a quadratic algorithm with a linear one.

    For each line we output, record the total length of its words,
    and the total length available for those words. This prepares
    for a future change that will try to replace several lines, even if
    they ended with "nl" pieces, with one,

    - if the result fits in the available space, and
    - if the text of the lines indicates this is desirable.

compiler/hlds_out_util.m:
compiler/prog_out.m:
    Move the code for writing out indents from hlds_out_util.m to prog_out.m.
    We now want to call it from error_util.m, and it does not depend on the
    HLDS at all.

tests/invalid/anys_in_negated_contexts.err_exp:
tests/invalid/ho_default_func_1.err_exp:
tests/invalid/ho_default_func_3.err_exp:
tests/invalid/ho_type_mode_bug.err_exp:
tests/invalid/modes_erroneous.err_exp:
tests/invalid_nodepend/errors2.err_exp:
tests/warnings/inconsistent_pred_order.exp:
tests/warnings/subtype_order.exp:
    Don't expect the line-specific indent on blank lines.
2022-10-12 15:34:49 +11:00
Julien Fischer
a685cdccba Fix a failing test.
tests/warnings/format_call_warning_helper.m:
    Add a missing module import.
2022-09-25 00:42:44 +10:00
Zoltan Somogyi
66873a528a Fix the handling of status in add_pragma.m.
compiler/add_pragma.m:
    The status checks in this module used to check for only one
    of the four possible combinations of <is pragma exported, is the
    pred the pragma is for expored>, even though we may want to generate
    errors or warnings in three of those combinations. Fix this.

    If an ambiguous pragma applies to more than one predicate, handle
    the status checks of each separately.

    When adding fact table pragmas to the HLDS, replace several lines
    of code that reuse an existing largish predicate with the single line
    of code from that predicate that we actually need.

    Stop representing the statuses of pragmas using the pred_status type,
    since the item_mercury_status that all items come with is adequate
    for all our needs, and is impossible to confuse with the status
    of the pred_info they refer to.

library/exception.m:
library/require.m:
    Move termination pragmas for exported predicates and functions
    from the implementation section to the interface section. This
    avoids a warning that we now generate in such situations.

tests/term/exception_analysis_test.trans_opt_exp:
tests/term/exception_analysis_test2.trans_opt_exp:
    Expected improved termination analysis results now that we export
    termination pragmas that used to be kept private.

tests/warnings/foreign_term_invalid.{m,exp}:
    Avoid warnings about keeping decl pragmas about exported predicates
    private by moving them into the interface.

    Fix the formatting of the top-of-module comment.

    Expect updated line numbers.

tests/warnings/pragma_term_conflict.{m,exp}:
    Don't avoid a warning about keeping decl pragmas about exported predicates
    private. Instead, document it as an additional purpose of this test.

    Expect both the extra warning and updated line numbers.

tests/invalid/pragma_export.{m,err_exp}:
    A new test case for testing the error message for inappropriately
    exported pragmas.

tests/invalid/Mmakefile:
    Enable the new test case.
2022-09-24 19:12:18 +10:00
Zoltan Somogyi
a32d6a16f4 Add the format_call pragma to the language.
doc/reference_manual.texi:
NEWS:
    Document and announce the new pragma.

compiler/prog_data_pragma.m:
compiler/prog_item.m:
    Provide a representation for the new pragma. The part that ends up
    being referred to from the HLDS goes into prog_data_pragma.m,
    the part that is not needed once the HLDS has been constructed
    goes into prog_item.m.

compiler/hlds_pred.m:
    Add a slot to pred_infos for info from the new pragma.

    Fix a bug in the comment on marker_has_format_call.

compiler/add_pragma.m:
    Add the information in these pragmas to the HLDS.

compiler/check_pragma_format_call.m:
    A new module to check the validity of format_call pragmas.
    These checks test whether the arguments named in such pragmas
    have the expected types and modes, which means that
    the check must be done after both type and mode checking.

compiler/check_hlds.m:
compiler/notes/compiler_design.html:
    Add and document the new module.

compiler/hlds_module.m:
    Add a field to the module_info that records the set of pred_ids
    that have format_call pragmas.

compiler/mercury_compile_front_end.m:
    Invoke the check_pragma_format_call pass *provided* that
    the new field in the module_info says it has any pragmas to check.

compiler/parse_pragma.m:
    Add code to parse the new pragma.

compiler/format_call.m:
    Check calls to predicates and functions with the new pragma
    the same way as we check calls to string.format, io.format,
    and stream.string_writer.format.

    This required separating the code that checked calls to such predicates
    from the code that optimized calls to such predicates, since

    - a predicate or function with a format_call pragma that specifies
      more than one argument pair has to have its correctness checked
      for each pair, and

    - a predicate or function with a format_call pragma does not actually
      do any formatting, so that formatting cannot be optimized.

    Fix an old bug, where we included the function result in the function's
    reported arity, which meant that an error message could mention a call
    to a nonexistent function. As part of that fix, the error message
    now specifies whether it is complaining about a call to a predicate
    or a function.

    Change the exported interface of this module a bit
    in order to allow the factoring out of repeated code.

compiler/parse_string_format.m:
    Separate the parsing of format strings from their optimization,
    again because calls to predicates and functions with format_call
    pragmas need to be checked but cannot be optimized.

compiler/polymorphism.m:
    Record the effect on argument numbers of any type_info and/or
    typeclass_info arguments added by this pass.

compiler/convert_parse_tree.m:
compiler/det_analysis.m:
compiler/direct_arg_in_out.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/hlds_out_pred.m:
compiler/item_util.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out_pragma.m:
compiler/prog_item_stats.m:
compiler/recompilation.version.m:
compiler/simplify_proc.m:
    Conform to the changes above.

tests/invalid/bad_format_call.{m,err_exp}:
    A new test case to see whether check_pragma_format_call.m detects
    and reports invalid format_call pragmas as expected.

tests/warnings/format_call_warning.{m,exp}:
tests/warnings/format_call_warning_helper.m:
    A new test case to see whether we generate the expected set of error
    messages for incorrect calls to a predicate with a format_call pragma.

tests/invalid/Mmakefile:
tests/warnings/Mercury.options:
tests/warnings/Mmakefile:
    Enable the new test cases.

tests/invalid/string_format_bad.err_exp:
tests/invalid/string_format_unknown.err_exp:
tests/warnings/disabled_warning.exp:
    Expect the predicate vs function distinction to the printed in
    error messages about bad calls to formatting predicates and functions.
2022-09-24 08:42:36 +10:00
Zoltan Somogyi
47ca4f9a66 Let disable_warning apply to unknown_format_calls.
doc/reference_manual.texi:
NEWS:
    Allow a disable_warning scope to override the setting of the
    --warn-unknown-format-calls option to "yes" inside its scope.

compiler/prog_data.m:
    Provide a representation for the new kind of disable-able warning.

compiler/parse_goal.m:
    Parse the new kind of disable-able warning.

compiler/prog_out.m:
    Print out the new kind of disable-able warning.

compiler/format_call.m:
    Add a parameter to the format checking code to control whether
    we generate this warning. Using this parameter yields clearer code
    that locally overriding the value of the option.

compiler/simplify_goal_scope.m:
    Ignore the new kind of disable-able warning in code that has nothing
    to do with it.

compiler/options.m:
doc/user_guide.texi:
    Fix an old issue: include stream.string_writer.format in the description
    of --warn-unknown-format-calls.

tests/warnings/disabled_warning.{m,exp}:
    Add a test of the new functionality.

tests/warnings/Mmakefile:
tests/warnings/Mercury.options:
    Enable the new test case.
2022-08-24 16:33:46 +10:00
Julien Fischer
f3a34e4651 Replace uses of __ as a module qualifier.
samples/muz.zbstract.m:
tests/*/*.m:
    As above.
2022-04-14 20:25:10 +10:00
Julien Fischer
99cd93dcfb Shift some tests.
The tests below are not actually invalid, they cause the compiler to emit only
warnings and properly belong in the warnings directory.

tests/invalid/empty_interface.{m,err_exp}:
tests/invalid/foreign_singleton.{m,err_exp}:
tests/invalid/obsolete_proc_pragma.{m,err_exp}:
     Shift these tests into the warnings directory and use the
     appropriate extension for expected outputs in that directory

tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
tests/warnings/Mercury.options:
tests/warnings/Mmakefile:
     Conform to the above changes.
2022-04-14 16:13:37 +10:00
Zoltan Somogyi
0186a64520 Warn for unneeded use of mode-specific clauses.
compiler/add_clause.m:
    Generate a warning for mode-specific clauses when the clause is for
    a predicate that has only one mode, provided that the warning is enabled.

compiler/options.m:
    Add an option to enable this warning.

doc/user_guide.texi:
    Document this option.

library/exception.m:
library/int.m:
library/rtti_implementation.m:
library/string.m:
    Delete modes from clause heads that would get this warning.

tests/valid/spurious_purity_warning.m:
    Delete modes from clause heads that would get this warning.

    Do not interleave predicate definitions.

tests/warnings/unneeded_mode_specific_clause.{m,exp}:
    A test case for this warning.
tests/warnings/Mmakefile:
    Enable the new test case.

tests/invalid/multimode_syntax.err_exp:
    Expect the new warning.
2022-04-13 23:39:23 +10:00
Zoltan Somogyi
07ffbce8e7 Implement --warn-sdtlib-shadowing.
compiler/mercury_compile_main.m:
    I added that option a week or so ago, but at that time, it did nothing.
    This diff implements the warning.

library/LIB_FLAGS.in:
    Disable the warning for the modules in the library directory.

configure.ac:
    Require the installed compiler to recognize the option, since without this,
    library/LIBFLAGS won't work.

tests/warnings/profiling_builtin.{m,exp}:
tests/warnings/time.{m,exp}:
tests/warnings/time.subtime.m:
    Two test cases for the warning. One, time, shadows the name of
    a documented library module, the other, profiling_builtin,
    shadows the name an undocumented library module.

    The purpose of time.subtime is to test the message when the module name
    *contains* a stdlib module name, but is not *identical* to it.

tests/warnings/Mmakefile:
    Do *not* turn on the new test cases, but do document why we do not do so.
2022-01-08 04:41:55 +11:00
Zoltan Somogyi
d64961d79d Use checked types/insts/modes in parse_tree_module_src.
This means that we can do the exact same checks (and, if needed, generate
the exact same error messages) when generating interface files as when
generating target language code.

This should also allow us to simplify the process of adding type, inst
and mode definitions to the HLDS.

compiler/prog_item.m:
    As above.

    Delete unused function.

compiler/error_util.m:
    Add mechanisms that allow us to distinguish (a) error specs that represent
    a type, inst or mode name definition being invalid, from (b) other error
    specs.

compiler/check_type_inst_mode_defns.m:
    Improve the error messages we generate, in several ways.

    First, for each message, specify a real severity. When the messages
    could be seen only when generating interface files, making them all
    warnings was fine and preserved old behavior, but since soon these
    will be the only place for these checks, we need to call errors errors.

    Second, specify, in the phase, which errors represent a invalid type,
    inst or mode definition, and which don't.

    Third, improve the wording of messages. In some places, do this by
    being clearer about the distinction between declarations and definitions.
    In others, do it by including more information in the message. In yet
    others, do it by recovering some kinds of mistakes (mostly items being
    in the wrong section) enough to avoid avalanche errors.

    Fourth, fix a bug. If a type ctor has an exported *declaration*,
    then it is ok for any foreign type definitions for that type_ctor
    being in the implementation section, but if the type_ctor has an
    exported Mercury *definition*, then any foreign_type definitions
    must be in the interface section as well. The code that handled
    both these situations did not enforce that.

    Fifth, fix another bug: do not include foreign type definitions
    in the source definitions of a type_ctor twice, once as a "du" (sic)
    definition, and once as itself.

compiler/convert_parse_tree.m:
    Check type, inst and mode definitions in raw_compilation_units
    when creating parse_tree_module_srcs.

compiler/comp_unit_interface.m:
    Make the code constructing interface files work from the checked maps
    in parse_tree_module_srcs.

compiler/make_hlds_passes.m:
    Set the flags that say we have found invalid type, inst or mode definitions
    from the error specs constructed during the creation of the checked
    type, inst and mode maps.

compiler/add_type.m:
    Comment out an error message for a condition that will be detected and
    reported by check_type_inst_mode_defns.m.

compiler/make_hlds_separate_items.m:
    For now, turn checked maps of type, inst and mode definitions
    back to item lists for addition to the HLDS. Adding whole checked
    definitions to the HLDS will be done by a future change.

compiler/make_hlds_error.m:
    Fix misleading indentation in an error message.

compiler/parse_tree_out.m:
    Conform to the changes above.

    Generate output whose indentation does not depend on tab settings.

compiler/check_raw_comp_unit.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
    Conform to the changes above.

compiler/parse_type_defn.m:
    Fix misleading error message for ":- type <name> = <type>".

tests/debugger/foreign_type.{m,exp}:
    Delete a redundant type declaration to avoid a warning, and update
    the .exp file to expect the new line numbers.

tests/invalid/any_mode.err_exp:
tests/invalid/bug436.err_exp:
tests/invalid/bug476.err_exp:
tests/invalid/exported_foreign_enum.err_exp:
tests/invalid/fe_unmapped_nonverbose.err_exp:
tests/invalid/fe_unmapped_verbose.err_exp:
tests/invalid/foreign_enum_invalid.err_exp:
tests/invalid/foreign_solver_type.err_exp:
tests/invalid/foreign_type_visibility.err_exp:
tests/invalid/pragma_qual_error.err_exp:
tests/invalid/repeated_field_name.err_exp:
tests/invalid/subtype_foreign.err_exp:
tests/invalid/type_with_no_defn.err_exp:
tests/invalid/types2.err_exp:
tests/invalid/user_field_access_decl_conflict.err_exp:
tests/invalid_nodepend/bad_foreign_type.err_exp:
tests/invalid_nodepend/bigtest.err_exp:
tests/invalid_nodepend/invalid_typeclass.err_exp:
tests/invalid_nodepend/types.err_exp:
tests/invalid_nodepend/uu_type.err_exp:
tests/invalid_nodepend/where_abstract_enum.err_exp:
    Expect the new error messages.

tests/invalid/abstract_solver_type.{m,err_exp}:
tests/warnings/abstract_solver_type.{m,exp}:
    Move the abstract_solver_type test case from invalid to warnings, because
    this diff changes its only error to be only a warning.

tests/invalid/Mmakefile
2021-10-16 17:37:36 +11:00
Zoltan Somogyi
785ec7d4b9 Move see/seen/tell/told from io.m to prolog.m.
library/io.m:
library/prolog.m:
    Move the definitions of see/seen/tell/told and their binary variants
    from io.m to prolog.m, leaving behind forwarding predicates that are
    marked obsolete.

library/robdd.m:
    Replace tell/told with output to specified streams.

    Where exported predicates sent output to the current output stream,
    add a version that sends output to a user-specified stream.

    This required replacing user-provided predicates that wrote a variable
    to the current output stream with a user-provided function that simply
    returns the string representation of the variable, so that the resulting
    string could be printed to a *specified* stream.

NEWS:
    Document the changes above.

compiler/mode_constraint_robdd.m:
compiler/mode_robdd.implications.m:
    Conform to the changes above.

compiler/simplify_goal_call.m:
    Warn about calls to see/seen/tell/told in prolog.m as well as io.m.

    Warn about the binary versions of see/seen/tell told, and
    the binary versions of set_{in,out}put_stream.

tests/warnings/save.{m,exp}:
    Call prolog.see instead of io.see, since we want to test the warning
    from simplify_goal_call.m, not the warning about io.see being obsolete.
2021-08-30 15:44:09 +10:00
Zoltan Somogyi
c03b11ca48 Update the style of more test cases.
And updated expected outputs for changed line numbers.
2021-07-27 19:29:21 +10:00
Zoltan Somogyi
4d699229ff Provide more info in a warning.
compiler/add_type.m:
    When a subtype lists data constructors in a different order than its
    supertype, print a diff of the two orders, not just the list of
    out-of-order constructors.

    Give some predicates more expressive names.

compiler/style_checks.m:
compiler/error_util.m:
    Move two predicates from style_checks to error_util.m
    to allow them to be called from add_type.m.

tests/warnings/subtype_order.exp:
    Expect the updated warning.
2021-07-03 21:52:59 +10:00
Peter Wang
5205908cd3 Make subtypes share standard ordering with base type.
doc/reference_manual.texi:
    Define the standard ordering of a subtype to be the same as that of
    its base type.

    Suggest that subtype constructors should be declared in the same
    order as in the supertype.

compiler/add_type.m:
    Warn if a subtype's constructors are declared in a different
    relative order to the supertype.

compiler/unify_proc.m
    Generate unify/compare procs for subtypes that cast to the base type
    then call the unify/compare proc for the base type. This was
    previously done only for the high-level data representation.

tests/hard_coded/Mmakefile:
tests/hard_coded/subtype_order.exp:
tests/hard_coded/subtype_order.m:
tests/warnings/Mmakefile:
tests/warnings/subtype_order.exp:
tests/warnings/subtype_order.m:
    Add test cases.
2021-04-09 17:41:23 +10:00
Peter Wang
88047bbb45 Delete Erlang from tests.
tests/general/float_test.exp3:
tests/general/float_test.m:
tests/general/read_dir_regression.exp4:
tests/general/read_dir_regression.m:
tests/hard_coded/remove_file.exp2:
tests/hard_coded/remove_file.m:
    Delete Erlang backend specific expected outputs.

tests/hard_coded/Mmakefile:
tests/hard_coded/erlang_deconstruct.exp:
tests/hard_coded/erlang_deconstruct.m:
tests/hard_coded/existential_list.exp:
tests/hard_coded/existential_list.m:
tests/valid/Mmakefile:
tests/valid/erl_ite_vars.m:
tests/valid/zf_erlang_bug.m:
    Delete erlang target specific tests.

tests/*:
    Delete Erlang foreign procs and foreign types.
2020-10-27 11:10:11 +11:00
Peter Wang
524f4d72e2 Delete references to Erlang backend in makefiles.
Mmake.workspace:
Mmakefile:
*/Mmakefile:
tests/*/Mmakefile:
tests/valid/Mmake.valid.common:
trace/Mmakefile:
    As above.
2020-10-27 11:10:11 +11:00
Zoltan Somogyi
660cfe4f83 s/predicate symbol predicate/predicate symbol/ in a diagnostic.
We used to generate diagnostics of the form

    The predicate symbol predicate `<'/2 is also overloaded here.

The second "predicate" is pure noise. It could never be "function",
even though the code generating that message was prepared for that.

compiler/typecheck.m:
    When typechecking a *predicate* call, don't specify the predicate
    being called using a data structure that can also refer to functions.

compiler/typecheck_info.m:
    When representing an overloaded predicate name, as opposed to
    an overloaded function name, don't include a pred_or_func indication
    that should *always* be pf_predicate.

compiler/typecheck_errors.m:
    When reporting an overloaded predicate name, or talking about a
    predicate's argument vector, do not take a pred_or_func indication,
    since it should *always* be pf_predicate.

tests/invalid/ambiguous_overloading_error.err_exp:
tests/warnings/ambiguous_overloading.exp:
    Don't expect the redundant "predicate" in the overload error message.

tests/invalid/max_error_line_width.err_exp:
tests/invalid/max_error_line_width.m:
    The deletion of the redundant "predicate" in overload error messages
    made them all fit on one line, robbing this test of its task of testing
    longer-than-80-column output lines. Change the test so that the overload
    is not between int.< and float.<, but between the unchecked_left_shift
    functions in int and uint, since the longer function name yields error
    message lines in the length range this test case wants to test.

tests/invalid/ambiguous_overloading_error.m:
tests/invalid/arg_permutation.m:
tests/invalid/assert_in_interface.m:
tests/invalid/bad_detism_category.m:
    Fix programming style.

tests/invalid/assert_in_interface.err_exp:
    Update a line number.
2020-10-26 20:28:18 +11:00
Zoltan Somogyi
9cacd33f47 Remove "is" as a synonym for "=", step 1.
This first step deals with the consequences of such removal.
The removal itself will happen in stage 2. That step will
add "is" to the prolog module in the library.

compiler/add_pred.m:
    Prepare for "is" being in the prolog module.

compiler/options.m:
    Add a way to test whether the change to add_pred.m is in the
    installed compiler.

tests/accumulator/base.m:
tests/accumulator/call_in_base.m:
tests/accumulator/chain.m:
tests/accumulator/commutative.m:
tests/accumulator/construct_test.m:
tests/accumulator/dcg.m:
tests/accumulator/deconstruct_test.m:
tests/accumulator/disj.m:
tests/accumulator/func.m:
tests/accumulator/heuristic.m:
tests/accumulator/highorder.m:
tests/accumulator/identity.m:
tests/accumulator/inter.m:
tests/accumulator/nonrec.m:
tests/accumulator/out_to_in.m:
tests/accumulator/qsort.m:
tests/accumulator/simple.m:
tests/accumulator/split.m:
tests/accumulator/swap.m:
tests/benchmarks/cqueens.m:
tests/benchmarks/crypt.m:
tests/benchmarks/deriv.m:
tests/benchmarks/deriv2.m:
tests/benchmarks/nrev.m:
tests/benchmarks/poly.m:
tests/benchmarks/primes.m:
tests/benchmarks/qsort.m:
tests/benchmarks/query.m:
tests/benchmarks/tak.m:
tests/debugger/interactive.m:
tests/declarative_debugger/Mercury.options:
tests/declarative_debugger/io_read_bug.m:
tests/declarative_debugger/queens.exp:
tests/declarative_debugger/queens.m:
tests/dppd/imperative_solve_impl.m:
tests/dppd/map_impl.m:
tests/dppd/max_length_impl.m:
tests/dppd/sum.m:
tests/dppd/upto_sum_impl.m:
tests/par_conj/dep_par_21.m:
tests/tabling/seq.m:
tests/term/dds3_14.m:
tests/term/mmatrix.m:
tests/term/money.m:
tests/term/occur.m:
tests/term/pl4_5_2.m:
tests/term/queens.m:
tests/typeclasses/inference_test.m:
tests/typeclasses/inference_test_2.m:
tests/valid/lazy_list.m:
tests/warnings/duplicate_const.m:
    Replace calls to "is" with unifications. In many places,
    bring programming style up to date.
2020-08-21 10:42:37 +10:00
Zoltan Somogyi
c4ea92582e Fix typo in expected output file. 2020-07-13 23:45:43 +10:00
Zoltan Somogyi
1f45f91886 Make "mmake runtests" work again.
My commit afe2887882 broke the ability
to run the test suite outside of a bootcheck by executing "mmake runtests"
in the tests directory. This diff fixes that.

tests/Mmake.common:
    Don't define "TESTS_DIR = ..". While every single tests/*/Mmakefile
    defined it as such, I overlooked the fact that tests/Mmakefile itself
    defined it ".", referring to the same directory from a different starting
    point. Document this easily-overlooked fact.

    Rename the old runtests target, which after afe2887 runs the tests
    in a single directory, as runtests_dir, to leave the target name
    "runtests" itself free for tests/Mmakefile to use.

tests/Mmakefile:
    Define "TESTS_DIR = .", and add a target "runtests" which invokes
    "mmake runtests_dir" in each test directory.

tools/bootcheck:
    Invoke "mmake runtests_dir" instead of "mmake runtests" in each
    test directory.

    Initialize a variable just before it is used.

tests/*/Mmakefile:
    Add back the definition "TESTS_DIR = .."
2020-06-10 01:05:15 +10:00
Peter Wang
e6f6baebfd Fix spelling. 2020-04-15 14:46:20 +10:00
Zoltan Somogyi
9a909ddc7f Avoid misleading occurs check warnings.
compiler/superhomogeneous.m:
    Record a unification between X and f(Yi) as possibly leading to
    an occurs check warning only if f is known to be a data constructor,
    either user defined or the builtin tuple constructor.

compiler/hlds_cons.m:
    Add a version of the search_cons_table predicate that does not construct
    the list of hlds_cons_defns that match the given cons_id. The new code
    in superhomogeneous.m needs to know whether a cons_id is a known data
    constructor, but it does not need to know its matching definitions,
    and constructing that list is reasonably expensive when it has to be
    executed for every single function symbol in every clause.

    Add some documentation of the existing predicates, and separate their
    implementations from each other with lines.

tests/warnings/occurs.{m,exp}:
    Extend this test case both with a unifications we should warn about
    (a circular unification whose top level cons_id is a tuple constructor)
    and one we should not warn about (when the cons_is is NOT a data
    constructor of any kind).

compiler/implementation_defined_literals.m:
compiler/prog_data.m:
    Clarify related documentation.
2020-04-15 02:57:16 +10:00
Zoltan Somogyi
afe2887882 Remove stale references to test subdirs.
A long time ago, test directories such as hard_coded had subdirectories
such as hard_coded/typeclasses. These have since been flattened out
(e.g. hard_coded/typeclasses is now just typeclasses), but there were
still remnants of the old approach. This diff deletes those remnants.

tests/*/Mmakefile:
    Delete the TESTS_DIR and the SUBDIRS mmake variables; TESTS_DIR
    was always set to "..", and SUBDIRS to the empty string.

    Delete any references to the make variable NOT_WORKING, since
    it is never used.

tests/Mmake.common:
    Document that Mmakefiles in test directories don't have to set
    TESTS_DIR and SUBDIRS anymore. Fix the formatting of the documentation
    of the make variables they do still have to set.

    Delete the targets and actions for handling subdirectories of
    test directories, since there aren't any.

tests/Mmakefile:
    Simplify some code.
2020-04-14 11:23:12 +10:00
Zoltan Somogyi
4f32c50822 Let clauses with unknown warnings be processed.
This implements Mantis feature request #497.

compiler/parse_goal.m:
compiler/parse_dcg_goal.m:
    When we find that a disable_warnings scope contains an unrecognized
    warning name, generate a warning for it, and return this warning
    *alongside*, not *instead of*, the disable_warnings scope goal.
    This requires passing around not a maybe1(goal), as we have been doing
    till now, but a maybe2(goal, list(warning_spec)), so this change
    affects both (1) most of these two modules, and (2) most of the
    modules below.

compiler/error_util.m:
    Provide warning_spec as a synonym for error_spec, to be used in
    situations like this where the "error_spec" is intended contain
    something with severity_warning.

compiler/maybe_error.m:
    Provide some new utility predicates now needed in parse_goal.m
    and elsewhere.

compiler/prog_item.m:
    Provide room in the representation of clauses for the warnings
    generated by parsing the clause body goal.

compiler/add_class.m:
compiler/add_clause.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma_tabling.m:
compiler/du_type_layout.m:
compiler/get_dependencies.m:
compiler/make_hlds_passes.m:
compiler/parse_item.m:
compiler/parse_tree_out_clause.m:
compiler/prog_item_stats.m:
compiler/superhomogeneous.m:
    Conform to the changes above.

tests/valid/unknown_warning.m:
    Add this test case that checks whether a source file with an unknown
    warning name in a disable_warnings scope can have code generated for it.

tests/warnings/unknown_warning.{m,exp}:
    Add the same source file to this directory as well, to check whether
    we get the right set of warnings.

tests/valid/Mmakefile:
tests/valid/Mercury.options:
tests/warnings/Mmakefile:
    Enable the two new test cases.
2020-04-05 19:09:31 +10:00
Zoltan Somogyi
79e8804db9 Fix "this disjunct can't have solutions" warnings in multimode preds.
This fixes github issue #85.

A complication is that the compiler itself has code, in make.util.m,
in which a disjunct has no solutions in only one mode of a two mode
function, but in this case, the code works (though its programming style
is pretty bad), so to get this change to bootstrap, we also need
a way to disable the "this disjunct can't have solutions" warning
in a scope.

compiler/simplify_goal_disj.m:
    When we generate a "this disjunct can't succeed" warning,
    do not insist on all modes generating that warning.
    We used to insist on that because in a multi-mode predicate,
    such warnings can be inappropriate for other modes.
    Instead, achieve the same objective of minimizing programmer
    confusion by adding a codicil explicitly mentioninging
    this possibility.

    Make the generation of this warning conditional on a simplify task
    that can be disabled by "disable_warnings" scope.

compiler/prog_data.m:
    Add "no_solution_disjunct" as a warning kind that may be disabled.

compiler/parse_goal.m:
    Parse the new kind of warning.

compiler/prog_out.m:
    Output the new kind of warning.

    Improve some adjacent though unrelated code.

compiler/make.util.m:
    Add code disable this warning in the affected predicate.
    Comment out this code until installed compilers know how
    to parse it and understand it.

compiler/Mercury.options:
    Don't turn warnings into errors for make.util.m until then.

compiler/simplify_goal_scope.m:
compiler/simplify_info.m:
compiler/simplify_tasks.m:
    Provide the mechanism needed to make it possible to disable
    warnings about no solution disjuncts.

doc/reference_manual.texi:
    Document the new disable-able warning.

NEWS:
    Document both the changed behavior of the old warning
    and the new way to disable it.

tests/warnings/gh85.{m,exp}:
    A regression test for the bug, based on the code in the
    github issue. It also tests the way to disable the warning.

tests/warnings/Mmakefile:
    Enable the new test case.
2020-03-24 15:20:59 +11:00
Zoltan Somogyi
3a1ed2efcb Replace simple_call_id with pf_sym_name_arity.
compiler/prog_data.m:
    Delete the simple_call_id data type, since it is isomorphic
    to the pf_sym_name_arity type, which more clearly specifies
    what is stored inside it.

compiler/prog_out.m:
    Rename (all three versions of) simple_call_id_to_string to
    pf_sym_name_orig_arity_to_string, both to conform to the change
    in the input data type, and to emphasize that the resulting string
    will contain the *original* arity of functions (which does not include
    the return value), which is one less than the arity in the
    pf_sym_name_arity structure (which, in accordance with the
    convention inside the compiler that the arity is the length
    of the argument list, *does* include the return value).

    Delete the provision inside simple_call_id_to_string, now
    pf_sym_name_orig_arity_to_string, for special handling of the names
    of the predicates we use to implement promises, because it seems that
    *none* of the call sites to any of the three versions of this function
    can actually pass to it the identity of such a predicate. These calls
    refer to a predicate or mode declaration item (which promise predicates
    do not have), to clause or foreign_proc items (which again, promise
    predicates cannot have) or calls to the predicate (promise predicates
    cannot be called).

    Delete the exported predicate simple_call_id_to_sym_name_arity.
    It was called from exactly one place, inside prog_out.m itself,
    and this diff inlines that call.

    Avoid unnecessary forwarding of work from prog_out.m to error_util.m.

    Delete (all three versions of) write_simple_call_id. The changes
    below replace all their (few) uses with calls to
    pf_sym_name_orig_arity_to_string.

compiler/error_util.m:
    Replace the simple_call() error piece with qual_pf_sym_name_orig_arity,
    and add a new version unqual_pf_sym_name_orig_arity. Their names
    explicitly say that they print the original arities of functions,
    also say whether they strip away any module qualification on the
    sym_name inside the pf_sym_name_arity. We prefer the unqual version
    in situations where the module qualifier is implicit, which usually means
    that it must be the same as the name of the module being compiled, because
    it reduces visual clutter for readers of error messages.

    Put {qual,unqual}_pf_sym_name_orig_arity next to their most closely
    related function symbols, {qual,unqual}_sym_name_arity, in the
    format_component type. (This yields a few inconsequential changes
    in the order of error_specs when sorted.)

compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/check_libgrades.m:
compiler/check_parse_tree_type_defns.m:
compiler/check_promise.m:
compiler/check_typeclass.m:
compiler/convert_parse_tree.m:
compiler/equiv_type.m:
compiler/goal_expr_to_goal.m:
compiler/hlds_data.m:
compiler/hlds_desc.m:
compiler/hlds_goal.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/hlds_pred.m:
compiler/inst_util.m:
compiler/llds_out_instr.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make_hlds_error.m:
compiler/make_hlds_warn.m:
compiler/mark_tail_calls.m:
compiler/ml_unify_gen_construct.m:
compiler/mlds_to_c_stmt.m:
compiler/mode_errors.m:
compiler/mode_info.m:
compiler/modecheck_util.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qualify_items.m:
compiler/parse_item.m:
compiler/parse_module.m:
compiler/parse_type_repn.m:
compiler/polymorphism.m:
compiler/post_typecheck.m:
compiler/pre_quantification.m:
compiler/pred_table.m:
compiler/prog_item.m:
compiler/recompilation.version.m:
compiler/term_constr_build.m:
compiler/termination.m:
compiler/type_ctor_info.m:
compiler/typecheck.m:
compiler/typecheck_errors.m:
compiler/typecheck_info.m:
compiler/unify_gen_construct.m:
compiler/unused_imports.m:
    Conform to the changes above. Where I am pretty sure that in an error
    message, the module qualifier of a name must be the current module,
    use unqual_pf_sym_name_orig_arity instead of qual_pf_sym_name_orig_arity.

    Add some sanity checks where they seem appropriate.

    Replace sequences of io.write_strings with uses of io.format where this
    yields clearer code. (This is why there were no remaining calls to
    write_simple_call_id.)

    Shorten some too-long lines.

    In add_pred.m, make the order of some predicate definitions match
    the order of the calls to them.

tests/invalid/ambiguous_method.err_exp:
tests/invalid/ambiguous_method_2.err_exp:
tests/invalid/bad_pred_arity.err_exp:
tests/invalid/bad_sv_unify_msg.err_exp:
tests/invalid/bigtest.err_exp:
tests/invalid/bug113.err_exp:
tests/invalid/bug197.err_exp:
tests/invalid/bug278.err_exp:
tests/invalid/bug410.err_exp:
tests/invalid/bug476.err_exp:
tests/invalid/bug487.err_exp:
tests/invalid/complex_constraint_err.err_exp:
tests/invalid/constrained_poly_insts.err_exp:
tests/invalid/errors.err_exp:
tests/invalid/errors1.err_exp:
tests/invalid/errors2.err_exp:
tests/invalid/exported_mode.err_exp:
tests/invalid/field_syntax_error.err_exp:
tests/invalid/foreign_singleton.err_exp:
tests/invalid/funcs_as_preds.err_exp:
tests/invalid/imported_mode.err_exp:
tests/invalid/invalid_binary_literal.err_exp:
tests/invalid/invalid_float_literal.err_exp:
tests/invalid/invalid_hex_literal.err_exp:
tests/invalid/invalid_octal_literal.err_exp:
tests/invalid/make_opt_error.err_exp:
tests/invalid/missing_det_decls.err_exp:
tests/invalid/multimode_syntax.err_exp:
tests/invalid/null_char.err_exp:
tests/invalid/occurs.err_exp:
tests/invalid/record_syntax_errors.err_exp:
tests/invalid/ref_to_implicit_pred.err_exp:
tests/invalid/require_tailrec_1.err_exp:
tests/invalid/require_tailrec_1.err_exp2:
tests/invalid/require_tailrec_2.err_exp:
tests/invalid/require_tailrec_2.err_exp2:
tests/invalid/require_tailrec_3.err_exp:
tests/invalid/require_tailrec_3.err_exp2:
tests/invalid/state_vars_test2.err_exp:
tests/invalid/state_vars_test3.err_exp:
tests/invalid/state_vars_test5.err_exp:
tests/invalid/type_inf_loop.err_exp:
tests/invalid/typeclass_constraint_extra_var.err_exp:
tests/invalid/typeclass_mode_2.err_exp:
tests/invalid/typeclass_test_12.err_exp:
tests/invalid/typeclass_test_2.err_exp:
tests/invalid/typeclass_test_9.err_exp:
tests/invalid/types.err_exp:
tests/invalid/types2.err_exp:
tests/invalid/unbound_type_vars.err_exp:
tests/invalid/with_type.err_exp:
tests/invalid_purity/purity_nonsense.err_exp:
tests/invalid_purity/purity_nonsense2.err_exp:
tests/warnings/double_underscore.exp:
tests/warnings/pragma_source_file.exp:
tests/warnings/singleton_test.exp:
tests/warnings/singleton_test.exp2:
tests/warnings/singleton_test.exp3:
tests/warnings/singleton_test.exp4:
tests/warnings/singleton_test_state_var.exp:
tests/warnings/warn_return.exp:
tests/warnings/warn_return.exp2:
tests/warnings/warn_return.exp3:
tests/warnings/warn_succ_ind.exp:
tests/warnings/warn_succ_ind.exp2:
tests/warnings/warn_succ_ind.exp3:
tests/warnings/warn_succ_ind.exp4:
    Update all these expected output files. Most changes are due to
    predicate and function names no longer being module qualified when
    the module qualification is obvious. A few changes are due to the
    change in the relative ordering of the function symbols of the
    format_component type.

    For singleton_test, warn_return and warn_succ_ind in warnings,
    the changes to the non-C .exp files were done by hand, so they
    may have the wrong white space.
2020-03-16 12:10:28 +11:00
Zoltan Somogyi
9789375cc5 Make pre-HLDS passes use file-kind-specific parse trees.
Replacing item blocks file-kind-specific kinds of section markers with
file-kind-specific parse trees has several benefits.

- It allows us to encode the structural invariants of each kind of file
  we read in within the type of its representation. This makes the detection
  of any accidental violations of those invariants trivial.

- Since each file-kind-specific parse tree has separate lists for separate
  kinds of items, code that wants to operate on one or a few kinds of items
  can just operate on those kinds of items, without having to traverse
  item blocks containing many other kinds of items as well. The most
  important consequence of this is not the improved efficiency, though
  that is nice, but the increased clarity of the code.

- The new design is much more flexible. For example, it should be possible
  to record that e.g. an interface file we read in as a indirect dependency
  (i.e. a file we read not because its module was imported by the module
  we are compiling, but because its module was imported by *another* imported
  module) should be used *only* for the purpose it was read in for. This should
  avoid situations where deleting an import of A from a module, because it
  is not needed anymore, leads the compiler to generate an error message
  about a missing import of module B. This can happen if (a) module B
  always *should* have been imported, since it is used, but (b) module A's
  import of module B lead to module B's interface being available *without*
  an import of B.

  Specifically, this flexibility should enable us to establish each module's
  .int file as the single source of truth about how values of each type
  defined in that module should be represented. When compiling each source
  file, this approach requires the compiler to read in that module's .int file
  but using only the type_repn items from that .int file, and nothing else.

- By recording a single parse tree for each file we have read, instead of
  a varying number of item blocks, it should be significantly easier to
  derive the contents of .d files directly from the records of those
  parse trees, *without* having to maintain a separate set of fields
  in the module_and_imports structure for that purpose. We could also
  trivially avoid any possibility of inconsistencies between these two
  different sources of truth. (We currently fill in the fields used to
  drive the generation of .d files using two different pieces of code,
  one used for --generate-dependencies and one used for all other invocations,
  and these two *definitely* generate inconsistent results, as the significant
  differences in .d files between (a) just after an invocation of
  --generate-dependencies and (b) just after any other compiler invocation
  can witness.)

This change is big and therefore hard to review. Therefore in many files,
this change adds "XXX CLEANUP" comments to draw attention to places that
have issues that should be fixed, but whose fixes should come later, in
separate diffs.

compiler/module_imports.m:
    The compiler uses the module_and_imports structure defined here
    to go from a raw compilation unit (essentially a module to be compiled)
    to an augmented compilation unit (a raw compilation unit together
    with all the interface and optimization files its compilation needs).
    We used to store the contents of both the source file and of
    the interface and optimization files in the module_and_imports structure
    as item blocks. This diff replaces all those item blocks with
    file-kind-specific parse trees, for the reasons mentioned above.

    Separate out the .int0 files of ancestors modules from the .intN
    files for N>0 of directly imported modules. (Their item blocks
    used to be stored in the same list.)

    Maintain a database of the source, interface and optimization files
    we have read in so far. We use it to avoid reading in interface files
    if we have already read in a file for the same module that contains
    strictly more information (either an interface file with a smaller
    number as a suffix, or the source file itself).

    Shorten some field names.

compiler/prog_item.m:
    Define data structures for storing information about include_module,
    import_module and use_module declarations, both in a form that allows
    the representation of possibly erroneous code in actual source files,
    and in checked-and-cleaned-up form which is guaranteed to be free
    of the relevant kinds of errors. Add a block comment at the start
    of the module about the need for this distinction.

    Define parse_tree_module_src, a data structure for representing
    the source code of a single module. This is different from the existing
    parse_tree_src type, which represents the contents of a single source file
    but which may contain *more* than one module, and also different from
    a raw_compilation_unit, which is based on item blocks and is thus
    unable to express to invariants such as "no clauses in the interface".

    Modify the existing parse_tree_intN types to express the distinction
    mentioned just above, and to unify them "culturally", i.e. if they
    store the same information, make them store it using the same types.

    Fix a mistake by allowing promises to appear in .opt files.
    I originally ruled them out because the code that generates .opt files
    does not have any code to write out promises, but some of the predicates
    whose clauses it writes out have goal_type_promise, which means that
    they originated as promises, and get written out as promises.

    Split the existing pragma item kind into three item kinds, which have
    different invariants applying to them.

    - The decl (short for declarative) pragmas give the compiler some
      information, such as that a predicate is obsolete or that we
      want to type specialize some predicate or function, that is in effect
      part of the module's interface. Decl pragmas may appear in module
      interfaces, and the compiler may put them into interface files;
      neither statement is true of the other two kinds of pragmas.

    - The impl (short for implementation) pragmas are named so
      precisely because they may appear only in implementation sections.
      They give the compiler information that is private to that module.
      Examples include foreign_decls, foreign_codes, foreign_procs,
      and promises of clause equivalence, and requests for inlining,
      tabling etc. These will never be put into interface files,
      though some of them can affect the compilation of other modules
      by being included in .opt files.

    - The gen (short for generated) pragmas can never (legally) appear
      in source files at all. They record the results of compiler
      analyses e.g. about which arguments of a predicate are unused,
      or what exceptions a function can throw, and accordingly they
      should only ever occur in compiler-generated interface files.

    Use the new type differences between the three kinds of pragmas
    to encode the above invariants about which kinds of pragmas can appear
    where into the various kinds of parse trees.

    Make the augmented compilation unit, which is computed from
    the final module_and_imports structure, likewise switch from
    storing item blocks to storing the whole parse trees of the
    files that went into its construction. With each such parse tree,
    record *why* we read it, since this controls what permissions
    the source module being compiled has for access to the entities
    in the parse tree.

    Simplify the contains_foreign_code type, since one of three
    function symbols was equivalent to one possible use of another
    function symbol.

    Provide a way to record which method of which class a compiler-generated
    predicate is for. (See hlds_pred.m below.)

    Move the code of almost all utility operations to item_util.m
    (which is imported by many fewer modules than prog_item.m),
    keeping just the most "popular" ones.

compiler/item_util.m:
    Move most of the previously-existing utility operations here from
    prog_item.m, most in a pretty heavily modified form.

    Add a whole bunch of other utility operations that are needed
    in more than one other module.

compiler/convert_parse_tree.m:
    Provide predicates to convert from raw compilation units to
    parse_tree_module_srcs, and vice versa (though the reverse
    shouldn't be needed much longer).

    Update the conversion operations between the general parse_tree_int
    and the specific parse_tree_intN forms for the changes in prog_item.m
    mentioned above. In doing so, use a consistent approach, based on
    new operations in item_util.m, to detect errors such as duplicate
    include_module and import/use_module declarations in all kinds
    of parse trees.

    Enforce the invariants that the types of parse trees of various kinds
    can now express in types, generating error messages for their violations.

    Delete some utility operations that have been moved to item_util.m
    because now they are also needed by other modules.

compiler/grab_modules.m:
    Delete code that did tests on raw compilation units that are now done
    when that raw compilation unit is converted to a parse_tree_module_src.
    Use the results of the checks done during that conversion to decide
    which modules are imported/used and in which module section.

    Record a single reason for why we reading in each interface and
    optimization file. The code of make_hlds_separate_items.m will use
    this reason to set up the appropriate permissions for each item
    in those files.

    Use separate code for handling different kinds of interface and
    optimization files. Using generic traversal code was acceptable economy
    when we used the same data structure for every kind of interface file,
    but now that we *can* express different invariants for different kinds
    of interface and optimization file, we want to execute not just different
    code for each kind of file, but the data structures we want to work on
    are also of different types. Using file-kind-specific code is a bit
    longer, but it is significantly simpler and more robust, and it is
    *much* easier to read and understand.

    Delete the code that separates the parts of the implementation section
    that are exported to submodules, and the part that isn't, since that task
    is now done in make_hlds_separate_items.m.

    Pass a database of the files we have read through the relevant predicates.

    Give some predicates more meaningful names.

compiler/notes/interface_files.html:
    Note a problem with the current operation of grab_modules.

compiler/get_dependencies.m:
    Add operations to gather implicit references to builtin modules
    (which have to be made available even without an explicit import_module
    or use_module declaration) in all kinds of parse trees. These have
    more code overall, but will be at runtime, since we need only look at
    the item kinds that may *have* such implicit references.

    Add a mechanism to record the result of these gathering operations
    in import_and_or_use_maps.

    Give some types, function symbols, predicates and variables
    more meaningful names.

compiler/make_hlds_separate_items.m:
    When we stored the contents of the source module and the
    interface and optimization files we read in to augment it
    in the module_and_imports structure as a bunch of item blocks,
    the job of this module was to separate out the different kinds of items
    in the item blocks, returning a single list of each kind of item,
    with each such item being packaged up with its status (which encodes
    a set of permissions saying what the source module is allowed
    to do with it).

    Now that the module_and_imports structure stores this info in
    file-kind-specific parse trees, all of which have separate lists
    for each kind of item and none of which contain item blocks,
    the job of this module has changed. Now its job is to convert
    the reason why each file was read in into the (one or more) statuses
    that apply to the different kinds of items stored in it, wrap up
    each item with its status, and return the resulting overall list
    of status/item pairs for each kind of item.

compiler/read_modules.m:
    Add predicates that, when reading an interface file, return its contents
    in the tightest possible file-kind-specific parse tree.

    Refine the database of files we have read to allow us to store
    more file-kind-specific parse trees.

    Don't require that files in the database have associated timestamps,
    since in some cases, we read files we can put into the database
    *without* getting their timestamps.

    Allow the database to record that an attempt to read a file failed.

compiler/split_parse_tree_src.m:
    Rearchitect how this module separates out nested submodules from within
    the main module in a file.

    Another of the jobs of this module is to generate error messages for
    when module A includes module B twice, whether via nesting or via
    include_module declarations, with one special exception for the case
    where A's interface contains nested submodule A.B's interface,
    and A's implementation contains nested submodule A.B's implementation.
    The problem ironically was that while it reported duplicate include_module
    declarations as errors, split_parse_tree_src.m also *generated*
    duplicate include_module declarations. Since it replaced each nested
    submodule occurrence with an include_module declaration, in the scenario
    above, it generated two include_module declarations for A.B. Even worse,
    the interface incarnation of submodule A.B could contain
    (the interface of) its own nested submodule A.B.C, while its
    implementation incarnation could contain (the implementation section of)
    A.B.C. Each occurrence of A.B.C would be its only occurrence in the
    including part of its parent A.B, which means local tests for duplicates
    do not work. (I found this out the hard way.)

    The solution we now adopt adds include_module declarations to the
    parents of any submodule only once the parse tree of the entire
    file has been processed, since only then do we know all the
    includer/included relationships among nested modules. Until then,
    we just record such relationships in a database as we discover them,
    reporting duplicates when needed (e.g. when A includes B twice
    *in the same section*), but not reporting duplicates when not needed
    (e.g. when A.B includes A.B.C in *different* sections).

compiler/prog_data.m:
    Add a new type, pf_sym_name_and_arity, that exactly specifies
    a predicate or function. It is a clone of the existing simple_call_id
    type, but its name does NOT imply that the predicate or function
    is being called.

    Add XXXs that call for some other improvements in type names.

compiler/prog_data_foreign.m:
    Give a type, and the operations on that type, a more specific name.

compiler/error_util.m:
    Add an id field to all error_specs, which by convention should be
    filled in with $pred. Print out the value in this field if the compiler
    is invoked with the developer-only option --print-error-spec-id.
    This allows a person debugging the compiler find out where in the code
    an undesired error message is coming from significantly easier
    than was previously possible.

    Most of the modules that have changes only "to conform to the changes
    above" will be for this change. In many cases, the updated code
    will also simplify the creation of the affected error_specs.

    Fix a bug that looked for a phase in only one kind of error_spec.

    Add some utility operations needed by other parts of this change.

    Delete a previously internal function that has been moved to
    mdbcomp/prim_data.m to make it accessible in other modules as well.

compiler/Mercury.options:
    Ask the compiler to warn about dead predicates in every module
    touched by this change (at least in one its earlier versions).

compiler/add_foreign_enum.m:
    Replace a check for an inappropriately placed foreign_enum declaration
    with a sanity check, since with this diff, the error should be caught
    earlier.

compiler/add_mutable_aux_preds.m:
    Delete a check for an inappropriately placed mutable declaration,
    since with this diff, the error should be caught earlier.

compiler/add_pragma.m:
    Instead of adding pass2 and pass3 pragmas, add decl and impl and
    generated pragmas.

    Delete the tests for generated pragma occurring anywhere except
    .opt files, since those tests are now done earlier.

    Shorten some too-long predicate names.

compiler/comp_unit_interface.m:
    Operate on as specific kinds of parse trees as the interface of this
    module will allow. (We could operate on more specific parse trees
    if we changed the interface, but that is future work).

    Use the same predicates for handling duplicate include_module,
    import_module and use_module declarations as everywhere else.

    Delete the code of an experiment that shouldn't be needed anymore.

compiler/equiv_type.m:
    Replace code that operated on item blocks with code that operates
    on various kinds of parse trees.

    Move a giant block of comments to the front, where it belongs.

compiler/hlds_module.m:
    Add a field to the module_info that lets us avoid generating
    misleading error messages above missing definitions of predicates
    or functions when those definitions were present but were not
    added to the HLDS because they had errors.

    Give a field and its access predicates a more specific name.

    Mark a spot where an existing type cannot express everything
    it is supposed to.

compiler/hlds_pred.m:
    For predicates which the compiler creates to represent a class method
    (the virtual function, in OOP terms), record not just this fact,
    but the id of the class and of the method. Using this extra info
    in progress messages (with mmc -V) prevents the compiler from printing e.g.

        % Checking typeclass constraints on class method
        % Checking typeclass constraints on class method
        % Checking typeclass constraints on class method

    when checking three such predicates.

compiler/make.m:
    Provide a slot in the make_info structure to allow the database
    of the files we have read in to be passed around.

compiler/make_hlds_error.m:
    Delete predicates that are needed in just one other module,
    and have therefore been moved there.

compiler/make_hlds_passes.m:
    Add decl, impl and generated pragma separately, instead of adding
    pass2 and pass3 pragmas separately.

    Do not generate error messages for clauses, initialises or finalises
    in module interfaces, since with this diff, such errors should be
    caught earlier.

compiler/mercury_compile_main.m:
compiler/recompilation.check.m:
    Explicitly pass around the expanded database of parse trees
    of files that have been read in.

compiler/module_qual.collect_mq_info.m:
compiler/module_qual.m:
compiler/module_qual.qualify_items.m:
    Collect module qualification information, and do module qualification
    respectively on parse trees of various kinds, not item blocks.
    Take information about what the module may do with the contents
    of each interface or optimization file from the record of why
    we read that file, not from the section markers in item blocks.

    Break up some too-large predicates by carving smaller ones out of them.

compiler/options.m:
    Add an option to control whether errors and/or warnings detecting
    when deciding what should go into a .intN file be printed,
    thus (potentially) preventing the creation of that file.

    Add commented-out documentation for a previously totally undocumented
    option.

doc/user_guide.texi:
    Document the new option.

NEWS:
    Announce the new option.

    Mention that we now generate warnings for unused import_module and
    use_module declarations in the interface even if the module has
    submodules.

compiler/write_module_interface_files.m:
    Let the new option control whether we filter out any messages generated
    when deciding what should go into a .intN file.

compiler/parse_item.m:
    Delete actually_read_module_opt, since it is no longer needed;
    its callers now call actually_read_module_{plain,trans}_opt instead.

    Delete unneeded arguments from some predicates.

compiler/parse_module.m:
    Delete some long unused predicates.

compiler/parse_pragma.m:
    When parsing pragmas, wrap them up in the new decl, impl or generated
    pragma kinds.

compiler/parse_tree_out.m:
    Add predicates to write out each of the file-kind-specific parse trees.

compiler/parse_tree_out_pragma.m:
    Add predicates to write out decl, impl and generated pragmas.

compiler/polymorphism.m:
    Add a conditionally-enabled progress message, which can be useful
    in tracking down problems.

compiler/prog_item_stats.m:
    Conform NOT to the changes above beyond what is needed to let this module
    compile. Let that work be done the next time the functionality of
    this module is needed, by which time the affected data structures
    maybe have changed further.

compiler/typecheck.m:
    Fix a performance problem. With intermodule optimization, we read in
    .opt files, some of which (e.g. list.opt and int.opt) contain promises.
    These promises are read in as predicates with goal_type_promise,
    but they do not have declarations of the types of their arguments
    (since promises do not have declarations as such). Those argument types
    therefore have to be inferred. That inference replaces the original
    "I don't know" argument types with their actual types.

    The performance problem is that when we change the recorded argument types
    of a predicate, we require another loop over all the predicates in the
    module, so that any calls to this predicate can be checked against
    the updated types. This is as it should be for callable predicates,
    but promises are not callable. So if all the *only* predicates whose
    recorded argument types change during the first iteration to fixpoint
    are promises, then a second iteration is not needed, yet we used to do it.

    The fix is to replace the "Have the recorded types of this predicate
    changed?" boolean flag with a bespoke enum that says "Did the checking
    of this predicate discover a need for another iteration", and not
    setting it when processing predicates whose type is goal_type_promise.

compiler/typecheck_errors.m:
    Do not generate an error message for a predicate missing its clauses
    is the clauses existed but were not added to the HLDS because they were
    in the interface section.

    When reporting on ambiguities (when a call can match more than one
    predicate or function), sort the possible matches before reporting
    them.

compiler/accumulator.m:
compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_mode.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/add_type.m:
compiler/canonicalize_interface.m:
compiler/check_for_missing_type_defns.m:
compiler/check_parse_tree_type_defns.m:
compiler/check_promise.m:
compiler/check_raw_comp_unit.m:
compiler/check_typeclass.m:
compiler/common.m:
compiler/compile_target_code.m:
compiler/compiler_util.m:
compiler/dead_proc_elim.m:
compiler/deps_map.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/du_type_layout.m:
compiler/field_access.m:
compiler/find_module.m:
compiler/float_regs.m:
compiler/format_call.m:
compiler/goal_expr_to_goal.m:
compiler/handle_options.m:
compiler/hlds_out_module.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/introduce_parallelism.m:
compiler/layout_out.m:
compiler/make.dependencies.m:
compiler/make.module_dep_file.m:
compiler/make_hlds_warn.m:
compiler/mark_tail_calls.m:
compiler/mercury_compile_llds_back_end.m:
compiler/ml_top_gen.m:
compiler/mmakefiles.m:
compiler/mode_errors.m:
compiler/mode_robdd.equiv_vars.m:
compiler/modes.m:
compiler/module_qual.qual_errors.m:
compiler/oisu_check.m:
compiler/old_type_constraints.m:
compiler/options_file.m:
compiler/parse_class.m:
compiler/parse_dcg_goal.m:
compiler/parse_goal.m:
compiler/parse_inst_mode_defn.m:
compiler/parse_inst_mode_name.m:
compiler/parse_mutable.m:
compiler/parse_sym_name.m:
compiler/parse_type_defn.m:
compiler/parse_type_name.m:
compiler/parse_type_repn.m:
compiler/parse_types.m:
compiler/parse_util.m:
compiler/parse_vars.m:
compiler/post_term_analysis.m:
compiler/post_typecheck.m:
compiler/prog_event.m:
compiler/prog_mode.m:
compiler/purity.m:
compiler/qual_info.m:
compiler/recompilation.version.m:
compiler/resolve_unify_functor.m:
compiler/simplify_goal.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_disj.m:
compiler/simplify_goal_ite.m:
compiler/simplify_proc.m:
compiler/state_var.m:
compiler/stratify.m:
compiler/style_checks.m:
compiler/superhomogeneous.m:
compiler/table_gen.m:
compiler/term_constr_errors.m:
compiler/term_errors.m:
compiler/termination.m:
compiler/trace_params.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/write_deps_file.m:
compiler/xml_documentation.m:
    Conform to the changes above.

mdbcomp/prim_data.m:
    Move a utility function on pred_or_funcs here from a compiler module,
    to make it available to other compiler modules as well.

scripts/compare_s1s2_lib:
    A new script that helped debug this diff, and may help debug
    similar diffs the future. It can compare (a) .int* files, (b) .*opt
    files, (c) .mh/.mih files or (d) .c files between the stage 1 and
    stage 2 library directories. The reason for the restriction
    to the library directory is that any problems affecting the
    generation of any of these kinds of files are likely to manifest
    themselves in the library directory, and if they do, the bootcheck
    won't go on to compile any of the other stage 2 directories.

tests/debugger/breakpoints.a.m:
tests/debugger/breakpoints.b.m:
    Move import_module declarations to the implementation section
    when they are not used in the interface. Until now, the compiler
    has ignored this, but this diff causes the compiler to generate
    a warning for such misplaced import_module declarations even modules
    that have submodules. The testing of such warnings is not the point
    of the breakpoints test.

tests/invalid/Mercury.options:
    Since the missing_interface_import test case tests error messages
    generated during an invocation of mmc --make-interface, add the
    new option that *allows* that invocation to generate error messages.

tests/invalid/ambiguous_overloading_error.err_exp:
tests/invalid/max_error_line_width.err_exp:
tests/warnings/ambiguous_overloading.exp:
    Expect the updated error messages for ambiguity, in which
    the possible matches are sorted.

tests/invalid/bad_finalise_decl.m:
tests/invalid/bad_initialise_decl.m:
    Fix programming style.

tests/invalid/bad_item_in_interface.err_exp:
    Expect an error message for a foreign_export_enum item in the interface,
    where it should not be.

tests/invalid/errors.err_exp:
    Expect the expanded wording of a warning message.

tests/invalid/foreign_enum_invalid.err_exp:
    Expect a different wording for an error message. It is more "standard"
    but slightly less informative.

tests/invalid_submodules/children2.m:
    Move a badly placed import_module declaration, to avoid having
    the message the compiler now generates for it from affecting the test.

tests/submodules/parent2.m:
    Move a badly placed import_module declaration, to avoid having
    the message the compiler now generates for it from affecting the test.

    Update programming style.
2020-03-13 12:58:33 +11:00
Zoltan Somogyi
6bfef65f50 Fix the reminder about hidden messages itself being hidden.
compiler/mercury_compile_main.m:
    When we generate more messages for the user than we show, either
    because of --limited-error-context options or because the user has
    not asked for the verbose part of messages, we used to print a reminder
    about this fact in only one case:

    - at the end of the compilation, and
    - only if the exit status wasn't zero.

    Both of these condition was wrong.

    - If we were compiling modules a, b, c, d ... z, we could get a message
      about more messages being available being printed after the compilation
      of a module (z) for which we generated *no* messages at all, just because
      some message earlier in the list got such messages.

    - If the compilation generated no errors but only warnings, then
      we never printed reminders about any verbose parts of those warnings
      being held back.

    Fix both of these issues by

    - separating the code doing the reminder into its own predicate,
      and invoking it at the end of the processing of each module
      (leaving a call at its old location where it is invoked
      after we have processed all modules), and

    - not making the invocation conditional on exit status.

tests/warnings/ambiguous_overloading.exp:
tests/warnings/arg_order_rearrangment.exp:
tests/warnings/bug477.exp:
tests/warnings/infinite_recursion.exp:
tests/warnings/simple_code.exp:
tests/warnings/singleton_test.exp:
tests/warnings/singleton_test.exp2:
tests/warnings/singleton_test.exp3:
tests/warnings/singleton_test.exp4:
    Update these to expect the "For more information, recompile with `-E'"
    message, now that we don't hide it.

tests/warnings/singleton_test.m:
    Document what the four .exp files are for.
2019-10-26 13:21:30 +11:00
Zoltan Somogyi
52b3fc68a2 Warn about occurs check violations in parse trees.
Until now, we have generated warnings about occurs check violations
in the HLDS. Since the HLDS is in superhomogeneous form, this means
we warn for X = f(X), but not for Xs = [X1, X2 | Xs]. The reason is
that the latter expands to Xs = [X1 | Xs1], Xs1 = [X2 | Xs],
and neither of those two unifications fails the occurs check by itself.

This diff switches to having that warning be generated during the creation
of the HLDS, by code that works on the original parse tree. That means
we can now generate warnings for code such as Xs = [X1, X2 | Xs].

NEWS:
    Mention that fact.

compiler/superhomogeneous.m:
    While expanding terms into superhomogeneous form, keep track
    of which variables have been unified with a term *or an ancestor
    of that term*. In the case above, we know that Xs1 is *part of* Xs,
    so unifying it with [X2 | Xs] is an occurs check violation.

    Conditionally generate a warning for such violations. This is only
    a warning, because in the parse tree, function symbols can be not just
    data constructors but also function applications, and we can't
    say which is which. While X = f(X) is a real problem if f is
    a data constructor, it may be perfectly ok code (a test for a
    fixpoint) if f is a function.

compiler/modecheck_unify.m:
    Disable the HLDS version of this warning, to avoid warning
    about the problem twice. (This diff leaves the infrastructure
    supporting the HLDS warning remains in place, in case we want
    to enable it again.)

compiler/options.m:
    Add the new warning option that the new warning is conditional on.

compiler/prog_data.m:
    Add the new warning to the list of warnings that may be disabled
    by a disable_warnings scope.

    Change code to avoid the new warning.

compiler/goal_expr_to_goal.m:
    Disable the new warning in goals inside a disable_warnings scope
    that asks for it to be disabled.

compiler/parse_goal.m:
    Parse the new warning in disable_warnings scopes.

compiler/prog_out.m:
    Output the new warning in disable_warnings scopes.

compiler/simplify_goal_scope.m:
    Ignore the new warning in disable_warnings scopes, since it is not
    for use here.

library/term_to_xml.m:
    Change code to avoid the new warning.

doc/reference_manual.texi:
doc/user_guide.texi:
    Document the new warning option, and the means of suppressing the
    warning using a disable_warnings scope.

tests/invalid/ambiguous_overloading_error.err_exp:
tests/invalid/max_error_line_width.err_exp:
tests/invalid/occurs.err_exp:
tests/warnings/unify_x_f_x.exp:
    Update these expected outputs to expect the new warning,
    and (in some cases) not to expect its HLDS version.

tests/warnings/occurs.{m,exp}:
    A new test case to test not just the warning (the tests above do that
    already) but also its suppression.

tests/warnings/Mmakefile:
    Enable the new test case.
2019-10-03 10:13:57 +10:00
Zoltan Somogyi
0584bc300d Expand obsolete pragmas with an optional "suggested replacements" field.
doc/reference_manual.texi:
NEWS:
    Document the extension.

compiler/prog_item.m:
    Add a field to the representation of obsolete pragmas to hold
    an optional list of suggested possible replacements.

compiler/parse_pragma.m:
    Parse the optional second argument in obsolete pragmas.

    Improve the error messages we generate for several kinds of errors
    we may encounter when parsing pragmas by making them more specific.

compiler/hlds_pred.m:
    Since an obsolete pragma now contains more than one bit of information
    (present vs not present), change their representation from a simple marker
    to a field containing the possible replacements.

    Make a comment about access stats more useful by sorting its contents
    on frequency of access, and putting it before the structure it is about.

compiler/simplify_goal_call.m:
    When generating warnings about calls to obsolete predicates or functions,
    mention the suggested replacements, if there are any.

compiler/add_pragma.m:
    Fill in the new field when adding an obsolete pragma to the HLDS.

compiler/globals.m:
    Add a function for use by new codee in parse_pragma.m.

compiler/canonicalize_interface.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/hlds_out_pred.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out_pragma.m:
compiler/prog_item_stats.m:
compiler/recompilation.version.m:
compiler/table_gen.m:
    Conform to the changes above.

tests/invalid/bad_foreign_code.err_exp:
tests/invalid/bad_foreign_enum.err_exp:
tests/invalid/bad_foreign_export.err_exp:
    Expect the improved error messages from parse_pragma.m.

tests/warnings/simple_code.{m,exp}:
    Add tests of the new forms of the obsolete pragma.
2019-09-09 13:53:21 +10:00
Zoltan Somogyi
f79b951baa Compute change hunks from diff sequences.
library/edit_seq.m:
    Extend this module with code to compute change hunk sequences
    from diff sequences. Each change hunk contains one or more
    insertions and/or deletions surrounded by a few lines of context.

compiler/style_checks.m:
    Print any differences between declaration and definition order
    using change hunks. This omits the boring parts of the diff.

tests/hard_coded/change_hunk_test.{m,exp}:
    A new test case for the new functionality in edit_seq.m.

tests/hard_coded/Mmakefile:
    Enable the new test case.

tests/hard_coded/edit_seq_test.m:
    Fix the copyright year. (The file was written in 2018, but committed
    in 2019.)

tests/warnings/inconsistent_pred_order.exp:
    Expect the updated output of style_checks.m.
2019-06-28 15:59:40 +02:00
Zoltan Somogyi
e3b07faca4 Use edit_seq to compute decl-order vs defn-order differences.
compiler/style_checks.m:
    When computing differences between the order in which predicates (and
    functions) are declared versus the order in which they are defined,
    use the edit_seq library instead of invoking an external diff process.

    For now at least, we always print the full diff sequence; we do not
    break it up into change hunks, which means we can print long sequences
    of unchanged lines.

compiler/mercury_compile_front_end.m:
    Don't pass the I/O state to style_checks.m, since now it does not need it.

tests/warnings/inconsistent_pred_order.exp:
    Don't expect change hunk headers.
2019-06-27 18:08:49 +02:00
Zoltan Somogyi
b75c509565 Record compiler output in .err even with use_mmc_make.
This fixes most test cases failures in the warning directory
in the C# grade (and probably in Java grade as well).
2019-06-24 20:22:17 +02:00
Zoltan Somogyi
ae64f09e84 Update line numbers in expected test output. 2019-06-18 09:07:51 +02:00
Zoltan Somogyi
4a04a79146 Update line numbers in expected test output. 2019-06-18 00:19:32 +02:00
Zoltan Somogyi
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.
2019-05-01 21:29:05 +10:00
Zoltan Somogyi
30901debf3 Warn about infinite recursive calls inside try goals.
compiler/hlds_goal.m:
    Add a goal feature that is intended to mark lambda goals
    created to implement try goals.

compiler/try_expand.m:
    Add this feature to the lambda goals created to implement try goals.

compiler/simplify_info.m:
    Replace an old counter "number of lambdas we are inside" with a
    slightly different counter "number of non-try lambdas we are inside".
    Move the position of the counter in its structure to reveal
    all the places that must be updated to account for this.

compiler/simplify_goal_unify.m:
    Do NOT increment the changed counter while traversing lambda goals
    that are part of the implementation of try goals.

compiler/simplify_goal_call.m:
    We used to suppress the generation of warnings about infinite recursion
    if we were inside any lambdas. This is because if the code of e.g.
    "p(InArgs, OutArgsA)" constructs a higher order value that contains
    the apparently-infinitely-recursive call "p(InARgs, OutArgsB)",
    the code that calls the new closure may well be *outside* the call tree
    of predicate p, and would thus no longer be recursive.

    However, a closure constructed to implement a try goal *will* be called
    inside the predicate that constructs it. So we now suppress the warning
    only if the number of *non-try* lambdas we are inside is nonzero.
    This is the motive behind the change in semantics in simplify_info.

    This implements feature request Mantis #477.

compiler/simplify_proc.m:
compiler/saved_vars.m:
    Conform to the changes above.

tests/warnings/bug477.{m,exp}:
    A test case for the new functionality.

tests/warnings/Mmakefile:
    Enable the new test.
2019-04-20 12:00:40 +10:00
Zoltan Somogyi
83dc913329 Update the style of the warnings test cases.
tests/warnings/*.m:
    Bring the programming style of these modules up to date,
    except where the problem being tested for seems to be related
    to the old programming style

    In the infinite_recursion test case, add code that we *should*
    warn about, but currently don't.

tests/warnings/*.m:
    Update the expected outputs to account for the changes in line
    numbers, and the fact that the compiler computes the contexts
    of (if C then T else E) if-then-elses differently from (C -> T; E)
    if-then-else (it takes the context of the "then" vs the context
    of the ";").

    Delete arg_order_rearrangment.exp2. It was long unused, but
    deleting it in CVS would not have allowed us to put it back later.
2019-04-20 09:37:37 +10:00
Zoltan Somogyi
7b893150de Include predicate names in warnings about infinite loops.
compiler/simplify_goal_call.m:
    As above.

    Also improve some comments, some predicate names, and formatting,
    as part of a post-commit review.

tests/invalid/loopcheck.err_exp:
tests/warnings/infinite_recursion.exp:
tests/warnings/simple_code.exp:
    Expect the predicate name in infinite loop warnings.

tests/tabling/Mercury.options:
tests/tabling/Mmakefile:
    Disable warning about the infinite loop this test case tests
    not by filtering out lines from the compiler output (which does not
    work anymore due to the predicate name causing the warning to spill
    onto a second line), but by simply asking the compiler not to generate
    the warning.

    Fix an old problem: the Mmakefile action for the loopcheck_nondet test case
    was modifying a file that did not belong to it.
2018-10-24 15:12:58 +11:00
Julien Fischer
e70a5406ad Warn about unsigned comparisons against zero that are tautologies etc.
If --warn-simple-code is enabled, then emit a warning for comparisons of
unsigned integer values against zero if that comparison is a tautology or
contradiction.

compiler/simplify_goal_call.m:
   Implement the new warning.

tests/warnings/Mmakefile:
tests/warnings/unsigned_zero_cmp.{m,exp}:
   Add a test of the new warning.
2018-10-21 03:22:18 +00:00
Julien Fischer
c98af88fa6 Add --warn-suspicious-foreign-code.
This causes the compiler to check the bodies of foreign_code pragmas in a
similar fashion to what --warn-suspicious-foreign-procs does for foreign_proc
pragmas.  Currently, the only check that is performed is for the presence of
MR_ALLOC_ID in the pragma bodies.

compiler/options.m:
     Add the new option.

compiler/add_pragma.m:
compiler/make_hlds_warn.m:
     Implement the new check.

doc/user_guide.texi:
     Document the new option.

tests/warnings/Mmakefile:
tests/warnings/Mercury.options:
tests/warnings/suspicious_foreign_code.{m,exp}:
     Add a test of the new warning.
2018-09-28 14:32:01 +00:00
Zoltan Somogyi
678b226be8 Generate messages for some state var singletons.
compiler/state_var.m:
    Delete redundant copy unifications, whose mere presence can hide the fact
    that the state variable instance being copied is a singleton.

compiler/add_clause.m:
    Conform to the change in state_var.m.

compiler/hlds_goal.m:
    Add a new goal feature for state_var.m to use to identify the copy goals
    inserted by the state var transformation.

    Add a mechanism to add more than feature to a goal at a time.

compiler/saved_vars.m:
    Conform to the change to hlds_goal.m.

compiler/proc_gen.m:
    Fix a singleton ocurrence of a state variable. This problem was hidden
    until the bug fix in state_var.m described above.

tests/warnings/singleton_test_state_var.{m,exp}:
    New regression test to test for the original bug.

tests/warnings/Mmakefile:
    Enable the new test case.
2018-03-09 14:10:50 +11:00
Zoltan Somogyi
05d1c73fb4 Add the flip side of the test I added recently. 2018-02-07 05:26:56 +11:00
Zoltan Somogyi
dfd67afbd7 Rename a warning option to make it fit in with others.
compiler/options.m:
    Rename --inhibit-accumulator-warnings as --no-warn-accumulator-swaps.
    This is better for two reasons: it says explicitly what kinds of warnings
    it talks about (swaps of accumulator arguments may lead to slowdowns),
    and it allows us to treat the option the same as all the other options
    that enable warnings.

    Separate out the lists of warning options into two lists: the style
    and the non-style warnings, now that all these options are positive
    (i.e. they enable options when set).

NEWS:
    Mention the rename.

compiler/accumulator.m:
doc/user_guide.texi:
tests/warnings/arg_order_rearrangment.exp:
    Conform to the rename.
2017-04-24 22:24:33 +10:00
Zoltan Somogyi
7b82c59c40 Remove unneeded module qualifications from error messages.
This should make error messages easier to read by removing clutter.

compiler/error_util.m:
    Split each of the sym_name and sym_name_and_arity error pieces into two;
    one which prints any module qualification present in the given sym_name,
    and one which does not. This forces people who use these pieces
    to think about whether they want the sym_name module qualified
    in the error message or not.

compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_enum.m:
compiler/add_foreign_proc.m:
compiler/add_mode.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pred.m:
compiler/add_type.m:
compiler/check_for_missing_type_defns.m:
compiler/check_promise.m:
compiler/check_raw_comp_unit.m:
compiler/check_typeclass.m:
compiler/det_report.m:
compiler/equiv_type.m:
compiler/format_call.m:
compiler/hlds_error_util.m:
compiler/inst_check.m:
compiler/introduce_parallelism.m:
compiler/make_hlds_error.m:
compiler/make_hlds_passes.m:
compiler/make_tags.m:
compiler/mercury_compile_main.m:
compiler/mode_errors.m:
compiler/modes.m:
compiler/module_qual.qual_errors.m:
compiler/modules.m:
compiler/oisu_check.m:
compiler/parse_inst_mode_defn.m:
compiler/parse_item.m:
compiler/parse_module.m:
compiler/parse_pragma.m:
compiler/parse_type_defn.m:
compiler/polymorphism.m:
compiler/post_term_analysis.m:
compiler/prog_out.m:
compiler/recompilation.check.m:
compiler/resolve_unify_functor.m:
compiler/split_parse_tree_src.m:
compiler/type_constraints.m:
compiler/typecheck_errors.m:
compiler/unused_args.m:
compiler/unused_imports.m:
    Conform to the change above. For sym_name references for which
    the module qualifier is obvious (usually because it *has* to be
    the module being compiled), change the reference to the variant
    that omits that qualifier; otherwise, keep the qualifier.

    In a few places, improve the wording of an error message.

tests/invalid/bad_instance.err_exp:
tests/invalid/bug17.err_exp:
tests/invalid/builtin_int.err_exp:
tests/invalid/foreign_purity_mismatch.err_exp:
tests/invalid/foreign_type_visibility.err_exp:
tests/invalid/fp_dup_bug.err_exp:
tests/invalid/fundeps_vars.err_exp:
tests/invalid/impl_def_literal_syntax.err_exp:
tests/invalid/inline_conflict.err_exp:
tests/invalid/inst_list_dup.err_exp:
tests/invalid/instance_no_type.err_exp:
tests/invalid/invalid_typeclass.err_exp:
tests/invalid/missing_interface_import.err_exp:
tests/invalid/missing_interface_import2.err_exp:
tests/invalid/oisu_check_semantic_errors.err_exp:
tests/invalid/tc_err1.err_exp:
tests/invalid/tc_err2.err_exp:
tests/invalid/transitive_import.err_exp:
tests/invalid/type_with_no_defn.err_exp:
tests/invalid/typeclass_bogus_method.err_exp:
tests/invalid/typeclass_missing_mode_2.err_exp:
tests/invalid/typeclass_test_10.err_exp:
tests/invalid/typeclass_test_3.err_exp:
tests/invalid/typeclass_test_4.err_exp:
tests/invalid/typeclass_test_5.err_exp:
tests/invalid/typeclass_test_9.err_exp:
tests/invalid/types2.err_exp:
tests/invalid/undef_inst.err_exp:
tests/invalid/undef_mode.err_exp:
tests/invalid/undef_mode_and_no_clauses.err_exp:
tests/invalid/undef_type.err_exp:
tests/invalid/undef_type_mod_qual.err_exp:
tests/invalid/uu_type.err_exp:
tests/invalid/where_direct_arg.err_exp:
tests/invalid/where_direct_arg2.err_exp:
tests/invalid/wrong_type_arity.err_exp:
tests/recompilation/add_type_re.err_exp.2:
tests/recompilation/field_r.err_exp.2:
tests/recompilation/remove_type_re.err_exp.2:
tests/warnings/inst_with_no_type.exp:
    Expect the updated versions of error messages.
2017-04-01 20:20:57 +11:00
Zoltan Somogyi
41c2fe79e8 Add a new language construct, the disable_warnings scope.
Its syntax is

    disable_warnings [warning_category1, ...] Goal

Its semantics is identical to Goal's semantics, with the only difference
being that the compiler will not generate warnings belonging to the listed
categories for code inside Goal.

At the moment, we support the disabling of two warning categories:
singleton variable warnings, and warnings about recursive calls that are not
*tail* recursive. However, the documentation of the latter is commented out
until we use the same code for generating such warnings regardless of what
backend generates code.

doc/reference_manual.texi:
    Document the new language extension.

NEWS:
    Mention the new language extension.

library/ops.m:
    Make "disable_warnings" (and its "disable_warning" variant) binary prefix
    operators, as required for the syntax of the new scope.

compiler/prog_item.m:
    Add disable_warnings_expr as a new kind of goal in the parse tree.

compiler/hlds_goal.m:
    Add disable_warnings as a new kind of scope goal in the HLDS.

compiler/prog_data.m:
    Add a type that represents the set of warnings that may be disabled.

    This type cannot be in prog_item.m, because it is needed by the HLDS,
    and we don't want the HLDS to depend on prog_item.m.

compiler/parse_goal.m:
    Parse the new kind of goal, transforming it from source code to parse tree.

compiler/goal_expr_to_goal.m:
    Transform the new kind of goal from parse tree to HLDS.

compiler/prog_out.m:
compiler/parse_tree_out_clause.m:
compiler/hlds_out_goal.m:
    Output the new kinds of parse tree and HLDS goals.

compiler/make_hlds_warn.m:
    Disable singleton variable warnings when the new scope asks for that.

compiler/mark_tail_calls.m:
    Disable warnings about non-tail-recursive recursive calls
    when the new scope asks for that.

    Improve a warning message.

compiler/ml_tailcall.m:
    Document why this sort-of-duplicate implementation of the
    warnings about non-tail-recursive recursive calls cannot respect
    the new scope. (I believe this sort-of-duplicate code should be deleted.)

    Improve the same warning message as in mark_tail_calls.m.

compiler/constraint.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/erl_code_gen.m:
compiler/get_dependencies.m:
compiler/goal_util.m:
compiler/hlds_desc.m:
compiler/interval.m:
compiler/lambda.m:
compiler/modecheck_goal.m:
compiler/module_qual.collect_mq_info.m:
compiler/polymorphism.m:
compiler/prog_item_stats.m:
compiler/prog_util.m:
compiler/purity.m:
compiler/quantification.m:
compiler/saved_vars.m:
compiler/simplify_goal_scope.m:
compiler/simplify_proc.m:
compiler/stm_expand.m:
compiler/switch_detection.m:
compiler/try_expand.m:
compiler/typecheck.m:
compiler/unique_modes.m:
    Handle the new kind of scope.

    In a couple of places, fix comments.

tests/invalid/require_tailrec_1.{m,err_exp}:
    Wrap a disable_warnings scope around one of the non-tail-recursive
    recursive calls we used to get a warning about, and expect that
    we don't get this warning anymore. (We still do get this warning in grades
    that use ml_tailcall.m instead of mark_tail_calls.m to generate such
    warnings, as mentioned above.)

    Specify Mercury syntax highlighting for the source file.
    Expect the improved wording of a warning.

tests/invalid/require_tailrec_2.{m,err_exp}:
    Specify Mercury syntax highlighting for the source file.
    Expect the improved wording of a warning.

tests/warnings/singleton_test.m:
    Add a test of a singleton variable whose warning is disabled.
2017-01-11 02:00:32 +11:00
Zoltan Somogyi
ecf46857c1 Fix warnings for io.format("...", [...], !IO).
The code I added recently to implement --warn-implicit-stream-calls
generated misleading messages for calls to io.format/3 and its
stream.string_writer.put cousin, because these calls are transformed
into other code by format_call.m before the main simplification pass
ever sees them. For example, calls to io.format/4 are transformed
into code that figures out what to print and then calls io.write_string/3.

Since format_call.m is called before the main simplification pass for a good
reason, the fix is to make format_call.m itself generate the warnings based
on the as-yet-untransformed code.

compiler/format_call.m:
    As above. Also, mark the calls in the transformed code that could possibly
    get the warning from simplify_goal_call.m with a new feature.

    Delete some dead code, and use a bespoke type to avoid ambiguity.

compiler/simplify_goal_call.m:
    Export to format_call.m the code that generates the warning if
    warranted. Make this code respect format_call.m's feature to avoid
    generating redundant and misleading error messages.

compiler/simplify_proc.m:
    Tell format_call.m whether it should try to generate these warnings.

compiler/hlds_goal.m:
    Add the goal feature that format_call.m uses to tell simplify_goal_call.m
    not generate would-be-redundant warnings for code generated by
    format_call.m.

compiler/saved_vars.m:
    Conform to the change to hlds_goal.m.

tests/warnings/save.{m,exp}:
    Change the test case for --warn-implicit-stream-call to test warnings
    for io.format too.
2016-10-17 20:54:03 +11:00
Zoltan Somogyi
93fea7de37 Address Julien's review comments about the new warnings.
compiler/options.m:
doc/user_guide.texi:
    Change the option --warn-no-stream-calls to --warn-implicit-stream-calls.

    Add a new option, --inhibit-style-warnings, that does what its name says.

    Fix the old option --inhibit-warnings, which was missing code to turn off
    a significant number of warning options.

    Document where new options may need changes. This may help avoid problems
    such as non-updates to --inhibit-warnings when new warning options are
    added.

NEWS:
    Change the announcement of --warn-no-stream-calls to refer to its new name.

    Announce --inhibit-style-warnings.

    Announce --warn-non-contiguous-decls and --warn-inconsistent-pred-order*
    as well, since the diff that added them did not do so.

compiler/simplify_goal_call.m:
compiler/simplify_info.m:
compiler/simplify_tasks.m:
    Change the compiler-internal names that used to refer to
    --warn-no-stream-calls to refer to its new name instead.

tests/warnings/Mercury.options:
    Specify the new name of --warn-no-stream-calls for the test of the
    option's functionality.

doc/Mmakefile:
    Make doc/mmc.1 depend on compiler/options.m, since if that changes,
    then the help message that mmc.1 is derived from may have changed as well.
2016-10-15 22:54:34 +11:00