Diff: Error in .opt file output

Andrew Bromage bromage at cs.mu.oz.au
Thu Nov 20 17:37:44 AEDT 1997


Estimated hours taken: 1

Fix a bug in the writing of .opt files.

The problem occurs when you have a pragma inline declaration for an
exported function.  The declaration:

:- func addone(int) = int.
:- pragma inline(addone/1).
addone(I) = I + 1.

gets written to the .opt file as:

:- pragma inline((foo:addone)/2).

That is, the arity of the _predicate_ version is written rather than
the arity of the _function_.

compiler/intermod.m:
compiler/mercury_to_mercury.m:
	Add a pred_or_func argument to mercury_output_pragma_decl,
	and use that to determine the declared arity.

tests/valid/intermod_test.m:
tests/valid/intermod_test2.m:
	Regression test.


Index: compiler/intermod.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/intermod.m,v
retrieving revision 1.34
diff -u -r1.34 intermod.m
--- intermod.m	1997/10/26 23:05:36	1.34
+++ intermod.m	1997/11/20 06:07:02
@@ -922,11 +922,11 @@
 	{ pred_info_name(PredInfo, Name) },
 	{ SymName = qualified(Module, Name) },
 	{ pred_info_get_marker_list(PredInfo, Markers) },
-	intermod__write_pragmas(SymName, Arity, Markers),
+	{ pred_info_get_is_pred_or_func(PredInfo, PredOrFunc) },
+	intermod__write_pragmas(SymName, Arity, Markers, PredOrFunc),
 	{ pred_info_clauses_info(PredInfo, ClausesInfo) },
 	{ ClausesInfo = clauses_info(Varset, _, _VarTypes, HeadVars, Clauses) },
 		% handle pragma(c_code, ...) separately
-	{ pred_info_get_is_pred_or_func(PredInfo, PredOrFunc) },
 	( { pred_info_get_goal_type(PredInfo, pragmas) } ->
 		{ pred_info_procedures(PredInfo, Procs) },
 		intermod__write_c_code(SymName, PredOrFunc, HeadVars, Varset,
@@ -940,10 +940,11 @@
 	intermod__write_preds(ModuleInfo, PredIds).
 
 :- pred intermod__write_pragmas(sym_name::in, int::in, list(marker_status)::in,
-				io__state::di, io__state::uo) is det.
+		pred_or_func::in, io__state::di, io__state::uo) is det.
 
-intermod__write_pragmas(_, _, []) --> [].
-intermod__write_pragmas(SymName, Arity, [MarkerStatus | Markers]) -->
+intermod__write_pragmas(_, _, [], _) --> [].
+intermod__write_pragmas(SymName, Arity, [MarkerStatus | Markers], PredOrFunc)
+		-->
 	(
 		{ MarkerStatus = request(Marker) }
 	;
@@ -958,11 +959,11 @@
 		)
 	->
 		{ hlds_out__marker_name(Marker, Name) },
-		mercury_output_pragma_decl(SymName, Arity, Name)
+		mercury_output_pragma_decl(SymName, Arity, PredOrFunc, Name)
 	;
 		[]
 	),
-	intermod__write_pragmas(SymName, Arity, Markers).
+	intermod__write_pragmas(SymName, Arity, Markers, PredOrFunc).
 
 	% Some pretty kludgy stuff to get c code written correctly.
 :- pred intermod__write_c_code(sym_name::in, pred_or_func::in, 
Index: compiler/mercury_to_mercury.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/mercury_to_mercury.m,v
retrieving revision 1.119
diff -u -r1.119 mercury_to_mercury.m
--- mercury_to_mercury.m	1997/10/09 09:38:54	1.119
+++ mercury_to_mercury.m	1997/11/20 05:47:24
@@ -46,8 +46,9 @@
 		maybe(determinism), term__context, io__state, io__state).
 :- mode mercury_output_func_mode_subdecl(in, in, in, in, in, in, di, uo) is det.
 
-:- pred mercury_output_pragma_decl(sym_name, int, string, io__state, io__state).
-:- mode mercury_output_pragma_decl(in, in, in, di, uo) is det.
+:- pred mercury_output_pragma_decl(sym_name, int, pred_or_func, string,
+		io__state, io__state).
+:- mode mercury_output_pragma_decl(in, in, in, in, di, uo) is det.
 
 :- pred mercury_output_pragma_c_code(may_call_mercury, sym_name, pred_or_func,
 		list(pragma_var), maybe(pair(list(string))),
@@ -285,16 +286,16 @@
 			C_Function)
 	;
 		{ Pragma = obsolete(Pred, Arity) },
