diff: pragma c without det decl

Simon Taylor stayl at cs.mu.oz.au
Mon Nov 17 13:29:20 AEDT 1997


Hi,

Tom wrote on mercury-bugs:
> I discovered that there is a missing determinism declaration on
> make_uniq - it should be declared det, but aparently defaults to
> erroneous. This still doesn't adequately explain the resulting
> operational behaviour...

Yes it does. Since the compiler assumes make_uniq does not return,
the code to update the array and the other info does not get executed, 
leaving any old junk in the return registers. The second call to set_pixel 
in subsample then falls over.

We should disallow pragma c_code for procedures without 
determinism declarations.

Tom, could you please review this.

Simon.


Estimated hours taken: 0.5

compiler/det_analysis.m
compiler/det_report.m
	Disallow pragma c_code without determinism declarations.


tests/invalid/pragma_c_code_no_det.m
tests/invalid/pragma_c_code_no_det.err_exp
	Test case.


Index: det_analysis.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/det_analysis.m,v
retrieving revision 1.122
diff -u -r1.122 det_analysis.m
--- det_analysis.m	1997/09/01 14:01:06	1.122
+++ det_analysis.m	1997/11/17 02:06:51
@@ -588,24 +588,31 @@
 		pragma_c_code(C_Code, IsRecursive, PredId, ProcId, Args,
 			ArgNameMap, OrigArgTypes, Extra),
 		Detism, Msgs) :-
-	det_lookup_detism(DetInfo, PredId, ProcId, Detism0),
-	determinism_components(Detism0, CanFail, NumSolns0),
-	( Extra = extra_pragma_info(_, _) ->
-		% pragma C codes that specify saved variables and labels
-		% can have more than one solution
-		NumSolns = at_most_many
+	det_info_get_module_info(DetInfo, ModuleInfo),
+	module_info_pred_proc_info(ModuleInfo, PredId, ProcId, _, ProcInfo),
+	proc_info_declared_determinism(ProcInfo, MaybeDetism),
+	( MaybeDetism = yes(Detism0) ->
+		determinism_components(Detism0, CanFail, NumSolns0),
+		( Extra = extra_pragma_info(_, _) ->
+			% pragma C codes that specify saved variables and labels
+			% can have more than one solution
+			NumSolns = at_most_many
+		;
+			NumSolns = NumSolns0
+		),
+		determinism_components(Detism, CanFail, NumSolns),
+		(
+			NumSolns = at_most_many_cc,
+			SolnContext \= first_soln
+		->
+			Msgs = [cc_pred_in_wrong_context(GoalInfo, Detism,
+					PredId, ProcId)]
+		;
+			Msgs = []
+		)
 	;
-		NumSolns = NumSolns0
-	),
-	determinism_components(Detism, CanFail, NumSolns),
-	(
-		NumSolns = at_most_many_cc,
-		SolnContext \= first_soln
-	->
-		Msgs = [cc_pred_in_wrong_context(GoalInfo, Detism,
-				PredId, ProcId)]
-	;
-		Msgs = []
+		Msgs = [pragma_c_code_without_det_decl(PredId, ProcId)],
+		Detism = erroneous
 	).
 
 %-----------------------------------------------------------------------------%
Index: det_report.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/det_report.m,v
retrieving revision 1.42
diff -u -r1.42 det_report.m
--- det_report.m	1997/10/15 07:39:42	1.42
+++ det_report.m	1997/11/17 02:13:48
@@ -49,7 +49,9 @@
 				determinism)
 		;	error_in_lambda(
 				determinism, determinism, % declared, inferred
-				hlds_goal, hlds_goal_info, pred_id, proc_id).
+				hlds_goal, hlds_goal_info, pred_id, proc_id)
+		; 	pragma_c_code_without_det_decl(pred_id, proc_id)
+		.
 
 :- type seen_call_id
 	--->	seen_call(pred_id, proc_id)
@@ -891,6 +893,7 @@
 det_msg_get_type(cc_pred_in_wrong_context(_, _, _, _), error).
 det_msg_get_type(higher_order_cc_pred_in_wrong_context(_, _), error).
 det_msg_get_type(error_in_lambda(_, _, _, _, _, _), error).
+det_msg_get_type(pragma_c_code_without_det_decl(_, _), error).
 
 :- pred det_report_msg(det_msg, module_info, io__state, io__state).
 :- mode det_report_msg(in, in, di, uo) is det.
@@ -1105,6 +1108,15 @@
 	{ det_info_init(ModuleInfo, PredId, ProcId, Globals, DetInfo) },
 	det_diagnose_goal(Goal, DeclaredDetism, [], DetInfo, _),
 	io__set_exit_status(1).
+det_report_msg(pragma_c_code_without_det_decl(PredId, ProcId),
+		ModuleInfo) -->
+	report_pred_proc_id(ModuleInfo, PredId, ProcId, no, Context),
+	prog_out__write_context(Context),	
+	io__write_string("  error: `:- pragma c_code(...)' for a procedure"),
+	io__nl,
+	prog_out__write_context(Context),	
+	io__write_string("  without a determinism declaration."),
+	io__nl.
 
 %-----------------------------------------------------------------------------%
 

Index: Mmakefile
===================================================================
RCS file: /home/staff/zs/imp/tests/invalid/Mmakefile,v
retrieving revision 1.2
diff -u -r1.2 Mmakefile
--- Mmakefile	1997/10/14 06:38:30	1.2
+++ Mmakefile	1997/11/17 02:21:45
@@ -30,6 +30,7 @@
 	occurs.m \
 	pragma_c_code_and_clauses1.m \
 	pragma_c_code_and_clauses2.m \
+	pragma_c_code_no_det.m \
 	qual_basic_test2.m \
 	type_loop.m \
 	type_mismatch.m \


pragma_c_code_no_det.m:
-----------------------------

:- module pragma_c_code_no_det.

:- interface.

:- pred test(int::out) is det.

:- implementation.

test(Int) :-
	c_code(Int).

:- pred c_code(int::out).
:- pragma c_code(c_code(X::out), "X = 1").



pragma_c_code_no_det.err_exp:
-----------------------------

pragma_c_code_no_det.m:012: In `c_code(out)':
pragma_c_code_no_det.m:012:   error: `:- pragma c_code(...)' for a procedure
pragma_c_code_no_det.m:012:   without a determinism declaration.
pragma_c_code_no_det.m:005: In `test(out)':
pragma_c_code_no_det.m:005:   warning: determinism declaration could be tighter.
pragma_c_code_no_det.m:005:   Declared `det', inferred `erroneous'.
For more information, try recompiling with `-E'.



More information about the developers mailing list