Files
mercury/tests/recompilation/two_module_debug
Zoltan Somogyi b4464a4ff7 Enforce either all types only, or all types/modes.
compiler/prog_item.m:
    Predicate declarations have a slot for describing the arguments
    of the predicate (or function). The type of this slot allowed
    the representation of an argument list in which some arguments
    contained only a type, but others contained both a type and a mode.

    Change this to a representation that enforces the invariant that
    - either all arguments contain only types
    - or all arguments contain both types and modes.

    Add a third alternative to this type, which describes predicate
    declarations that contain NO visible arguments. The correct handling
    of this kind of predicate is far from trivial, due to the possible
    presence of with_type and with_inst annotations; adding this alternative
    requires det code dealing with argument lists to include a switch arm
    dealing with this situation specifically.

    Move this types here from prog_data.m, since it is used only during
    the initial construction of the HLDS. Likewise, move a utility operation
    on this type here from prog_util.m.

    Add some other utility operations on this type. One of them,
    get_declared_types_and_maybe_modes, factors out what used to be
    repeated code in other modules. It contains a fix for what seem to be some
    not-tested-for bugs in the old code's handling of arity-zero predicates.
    This fix is commented out due to a limitation in the syntax rules
    of the language. Document this issue.

compiler/parse_item.m:
compiler/parse_type_name.m:
    Enforce the invariant when constructing item_pred_decl_infos.

    Add indentation to an error message (which the test suite does not test).

compiler/add_pred.m:
    Update the logic of when an item_pred_decl_info represents a predmode
    declaration, and thus requires adding a mode to the HLDS as well.

compiler/recompilation.version.m:
    Update the logic of when an item_pred_decl_info represents a predmode
    declaration, and thus requires checking whether the mode information
    has changed since the last version.

compiler/equiv_type.m:
    Update and simplify the code that checks with_type and with_inst
    annotations for consistency.

    Update the wording of an error message. Stop module qualifying
    the predicate name involved in the error, since it is implicit
    in the context of the error message, and therefore hurts more
    as clutter than it helps.

    Fix a misleading predicate name.

compiler/prog_mode.m:
    Change the interface of a predicate to generate an error message
    unconditionally, not conditionally.

    Shorten some predicate names.

compiler/prog_data.m:
compiler/prog_util.m:
    Delete the stuff moved to prog_item.m.

compiler/parse_tree_out_pred_decl.m:
    Fix a quoting issue that are arises if the fix for the handling of
    arity-zero predicates is *not* commented out.

compiler/add_class.m:
compiler/add_pragma_tabling.m:
compiler/add_solver.m:
compiler/canonicalize_interface.m:
compiler/handle_options.m:
compiler/intermod.m:
compiler/make_hlds_passes.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out.m:
compiler/prog_mutable.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
    Conform to the changes above.

tests/invalid_nodepend/test_with_type.err_exp:
    Expect the updated error message from equiv_type.m.

tests/invalid_nodepend/invalid_float_literal.err_exp:
    Expect the fix in declaration formatting from parse_tree_out_pred_decl.m.

tests/recompilation/two_module_debug:
    Update this debug script to help debug this diff.

tests/recompilation/unchanged_with_type_nr_2.m.2:
    Fix an old inadvertent white space change.
2023-11-18 22:20:39 +11:00

221 lines
7.6 KiB
Bash
Executable File

