Print two kinds of ambiguities only if asked for.

trace/mercury_trace_cmd_developer.c:
trace/mercury_trace_tables.[ch]:
    Add two options to the mdb command "ambiguity".

    Print ambiguities between function and predicate forms of the same
    operation, such as list.length, only if the new option -b, or
    --both-pred-and-func, is given.

    Print ambiguities involving procedures that were created by type
    specialization only if the new option -s, or --typespec is given.
    (The -t option name was already taken.)

    These changes remove from the ambiguity command's output
    (some of) the parts that are not useful when one wants to eliminate
    ambiguities by renaming.

    Clarify a heading.

doc/user_guide.texi:
    Document the above changes.

runtime/mercury_proc_id.h:
    Fix a field name that has become misleading.

    MR_UserProcId_Structs have a field named MR_user_arity.
    In this name, the "MR_user_" part is a prefix shared by the other
    fields in that structure, to indicate that they are part of the id
    of a user-defined procedure, as opposed to a compiler-created
    unify, compare or index procedure. However, the arity it contains
    is what the compiler now calls a pred_form_arity: it does not count
    type_info and typeclass_info arguments added by polymorphism, but
    it *does* count function return values for functions. This is now
    misleading, because in the compiler, a user_arity does *not* count
    function return values for functions.

    Replace this field name with MR_user_pred_form_arity, which tells
    readers that this arity is a pred_form_arity. The presence of the
    "user" part of the name may still cause some confusion, but at least
    that confusion should motivate readers to look up the field name,
    whose comment should clarify things.

mdbcomp/rtti_access.m:
runtime/mercury_debug.c:
runtime/mercury_deep_profiling.c:
runtime/mercury_ho_call.c:
runtime/mercury_layout_util.c:
runtime/mercury_ml_expand_body.h:
runtime/mercury_stack_layout.h:
runtime/mercury_trace_base.c:
trace/mercury_trace.c:
trace/mercury_trace_external.c:
trace/mercury_trace_util.c:
    Conform to the change in mercury_proc_id.h.

tests/debugger/ambiguity.{m,inp,exp}:
tests/debugger/ambiguity_helper.m:
    Expand this test case to test the new functionality.
    The type specialized predicates are in a new helper module,
    because this is the simplest way to avoid dead procedure elimination
    deleting any of the predicates whose names we want to test for ambiguities.
This commit is contained in:
Zoltan Somogyi
2022-07-05 08:00:12 +10:00
parent 40401a6b5c
commit e35a09542e
20 changed files with 338 additions and 53 deletions

View File

@@ -4768,7 +4768,7 @@ the list will include the procedures of
compiler generated unify, compare, index and initialization predicates.
Normally, the list includes the procedures of only user defined predicates.
@sp 1
@item ambiguity [-o @var{filename}] [-ptf] [@var{modulename} @dots{}]
@item ambiguity [-o @var{filename}] [-ptfbs] [@var{modulename} @dots{}]
@kindex ambiguity (mdb command)
Print ambiguous procedure, type constructor and/or function symbol names.
A procedure name is ambiguous
@@ -4794,14 +4794,46 @@ If the @samp{-o} or @samp{--outputfile} option is given,
the output goes to the file named as the argument of the option;
otherwise, it goes to standard output.
@sp 1
If one or more of the @samp{-p}, @samp{-t}, @samp{-f} options
or their long equivalents, @samp{--types}, or @samp{--functors},
If given one or more of the @samp{-p}, @samp{-t} and @samp{-f} options,
or their long equivalents
@samp{--procedures}, @samp{--types}, and @samp{--functors},
this command prints ambiguities only for the indicated kinds of constructs.
The default is to print all ambiguities.
The default is to print ambiguities for all these three kinds of constructs.
@sp 1
This command does not normally report
two kinds of ambiguities among procedures.
@sp 1
First, this command does not usually report
operations that have both function and predicate forms,
with the predicate version having a (usually output) argument
in place of the function's return value.
An example is @code{list.length} being both a function with arity one
and a predicate with arity two.
The reason for not reporting this by default is that
this is usually an @emph{intended} ambiguity,
and this command is usually used to find @emph{unintended} ambiguities,
so that they can be eliminated by renaming.
However, users can ask for these ambiguities to be printed
by specifying either the option @samp{-b},
or its long form @samp{--both-pred-and-func}.
@sp 1
Second, this command does not usually report
ambiguities involving procedures that were created by the compiler
as a type specialized version of another procedure.
The reason for not reporting this by default is that
ambiguities among the names of type specialized procedures
cannot arise without ambiguities among
the names of the original, not-yet-type-specialized procedures,
and eliminating the ambiguities among the original names
will perforce eliminate the ambiguities among the specialized names as well.
However, users can ask for these ambiguities to be printed
by specifying either the option @samp{-s},
or its long form @samp{--typespec}.
@sp 1
@item trail_details
@kindex trail_details (mdb command)
Prints out low-level details of the state of the trail.
In grades that specify trailing,
prints out low-level details of the state of the trail.
In other grades, it reports an error.
@end table

