diff: fix copy/2 string literal alignment bug

Fergus Henderson fjh at cs.mu.OZ.AU
Wed Mar 24 15:21:18 AEDT 1999


Estimated hours taken: 2

Fix a bug where copy/2 was returning bogus data when copying string literals.

runtime/mercury_deep_copy_body.h:
	Change the code so that it doesn't assume that string literals
	must be aligned, since currently they aren't.

tests/hard_coded/Mmakefile:
tests/hard_coded/string_alignment_bug.m:
tests/hard_coded/string_alignment_bug.exp:
	Add a regression test.

Index: runtime/mercury_deep_copy_body.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_deep_copy_body.h,v
retrieving revision 1.5
diff -u -r1.5 mercury_deep_copy_body.h
--- mercury_deep_copy_body.h	1999/03/02 09:46:10	1.5
+++ mercury_deep_copy_body.h	1999/03/24 03:07:49
@@ -169,7 +169,7 @@
                 incr_saved_hp_atomic(new_data, 
                     (strlen((String) data_value) + sizeof(Word)) 
                                 / sizeof(Word));
-                strcpy((String) new_data, (String) data_value);
+                strcpy((String) new_data, (String) data);
                 leave_forwarding_pointer(data_ptr, new_data);
             } else {
                 new_data = data;
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.51
diff -u -r1.51 Mmakefile
--- Mmakefile	1999/02/08 23:36:46	1.51
+++ Mmakefile	1999/03/24 04:03:26
@@ -82,6 +82,7 @@
 	rtc_bug \
 	space \
 	string_alignment \
+	string_alignment_bug \
 	string_loop \
 	test_imported_no_tag \
 	term_io_test \
Index: tests/hard_coded/string_alignment_bug.m
===================================================================
RCS file: string_alignment_bug.m
diff -N string_alignment_bug.m
--- /dev/null	Wed Mar 24 15:18:59 1999
+++ string_alignment_bug.m	Wed Mar 24 15:16:42 1999
@@ -0,0 +1,180 @@
+% mercury 0.8 failed this test on some architectures,
+% because string literals were not aligned by deep_copy()
+% was assuming that they were.
+
+:- module string_alignment_bug.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module bool, int, list, map, require, set, std_util, string.
+
+main -->
+	init_globals,
+	{ gen_tiles(10, 10, Tiles) },
+	set_global("Tiles", Tiles),
+	{ init_selection(Selection) },
+	set_global("Selection", Selection),
+	{ init_file(MFN) },
+	set_global("CurrentFile", MFN).
+	%main(bedit__setup, ["robot"]).
+
+:- pred init_file(maybe(string)::out) is det.
+init_file(no).
+
+%------------------------------------------------------------------------------%
+
+:- type pos      ==      pair(int).
+
+:- type selection	==	set(pos).
+
+:- pred init_selection(selection::out) is det.
+
+init_selection(Sel) :-
+	set__init(Sel).
+
+%------------------------------------------------------------------------------%
+
+:- type tiles == map(pos, tile).
+:- type tile ---> tile(kind, list(attr)).
+:- type kind ---> plain ; pit ; gear(chirality) ; conv(dir).
+:- type chirality ---> clock ; anti.
+:- type attr ---> wall(dir) ; start ; flag(int).
+:- type dir ---> north ; south ; east ; west.
+
+
+:- pred gen_tiles(int, int, map(pos, tile)).
+:- mode gen_tiles(in, in, out) is det.
+
+gen_tiles(Xmax, Ymax, Tiles) :-
+	map__init(Tiles0),
+	AllPos = (pred(Pos::out) is nondet :-
+		between(0, Xmax-1, X),
+		between(0, Ymax-1, Y),
+		Pos = X - Y
+	),
+	AddTile = (pred(Pos::in, T0::in, T::out) is det :-
+		map__set(T0, Pos, tile(plain, []), T)
+	),
+	aggregate(AllPos, AddTile, Tiles0, Tiles).
+
+%------------------------------------------------------------------------------%
+
+:- pred between(int, int, int).
+:- mode between(in, in, out) is nondet.
+
+between(Min, Max, I) :-
+	Min =< Max,
+	(
+		I = Min
+	;
+		Min1 is Min + 1,
+		between(Min1, Max, I)
+	).
+
+%------------------------------------------------------------------------------%
+
+:- pred init_globals(io__state, io__state).
+:- mode init_globals(di, uo) is det.
+
+:- pred get_global(string, T, io__state, io__state).
+:- mode get_global(in, out, di, uo) is det.
+
+:- pred set_global(string, T, io__state, io__state).
+:- mode set_global(in, in, di, uo) is det.
+
+:- import_module list, map, require, string, std_util.
+
+init_globals -->
+	{ my_map_init(Map) },
+	{ type_to_univ(Map, UMap1) },
+	{ copy(UMap1, UMap) },
+	io__set_globals(UMap).
+
+get_global(Name, Value) -->
+	io__get_globals(UMap0),
+	(
+		{ univ_to_type(UMap0, Map0) }
+	->
+		(
+			{ map__search(Map0, Name, UValue) }
+		->
+			(
+				{ univ_to_type(UValue, Value0) }
+			->
+				{ Value = Value0 }
+			;
+				{ string__format(
+					"globals: value for `%s' has bad type",
+					[s(Name)], Str) },
+				{ error(Str) }
+			)
+		;
+			{ string__format("globals: %s not found",
+				[s(Name)], Str) },
+			{ error(Str) }
+		)
+	;
+		{ error("globals: global store stuffed up") }
+	).
+
+set_global(Name, Value) -->
+	io__get_globals(UMap0),
+	(
+		{ univ_to_type(UMap0, Map0) }
+	->
+		{ type_to_univ(Value, UValue) },
+		io__write_string("Current global store:\n"),
+		io__write(Map0),
+		nl,
+		io__write_string("Adding `"),
+		io__write_string(Name),
+		io__write_string("': "),
+		io__write(Value),
+		nl,
+		{ map__set(Map0, Name, UValue, Map) },
+		io__write_string("New global store:\n"),
+		io__write(Map),
+		nl,
+		{ type_to_univ(Map, UMap1) },
+		{ copy(UMap1, UMap) },
+		io__set_globals(UMap)
+	;
+		{ error("globals: global store stuffed up") }
+	).
+
+:- pred my_map_init(map(string, univ)::out) is det.
+
+my_map_init(Map) :-
+	map__init(Map).
Index: tests/hard_coded/string_alignment_bug.exp
[... deleted since it is not very interesting ...]

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3        |     -- the last words of T. S. Garp.



More information about the developers mailing list