#!/bin/sh
# vim: ts=4 sw=4 expandtab ft=sh
#
# A version of two_module_test that should be more useful for debugging,
# because instead of hiding the action behind shell functions, it exposes
# the details of each step. This allows a Mercury developer to (temporarily)
# modify this script to observe not just the final result of a call to a shell
# function, but also its intermediate results, e.g. by copying files
# suspected to be constructed incorrectly to safe locations before later steps
# overwrite them. It also allows running some compiler invocations under mdb.
# When you suspect, or know, that a step is screwing up, this can be extremely
# helpful. Smart recompilation is NOT idempotent; executing even part of
# a compiler invocation (until e.g. a compiler abort) can, and often will,
# change the contents of files in a way that will cause later, seeming
# identical compiler invocations to take a different execution path.
# By rerunning the whole test process from the start, recreating all
# the relevant files from scratch each time, this script can sidestep
# that problem.
#
# This script also has some limitations compared with two_module_test.
# The main one is that it covers only grades that target C.
# It also handles the <mmake_test 2 should_fail> block differently
# than two_module_test.
# It is easier to look up the contents of e.g. .used files
# if they are in the current directory.
/bin/rm -fr Mercury
test_prog="unchanged_with_type_nr"
expected_mmake_result=should_succeed
module_1="${test_prog}"
module_2="${test_prog}_2"
modules="${module_1} ${module_2}"
tested_compiler="/home/zs/ws/ws31/compiler/mercury_compile"
MERCURY_COMPILER="${tested_compiler}"
export MERCURY_COMPILER
grade_opts="--grade hlc.gc"
dir_opts="--flags ../TESTS_FLAGS"
opt_opts="--no-intermodule-optimization"
smart_opts="--smart-recompilation --find-all-recompilation-reasons"
std_opts="${grade_opts} ${dir_opts} ${opt_opts} ${smart_opts}"
echo "Testing ${test_prog}"
echo "block <test_module ${module_1} ${module_2}>"
rm -f "${module_1}.m"
cp "${module_1}.m.1" "${module_1}.m"
chmod -w "${module_1}.m"
rm -f "${module_2}.m"
cp "${module_2}.m.1" "${module_2}.m"
chmod -w "${module_2}.m"
rm -f "${module_1}.res"
touch "${module_1}.res"
sleep 1
echo "block <mmake_depend>"
mmc --generate-dependencies ${std_opts} ${module_1} > ${module_1}.dep_err 2>&1
echo "block <mmake_test 1 should_succeed>"
mmc --make-short-interface ${std_opts} ${module_2}
mmc --make-interface ${std_opts} ${module_2}
mmc --make-interface ${std_opts} ${module_1}
mmc --compile-to-c ${std_opts} ${module_1} > ${module_1}.err 2>&1
mmc --compile-to-c ${std_opts} ${module_2} > ${module_2}.err 2>&1
cp -f ${module_2}.int ${module_2}.int.step1
cp -f ${module_2}.used ${module_2}.used.step1
mgnuc ${grade_opts} -- -c ${module_1}.c -o ${module_1}.o
mgnuc ${grade_opts} -- -c ${module_2}.c -o ${module_2}.o
ml ${grade_opts} -- -o ${module_1} ${module_1}_init.o \
${module_1}.o ${module_2}.o
case "$?" in
0)
;;
*)
echo "exiting due to failure of <mmake_test 1 should_succeed>"
exit 1
;;
esac
exp_file="${module_1}.exp.1"
res_file="${module_1}.out"
./${module_1} > "${res_file}"
# We assume ${exp_file} exists.
if diff ${DIFF_OPTS-"-c"} "${exp_file}" "${res_file}" >> "${module_1}.res"
then
true
else
echo "** Error in mmake_test 1 should_succeed: ${exp_file} and ${res_file} differ."
cat "${module_1}.res"
exit 1
fi
echo "block <update_module ${module_2} 2>"
sleep 1
rm -f "${module_2}.m"
cp "${module_2}.m.2" "${module_2}.m"
chmod -w "${module_2}.m"
sleep 1
case "${expected_mmake_result}" in
should_succeed)
echo "block <mmake_test 2 should_succeed>"
mmc --make-short-interface ${std_opts} ${module_2}
mmc --make-interface ${std_opts} ${module_2}
mmc --make-interface ${std_opts} ${module_1}
cp -f ${module_2}.int ${module_2}.int.step2
cp -f ${module_2}.used ${module_2}.used.step2
# mdb mmc --compile-to-c ${std_opts} ${module_1}
mmc --compile-to-c ${std_opts} ${module_1} \
> ${module_1}.err 2>&1
echo --- ${module_1}.err ---
cat ${module_1}.err
echo status = $?
exit 0
mmc --compile-to-c ${std_opts} ${module_2} \
> ${module_2}.err 2>&1
mgnuc ${grade_opts} -- -c ${module_1}.c -o ${module_1}.o
mgnuc ${grade_opts} -- -c ${module_2}.c -o ${module_2}.o
ml ${grade_opts} -- -o ${module_1} ${module_1}_init.o \
${module_1}.o ${module_2}.o
case "$?" in
0)
;;
*)
echo "Error: <mmake_test 2 should_succeed> has failed"
exit 1
;;
esac
exp_file="${module_1}.exp.2"
res_file="${module_1}.out"
./${module_1} > "${res_file}"
# We assume ${exp_file} exists.
if diff ${DIFF_OPTS-"-c"} "${exp_file}" "${res_file}" \
>> "${module_1}.res"
then
true
else
echo "** Error in mmake_test 2 should_succeed: ${exp_file} and ${res_file} differ."
cat "${module_1}.res"
exit 1
fi
;;
should_fail)
echo "block <mmake_test 2 should_fail>"
> "${module_1}.should_fail"
( \
mmc --make-short-interface ${std_opts} ${module_2}; \
if test "$?" != 0; \
then \
echo "failure" >> "${module_1}.should_fail"; \
fi; \
mmc --make-interface ${std_opts} ${module_2}; \
if test "$?" != 0; \
then \
echo "failure" >> "${module_1}.should_fail"; \
fi; \
mmc --make-interface ${std_opts} ${module_1}; \
if test "$?" != 0; \
then \
echo "failure" >> "${module_1}.should_fail"; \
fi; \
mmc --compile-to-c ${std_opts} ${module_1} \
> ${module_1}.err 2>&1; \
if test "$?" != 0; \
then \
echo "failure" >> "${module_1}.should_fail"; \
fi; \
mmc --compile-to-c ${std_opts} ${module_2} \
> ${module_2}.err 2>&1; \
if test "$?" != 0; \
then \
echo "failure" >> "${module_1}.should_fail"; \
fi; \
) > "${module_1}.failing_make_output"
if test ! -s "${module_1}.should_fail)"
then
echo "Error: <mmake_test 2 should_fail> has succeeded"
exit 1
fi
;;
*)
echo "** Error: bad expected_mmake_result ${expected_mmake_result}"
exit 1
;;
esac
echo "block <check_err_file ${module_1} 2>"
sed -e '/has CHANGED/d' -e 's/Mercury\/.*\///g' "${module_1}.err" \
> "${module_1}.err2"
mv "${module_1}.err2" "${module_1}.err"
exp_file="${module_1}.err_exp.2"
res_file="${module_1}.err"
# We assume ${exp_file} exists.
if diff ${DIFF_OPTS-"-c"} "${exp_file}" "${res_file}" >> "${module_1}.res"
then
true
else
echo "** Error in check_err_file ${module_1} 2: ${exp_file} and ${res_file} differ."
cat "${module_1}.res"
exit 1
fi
echo "block <check_err_file ${module_2} 2>"
sed -e '/has CHANGED/d' -e 's/Mercury\/.*\///g' "${module_2}.err" \
> "${module_2}.err2"
mv "${module_2}.err2" "${module_2}.err"
exp_file="${module_2}.err_exp.2"
res_file="${module_2}.err"
# We assume ${exp_file} exists.
if diff ${DIFF_OPTS-"-c"} "${exp_file}" "${res_file}" >> "${module_2}.res"
then
true
else
echo "** Error in check_err_file ${module_2} 2: ${exp_file} and ${res_file} differ."
cat "${module_2}.res"
exit 1
fi
exit 0