View File

@@ -336,7 +336,7 @@ get_proc_name(special_proc_label(_, _, _, ProcName , _, _)) = ProcName.
DeclModule = (MR_String) (MR_Integer) proc_id->MR_user_decl_module;
DefModule = (MR_String) (MR_Integer) proc_id->MR_user_def_module;
PredName = (MR_String) (MR_Integer) proc_id->MR_user_name;
Arity = proc_id->MR_user_arity;
Arity = proc_id->MR_user_pred_form_arity;
ModeNum = proc_id->MR_user_mode;
").
@@ -544,8 +544,8 @@ get_proc_name(special_proc_label(_, _, _, ProcName , _, _)) = ProcName.
selected_proc_id->MR_user_decl_module)
&& MR_streq(proc_id->MR_user_name,
selected_proc_id->MR_user_name)
&& (proc_id->MR_user_arity ==
selected_proc_id->MR_user_arity))
&& (proc_id->MR_user_pred_form_arity ==
selected_proc_id->MR_user_pred_form_arity))
{
match = MR_TRUE;
} else {

View File

@@ -1095,7 +1095,7 @@ MR_print_deep_prof_var(FILE *fp, const char *name, MR_CallSiteDynamic *csd)
fprintf(fp, " %s.%s/%d-%d\n ",
proc_id->MR_proc_user.MR_user_decl_module,
proc_id->MR_proc_user.MR_user_name,
proc_id->MR_proc_user.MR_user_arity,
proc_id->MR_proc_user.MR_user_pred_form_arity,
proc_id->MR_proc_user.MR_user_mode);
}

View File

@@ -892,7 +892,7 @@ MR_write_out_proc_static(FILE *deep_fp, FILE *procrep_fp,
procid->MR_proc_user.MR_user_decl_module,
procid->MR_proc_user.MR_user_def_module,
procid->MR_proc_user.MR_user_name,
procid->MR_proc_user.MR_user_arity,
procid->MR_proc_user.MR_user_pred_form_arity,
procid->MR_proc_user.MR_user_mode);
}
@@ -959,7 +959,7 @@ MR_write_out_proc_static(FILE *deep_fp, FILE *procrep_fp,
procid->MR_proc_user.MR_user_decl_module,
procid->MR_proc_user.MR_user_def_module,
procid->MR_proc_user.MR_user_name,
procid->MR_proc_user.MR_user_arity,
procid->MR_proc_user.MR_user_pred_form_arity,
procid->MR_proc_user.MR_user_mode);
}
@@ -1097,7 +1097,7 @@ MR_write_out_str_proc_label(FILE *deep_fp, const MR_ProcId *procid)
procid->MR_proc_user.MR_user_decl_module,
procid->MR_proc_user.MR_user_def_module,
procid->MR_proc_user.MR_user_name,
procid->MR_proc_user.MR_user_arity,
procid->MR_proc_user.MR_user_pred_form_arity,
procid->MR_proc_user.MR_user_mode);
}
#endif
@@ -1111,7 +1111,7 @@ MR_write_out_str_proc_label(FILE *deep_fp, const MR_ProcId *procid)
MR_write_string(deep_fp, procid->MR_proc_user.MR_user_decl_module);
MR_write_string(deep_fp, procid->MR_proc_user.MR_user_def_module);
MR_write_string(deep_fp, procid->MR_proc_user.MR_user_name);
MR_write_num(deep_fp, procid->MR_proc_user.MR_user_arity);
MR_write_num(deep_fp, procid->MR_proc_user.MR_user_pred_form_arity);
MR_write_num(deep_fp, procid->MR_proc_user.MR_user_mode);
}
}
@@ -1872,7 +1872,7 @@ MR_unwritten_pl_handler(FILE *fp, const void *pl)
procid->MR_proc_user.MR_user_decl_module,
procid->MR_proc_user.MR_user_def_module,
procid->MR_proc_user.MR_user_name,
procid->MR_proc_user.MR_user_arity,
procid->MR_proc_user.MR_user_pred_form_arity,
procid->MR_proc_user.MR_user_mode);
}
}