-		mercury_output_pragma_decl(Pred, Arity, "obsolete")
+		mercury_output_pragma_decl(Pred, Arity, predicate, "obsolete")
 	;
 		{ Pragma = memo(Pred, Arity) },
-		mercury_output_pragma_decl(Pred, Arity, "memo")
+		mercury_output_pragma_decl(Pred, Arity, predicate, "memo")
 	;
 		{ Pragma = inline(Pred, Arity) },
-		mercury_output_pragma_decl(Pred, Arity, "inline")
+		mercury_output_pragma_decl(Pred, Arity, predicate, "inline")
 	;
 		{ Pragma = no_inline(Pred, Arity) },
-		mercury_output_pragma_decl(Pred, Arity, "no_inline")
+		mercury_output_pragma_decl(Pred, Arity, predicate, "no_inline")
 	;
 		{ Pragma = unused_args(PredOrFunc, PredName,
 			Arity, ProcId, UnusedArgs) },
@@ -310,13 +311,15 @@
 			PredName, ModeList, Termination, Context)
 	;
 		{ Pragma = terminates(Pred, Arity) },
-		mercury_output_pragma_decl(Pred, Arity, "terminates")
+		mercury_output_pragma_decl(Pred, Arity, predicate, "terminates")
 	;
 		{ Pragma = does_not_terminate(Pred, Arity) },
-		mercury_output_pragma_decl(Pred, Arity, "does_not_terminate")
+		mercury_output_pragma_decl(Pred, Arity, predicate,
+			"does_not_terminate")
 	;
 		{ Pragma = check_termination(Pred, Arity) },
-		mercury_output_pragma_decl(Pred, Arity, "check_termination")
+		mercury_output_pragma_decl(Pred, Arity, predicate,
+			"check_termination")
 	).
 
 mercury_output_item(nothing, _) --> [].
@@ -1620,13 +1623,18 @@
 
 %-----------------------------------------------------------------------------%
 
-mercury_output_pragma_decl(PredName, Arity, PragmaName) -->
+mercury_output_pragma_decl(PredName, Arity, PredOrFunc, PragmaName) -->
+	{ PredOrFunc = predicate,
+		DeclaredArity = Arity
+	; PredOrFunc = function,
+		DeclaredArity is Arity - 1
+	},
 	io__write_string(":- pragma "),
 	io__write_string(PragmaName),
 	io__write_string("(("),
 	mercury_output_bracketed_sym_name(PredName),
 	io__write_string(")/"),
-	io__write_int(Arity),
+	io__write_int(DeclaredArity),
 	io__write_string(").\n").
 
 %-----------------------------------------------------------------------------%
Index: tests/valid/intermod_test.m
===================================================================
RCS file: /home/staff/zs/imp/tests/valid/intermod_test.m,v
retrieving revision 1.1
diff -u -r1.1 intermod_test.m
--- intermod_test.m	1997/06/29 23:23:31	1.1
+++ intermod_test.m	1997/11/20 06:26:53
@@ -26,3 +26,9 @@
 :- mode local(pred(int_mode) is det, out) is det.
 
 local(Pred, Int) :- call(Pred, Int).
+
+:- pred local_2(pred(int), int).
+:- mode local_2(pred(int_mode) is det, out) is det.
+
+local_2(Pred, plusone(Int)) :- call(Pred, Int).
+
Index: tests/valid/intermod_test2.m
===================================================================
RCS file: /home/staff/zs/imp/tests/valid/intermod_test2.m,v
retrieving revision 1.1
diff -u -r1.1 intermod_test2.m
--- intermod_test2.m	1997/06/29 23:23:32	1.1
+++ intermod_test2.m	1997/11/20 06:29:11
@@ -5,6 +5,8 @@
 :- import_module int.
 :- pred baz(int::in) is semidet.
 
+:- func plusone(int :: in) = (int :: out) is det.
+
 :- implementation.
 
 :- type t
@@ -24,3 +26,11 @@
 :- mode local(pred(int_mode) is det, out) is det.
 
 local(Pred, Int) :- call(Pred, Int0), Int is Int0 + 1.
+
+% One version of the compiler incorrectly wrote this declaration to
+% the .opt file as `:- pragma inline((intermod_test2:plusone)/2).'
+% 		-- bromage  20 Nov 1997
+:- pragma inline(plusone/1).
+
+plusone(Int0) = Int :- Int is Int0 + 1.
+




More information about the developers mailing list