View File

@@ -931,7 +931,7 @@ MR_make_closure(MR_Code *proc_addr)
"unknown";
closure_id->MR_closure_proc_id.MR_proc_user.MR_user_def_module = "unknown";
closure_id->MR_closure_proc_id.MR_proc_user.MR_user_name = "unknown";
closure_id->MR_closure_proc_id.MR_proc_user.MR_user_arity = -1;
closure_id->MR_closure_proc_id.MR_proc_user.MR_user_pred_form_arity = -1;
closure_id->MR_closure_proc_id.MR_proc_user.MR_user_mode = -1;
closure_id->MR_closure_module_name = "dl";
closure_id->MR_closure_file_name = __FILE__;

View File

@@ -1025,7 +1025,8 @@ MR_generate_proc_name_from_layout(const MR_ProcLayout *proc_layout,
*is_func_ptr = MR_BOOL_NO;
} else {
*proc_name_ptr = proc_layout->MR_sle_proc_id.MR_proc_user.MR_user_name;
*arity_ptr = proc_layout->MR_sle_proc_id. MR_proc_user.MR_user_arity;
*arity_ptr = proc_layout->MR_sle_proc_id.
MR_proc_user.MR_user_pred_form_arity;
if (proc_layout->MR_sle_user.MR_user_pred_or_func == MR_FUNCTION) {
*is_func_ptr = MR_BOOL_YES;
} else {
@@ -1049,7 +1050,7 @@ MR_proc_id_arity_addedargs_predfunc(const MR_ProcLayout *proc, int *arity_ptr,
*arity_ptr = proc->MR_sle_num_head_vars - *num_added_args_ptr;
*pred_or_func_ptr = MR_PREDICATE;
} else {
*arity_ptr = proc->MR_sle_user.MR_user_arity;
*arity_ptr = proc->MR_sle_user.MR_user_pred_form_arity;
*num_added_args_ptr = proc->MR_sle_num_head_vars - *arity_ptr;
*pred_or_func_ptr = proc->MR_sle_user.MR_user_pred_or_func;
}

View File

@@ -1275,7 +1275,7 @@ EXPAND_FUNCTION_NAME(MR_TypeInfo type_info, MR_Word *data_word_ptr,
#ifdef EXPAND_FUNCTOR_FIELD
proc_id = &closure_layout->MR_closure_id->MR_closure_proc_id;
if (proc_id->MR_proc_user.MR_user_arity < 0) {
if (proc_id->MR_proc_user.MR_user_pred_form_arity < 0) {
name = "dynlink_proc"; // XXX
} else if (MR_PROC_ID_IS_UCI(*proc_id)) {
name = proc_id->MR_proc_uci.MR_uci_pred_name;

View File

@@ -52,7 +52,11 @@ struct MR_UserProcId_Struct {
MR_ConstString MR_user_decl_module;
MR_ConstString MR_user_def_module;
MR_ConstString MR_user_name;
MR_int_least16_t MR_user_arity;
// The arity stored in this field is what the compiler calls
// a pred_form_arity, i.e. an arity that includes the return value
// for functions. It does not include non-user-visible arguments, such as
// any type_info and/or typeclass_info arguments added by polymorphism.
MR_int_least16_t MR_user_pred_form_arity;
MR_int_least16_t MR_user_mode;
};

View File

@@ -1143,7 +1143,7 @@ typedef struct MR_ProcLayout_Traversal_Struct {
// Adjust the arity of functions for printing.
#define MR_sle_user_adjusted_arity(entry) \
((entry)->MR_sle_user.MR_user_arity - \
((entry)->MR_sle_user.MR_user_pred_form_arity - \
(((entry)->MR_sle_user.MR_user_pred_or_func == MR_FUNCTION) ? 1 : 0))
#define MR_MAX_VARNAME_SIZE 160

View File

@@ -533,7 +533,8 @@ MR_trace_write_label_exec_counts_for_file(FILE *fp,
fputc(' ', fp);
MR_trace_write_quoted_atom(fp, id->MR_user_name);
fprintf(fp, " %d %d\n", id->MR_user_arity, id->MR_user_mode);
fprintf(fp, " %d %d\n",
id->MR_user_pred_form_arity, id->MR_user_mode);
}
port = label->MR_sll_port;

View File

@@ -1,4 +1,4 @@
E1: C1 CALL pred ambiguity.main/2-0 (det) ambiguity.m:28
E1: C1 CALL pred ambiguity.main/2-0 (det) ambiguity.m:38
mdb> echo on
Command echo enabled.
mdb> register --quiet
@@ -19,7 +19,7 @@ ambiguity.t/1
Total: 1 names used 2 times, maximum 2, average: 2.00
Ambiguous function symbols:
Ambiguous function symbol names:
t1/0 ambiguity.t/0
t1/1 ambiguity.t2/0
@@ -30,8 +30,52 @@ u1/1 ambiguity.t2/0
Total: 2 names used 5 times, maximum 3, average: 2.50
mdb> ambiguity -p ambiguity_helper
Ambiguous procedure names:
pred ambiguity_helper.get_length_sum/3
pred ambiguity_helper.get_length_sum/5
Total: 1 names used 2 times, maximum 2, average: 2.00
mdb> ambiguity -pb ambiguity_helper
Ambiguous procedure names:
pred ambiguity_helper.add_float/3
func ambiguity_helper.add_float/2
pred ambiguity_helper.add_int/3
func ambiguity_helper.add_int/2
pred ambiguity_helper.get_length_sum/3
pred ambiguity_helper.get_length_sum/5
Total: 3 names used 6 times, maximum 2, average: 2.00
mdb> ambiguity -pbs ambiguity_helper
Ambiguous procedure names:
pred ambiguity_helper.TypeSpecOf__pred__get_length_sum__[T = float]_0_1/3
pred ambiguity_helper.TypeSpecOf__pred__get_length_sum__[T = float]_0_1/5
pred ambiguity_helper.TypeSpecOf__pred__get_length_sum__[T = int]_0_1/3
pred ambiguity_helper.TypeSpecOf__pred__get_length_sum__[T = int]_0_1/5
pred ambiguity_helper.add_float/3
func ambiguity_helper.add_float/2
pred ambiguity_helper.add_int/3
func ambiguity_helper.add_int/2
pred ambiguity_helper.get_length_sum/3
pred ambiguity_helper.get_length_sum/5
Total: 5 names used 10 times, maximum 2, average: 2.00
mdb> continue
2.5
t1
u2(42)
1
8
13.2

View File

@@ -1,4 +1,7 @@
echo on
register --quiet
ambiguity ambiguity
ambiguity -p ambiguity_helper
ambiguity -pb ambiguity_helper
ambiguity -pbs ambiguity_helper
continue

View File

@@ -12,6 +12,14 @@
:- implementation.
:- import_module ambiguity_helper.
:- import_module float.
:- import_module int.
:- import_module list.
%---------------------%
:- type t
---> t1
; t2.
@@ -25,16 +33,26 @@
---> u1
; u2(T).
%---------------------%
main(!IO) :-
io.write(p(2.5), !IO),
io.nl(!IO),
io.write(p(1, t1), !IO),
io.nl(!IO),
io.write(p(0, 1, u2(42)), !IO),
io.nl(!IO),
io.write_line(p(2.5), !IO),
io.write_line(p(1, t1), !IO),
io.write_line(p(0, 1, u2(42)), !IO),
p(1, X),
io.write(X, !IO),
io.nl(!IO).
io.write_line(X, !IO),
ListA = [1, 2],
ListB = [3.0, 4.0, 5.0],
get_length_sum(ListA, SumA, LenA),
get_length_sum_via_acc(ListB, _SumB, LenB),
add_int(SumA, add_int(LenA, LenB), TotalInt),
io.write_line(TotalInt, !IO),
add_float(3.3, add_float(4.4, 5.5), TotalFloat),
io.write_line(TotalFloat, !IO).
%---------------------%
:- func p(float) = float.

View File

@@ -0,0 +1,92 @@
%---------------------------------------------------------------------------%
% vim: ts=4 sw=4 et ft=mercury
%---------------------------------------------------------------------------%
:- module ambiguity_helper.
:- interface.
:- import_module list.
:- pred zero_int(int::out) is det.
:- pred add_int(int::in, int::in, int::out) is det.
:- func add_int(int, int) = int.
:- pred zero_float(float::out) is det.
:- pred add_float(float::in, float::in, float::out) is det.
:- func add_float(float, float) = float.
:- typeclass summable(T) where [
(pred zero(T::out) is det),
(pred sum(T::in, T::in, T::out) is det)
].
:- instance summable(int).
:- instance summable(float).
:- pred get_length_sum(list(T)::in, T::out, int::out) is det
<= summable(T).
:- pragma type_spec(pred(ambiguity_helper.get_length_sum/3), T = int).
:- pragma type_spec(pred(ambiguity_helper.get_length_sum/3), T = float).
:- pred get_length_sum_via_acc(list(T)::in, T::out, int::out) is det
<= summable(T).
:- pragma type_spec(pred(ambiguity_helper.get_length_sum_via_acc/3), T = int).
:- pragma type_spec(pred(ambiguity_helper.get_length_sum_via_acc/3), T = float).
%---------------------------------------------------------------------------%
:- implementation.
:- import_module float.
:- import_module int.
:- instance summable(int) where [
pred(zero/1) is zero_int,
pred(sum/3) is add_int
].
:- instance summable(float) where [
pred(zero/1) is zero_float,
pred(sum/3) is add_float
].
%---------------------%
zero_int(0).
add_int(A, B, A + B).
add_int(A, B) = A + B.
%---------------------%
zero_float(0.0).
add_float(A, B, A + B).
add_float(A, B) = A + B.
%---------------------%
get_length_sum([], Sum, 0) :-
zero(Sum).
get_length_sum([Head | Tail], Sum, Len) :-
get_length_sum(Tail, TailSum, TailLen),
sum(Head, TailSum, Sum),
Len = 1 + TailLen.
get_length_sum_via_acc(List, Sum, Len) :-
zero(Sum0),
get_length_sum(List, Sum0, Sum, 0, Len).
:- pred get_length_sum(list(T)::in, T::in, T::out, int::in, int::out) is det
<= summable(T).
:- pragma type_spec(pred(ambiguity_helper.get_length_sum/5), T = int).
:- pragma type_spec(pred(ambiguity_helper.get_length_sum/5), T = float).
get_length_sum([], !Sum, !Len).
get_length_sum([Head | Tail], !Sum, !Len) :-
get_length_sum(Tail, !Sum, !Len),
sum(Head, !.Sum, !:Sum),
!:Len = 1 + !.Len.

View File

@@ -1621,7 +1621,7 @@ MR_maybe_record_call_table(const MR_ProcLayout *level_layout,
user = &level_layout->MR_sle_user;
if (MR_streq(user->MR_user_decl_module, "exception") &&
MR_streq(user->MR_user_name, "builtin_catch") &&
(user->MR_user_arity == 3))
(user->MR_user_pred_form_arity == 3))
{
// builtin_catch doesn't fill in the MR_sle_exec_trace
// field, but we know its evaluation method, so we return.

View File

@@ -234,7 +234,8 @@ static MR_bool MR_trace_options_all_procedures(MR_bool *separate,
int *word_count);
static MR_bool MR_trace_options_ambiguity(const char **outfile,
MR_bool *print_procs, MR_bool *print_types,
MR_bool *print_functors, char ***words,
MR_bool *print_functors, MR_bool *print_typespec_of,
MR_bool *print_pred_and_func, char ***words,
int *word_count);
////////////////////////////////////////////////////////////////////////////
@@ -1271,6 +1272,8 @@ MR_trace_cmd_ambiguity(char **words, int word_count,
MR_bool print_procs;
MR_bool print_types;
MR_bool print_functors;
MR_bool print_typespec_of;
MR_bool print_pred_and_func;
FILE *fp;
char errbuf[MR_STRERROR_BUF_SIZE];
@@ -1278,8 +1281,11 @@ MR_trace_cmd_ambiguity(char **words, int word_count,
print_procs = MR_FALSE;
print_types = MR_FALSE;
print_functors = MR_FALSE;
print_typespec_of = MR_FALSE;
print_pred_and_func = MR_FALSE;
if (! MR_trace_options_ambiguity(&filename, &print_procs, &print_types,
&print_functors, &words, &word_count))
&print_functors, &print_typespec_of, &print_pred_and_func,
&words, &word_count))
{
// The usage message has already been printed.
;
@@ -1310,7 +1316,7 @@ MR_trace_cmd_ambiguity(char **words, int word_count,
// ambiguities.
MR_print_ambiguities(fp, print_procs, print_types, print_functors,
&words[1], word_count - 1);
print_typespec_of, print_pred_and_func, &words[1], word_count - 1);
if (filename != NULL) {
fprintf(MR_mdb_out, "mdb: wrote report to `%s'.\n", filename);
@@ -2228,22 +2234,24 @@ MR_trace_options_all_procedures(MR_bool *separate, MR_bool *uci, char **module,
static struct MR_option MR_trace_ambiguity_opts[] =
{
{ "outputfile", MR_required_argument, NULL, 'o' },
{ "procedures", MR_no_argument, NULL, 'p' },
{ "types", MR_no_argument, NULL, 't' },
{ "functors", MR_no_argument, NULL, 'f' },
{ NULL, MR_no_argument, NULL, 0 }
{ "outputfile", MR_required_argument, NULL, 'o' },
{ "procedures", MR_no_argument, NULL, 'p' },
{ "types", MR_no_argument, NULL, 't' },
{ "functors", MR_no_argument, NULL, 'f' },
{ "typespec", MR_no_argument, NULL, 's' },
{ "both-pred-and-func", MR_no_argument, NULL, 'b' },
{ NULL, MR_no_argument, NULL, 0 }
};
static MR_bool
MR_trace_options_ambiguity(const char **outfile, MR_bool *print_procs,
MR_bool *print_types, MR_bool *print_functors, char ***words,
int *word_count)
MR_bool *print_types, MR_bool *print_functors, MR_bool *print_typespec_of,
MR_bool *print_pred_and_func, char ***words, int *word_count)
{
int c;
MR_optind = 0;
while ((c = MR_getopt_long(*word_count, *words, "o:ptf",
while ((c = MR_getopt_long(*word_count, *words, "o:ptfsb",
MR_trace_ambiguity_opts, NULL)) != EOF)
{
switch (c) {
@@ -2264,6 +2272,14 @@ MR_trace_options_ambiguity(const char **outfile, MR_bool *print_procs,
*print_functors = MR_TRUE;
break;
case 's':
*print_typespec_of = MR_TRUE;
break;
case 'b':
*print_pred_and_func = MR_TRUE;
break;
default:
MR_trace_usage_cur_cmd();
return MR_FALSE;

View File

@@ -874,7 +874,7 @@ MR_output_current_slots(const MR_LabelLayout *layout,
layout->MR_sll_entry->MR_sle_user.MR_user_def_module,
(MR_String)
layout->MR_sll_entry->MR_sle_user.MR_user_name,
layout->MR_sll_entry->MR_sle_user.MR_user_arity,
layout->MR_sll_entry->MR_sle_user.MR_user_pred_form_arity,
layout->MR_sll_entry->MR_sle_user.MR_user_mode,
layout->MR_sll_entry->MR_sle_detism,
(MR_String) (MR_Word) path,
@@ -977,7 +977,7 @@ MR_found_match(const MR_LabelLayout *layout,
layout->MR_sll_entry->MR_sle_user.MR_user_def_module,
(MR_String)
layout->MR_sll_entry->MR_sle_user.MR_user_name,
layout->MR_sll_entry->MR_sle_user.MR_user_arity,
layout->MR_sll_entry->MR_sle_user.MR_user_pred_form_arity,
layout->MR_sll_entry->MR_sle_user.MR_user_mode,
layout->MR_sll_entry->MR_sle_detism,
arguments,
@@ -1295,7 +1295,7 @@ MR_print_proc_id_to_socket(const MR_ProcLayout *entry,
"proc(\"%s\",\"%s\",%ld,%ld).\n",
entry->MR_sle_user.MR_user_decl_module,
entry->MR_sle_user.MR_user_name,
(long) entry->MR_sle_user.MR_user_arity,
(long) entry->MR_sle_user.MR_user_pred_form_arity,
(long) entry->MR_sle_user.MR_user_mode);
if (strcmp(entry->MR_sle_user.MR_user_decl_module,
@@ -1397,7 +1397,7 @@ MR_COLLECT_filter(MR_FilterFuncPtr filter_ptr, MR_Unsigned seqno,
(MR_String) layout->MR_sll_entry->MR_sle_user.MR_user_decl_module,
(MR_String) layout->MR_sll_entry->MR_sle_user.MR_user_def_module,
(MR_String) layout->MR_sll_entry->MR_sle_user.MR_user_name,
layout->MR_sll_entry->MR_sle_user.MR_user_arity,
layout->MR_sll_entry->MR_sle_user.MR_user_pred_form_arity,
layout->MR_sll_entry->MR_sle_user.MR_user_mode,
arguments,
layout->MR_sll_entry->MR_sle_detism,

View File

@@ -688,9 +688,51 @@ MR_compare_functor_by_name(const void *ptr1, const void *ptr2)
return MR_functor_compare_type_arity(*addr1, *addr2);
}
static MR_bool
proc_name_is_interesting(MR_bool print_typespec_of,
const MR_ProcLayout *proc)
{
if (strstr(proc->MR_sle_user.MR_user_name, "TypeSpecOf__") != NULL) {
// This procedure was created by type specialization.
// Any ambiguity involving this name comes from the original names
// *before* type specialization, so we consider it interesting
// only if the user specifically asks for it.
return print_typespec_of;
} else {
return MR_TRUE;
}
}
static MR_bool
procs_are_pred_and_func(FILE *fp, const MR_ProcLayout **procs,
int num_distinct, int pred_proc_num, int func_proc_num)
{
if (num_distinct == 2 &&
(pred_proc_num >= 0) && (func_proc_num >= 0))
{
// There are two procedures with the same name,
// one predicate and one function. Are they in the same module,
// and do they have the same pred-form arity?
if (
MR_proc_same_module_name(procs[pred_proc_num],
procs[func_proc_num]) &&
(procs[pred_proc_num]->MR_sle_user.MR_user_pred_form_arity ==
procs[func_proc_num]->MR_sle_user.MR_user_pred_form_arity))
{
return MR_TRUE;
} else {
return MR_FALSE;
}
} else {
return MR_FALSE;
}
}
void
MR_print_ambiguities(FILE *fp, MR_bool print_procs, MR_bool print_types,
MR_bool print_functors, char **arena_module_names, int arena_num_modules)
MR_bool print_functors, MR_bool print_typespec_of,
MR_bool print_pred_and_func,
char **arena_module_names, int arena_num_modules)
{
unsigned module_num;
int proc_num;
@@ -717,7 +759,6 @@ MR_print_ambiguities(FILE *fp, MR_bool print_procs, MR_bool print_types,
MR_EnumFunctorDesc **enum_functors;
MR_DuFunctorDesc **du_functors;
MR_NotagFunctorDesc *notag_functor;
int num_distinct;
int num_ambiguous;
int num_ambiguous_total;
int num_ambiguous_max;
@@ -784,10 +825,24 @@ MR_print_ambiguities(FILE *fp, MR_bool print_procs, MR_bool print_types,
end_proc_num++;
}
if (end_proc_num > proc_num + 1) {
if ((end_proc_num > proc_num + 1) &&
proc_name_is_interesting(print_typespec_of, procs[proc_num]))
{
int num_distinct;
int func_proc_num = -1;
int pred_proc_num = -1;
report[proc_num] = MR_TRUE;
num_distinct = 1;
if (procs[proc_num]->MR_sle_user.MR_user_pred_or_func ==
MR_PREDICATE)
{
pred_proc_num = proc_num;
} else {
func_proc_num = proc_num;
}
for (i = proc_num + 1; i < end_proc_num; i++) {
if (MR_proc_same_name_module_pf_arity(procs[i-1],
procs[i]))
@@ -796,10 +851,22 @@ MR_print_ambiguities(FILE *fp, MR_bool print_procs, MR_bool print_types,
} else {
report[i] = MR_TRUE;
num_distinct++;
if (procs[i]->MR_sle_user.MR_user_pred_or_func ==
MR_PREDICATE)
{
pred_proc_num = i;
} else {
func_proc_num = i;
}
}
}
if (num_distinct > 1) {
if ((num_distinct > 1) &&
(print_pred_and_func
? MR_TRUE
: !procs_are_pred_and_func(fp, procs, num_distinct,
pred_proc_num, func_proc_num)))
{
num_ambiguous++;
num_ambiguous_total += (end_proc_num - proc_num);
if ((end_proc_num - proc_num) > num_ambiguous_max) {
@@ -1026,7 +1093,7 @@ MR_print_ambiguities(FILE *fp, MR_bool print_procs, MR_bool print_types,
MR_compare_functor_by_name);
if (print_functors) {
fprintf(fp, "Ambiguous function symbols:\n");
fprintf(fp, "Ambiguous function symbol names:\n");
num_ambiguous = 0;
num_ambiguous_total = 0;
num_ambiguous_max = 0;

View File

@@ -113,12 +113,19 @@ extern void MR_dump_module_procs(FILE *fp, const char *name);
// function, type or (constructor) function symbol with that name is defined
// with more than one arity or in more than one module.
//
// Print ambiguities involving type-specialized procedures only if the
// print_typespec_of parameter is set. Print ambiguities between the predicate
// and the function form of an operation (such as function list.length/1
// and predicate list.length/2) only if the print_pred_and_func parameter
// is set.
//
// If num_modules is positive, then the search for ambiguities should consider
// only predicates, functions, types and function symbols in the modules whose
// names appear in module_names[0] .. module_names[num_modules-1].
extern void MR_print_ambiguities(FILE *fp, MR_bool print_procs,
MR_bool print_types, MR_bool print_functors,
MR_bool print_typespec_of, MR_bool print_pred_and_func,
char **module_names, int num_modules);
// A procedure specification has several components, the meaning of which

View File

@@ -228,7 +228,7 @@ MR_trace_proc_layout_is_builtin_catch(const MR_ProcLayout *layout)
user = &layout->MR_sle_user;
if (MR_streq(user->MR_user_decl_module, "exception") &&
MR_streq(user->MR_user_name, "builtin_catch") &&
(user->MR_user_arity == 3))
(user->MR_user_pred_form_arity == 3))
{
return MR_TRUE;
}