diff --git a/pkgs/development/libraries/aterm/aterm-2.4.nix b/pkgs/development/libraries/aterm/aterm-2.4.nix index c367b4b90549..4e6990e44acd 100644 --- a/pkgs/development/libraries/aterm/aterm-2.4.nix +++ b/pkgs/development/libraries/aterm/aterm-2.4.nix @@ -6,6 +6,7 @@ stdenv.mkDerivation { url = http://nix.cs.uu.nl/dist/tarballs/aterm-2.4.2.tar.gz; md5 = "18617081dd112d85e6c4b1b552628114"; }; + patches = [./aterm-alias-fix-2.patch]; meta = { homepage = http://www.cwi.nl/htbin/sen1/twiki/bin/view/SEN1/ATerm; license = "LGPL"; diff --git a/pkgs/development/libraries/aterm/aterm-alias-fix-2.patch b/pkgs/development/libraries/aterm/aterm-alias-fix-2.patch new file mode 100644 index 000000000000..c1dfc3e0e737 --- /dev/null +++ b/pkgs/development/libraries/aterm/aterm-alias-fix-2.patch @@ -0,0 +1,224 @@ +diff -rc aterm-1142707243.10633/aterm/aterm.c aterm/aterm/aterm.c +*** aterm-1142707243.10633/aterm/aterm.c 2006-02-08 11:35:28.000000000 +0100 +--- aterm/aterm/aterm.c 2006-04-25 17:10:52.000000000 +0200 +*************** +*** 193,198 **** +--- 193,199 ---- + /* that have char == 2 bytes, and sizeof(header_type) == 2 */ + assert(sizeof(header_type) == sizeof(ATerm *)); + assert(sizeof(header_type) >= 4); ++ assert(sizeof(ATerm) == sizeof(MachineWord)); + + /*}}} */ + /*{{{ Initialize buffer */ +diff -rc aterm-1142707243.10633/aterm/memory.c aterm/aterm/memory.c +*** aterm-1142707243.10633/aterm/memory.c 2006-03-09 15:02:56.000000000 +0100 +--- aterm/aterm/memory.c 2006-04-25 18:22:00.000000000 +0200 +*************** +*** 119,130 **** + hash_number(tmp,3)) + */ + + #define HASHNUMBER3(t)\ +! FINISH(COMBINE(START(((MachineWord*)t)[0]), ((MachineWord*)t)[2])) + + #define HASHNUMBER4(t)\ +! FINISH(COMBINE(COMBINE(START(((MachineWord*)t)[0]), \ +! ((MachineWord*)t)[2]),((MachineWord*)t)[3])) + + #define HASHINT(val) \ + FINISH(COMBINE(START( (AT_INT<header = header; ++ ++ and then read it through a MachineWord*, e.g., ++ ++ hnr = hash_number((ATerm) protoAppl, 2); ++ ++ (hash_number walks over the term by casting it to a MachineWord*). ++ ++ However, the same clause of the C standard also specifies that you ++ *can* read the memory location through a union type that contains ++ both the original type (e.g. ATermAppl) and the type used to read ++ the memory location (e.g. MachineWord). That's what we do ++ below: we have a union of all the types that occur in the various ++ ATerm types. We then read the "w" element of the union. The ++ compiler is not allowed to assume absence of aliasing with the ++ other types in the union. ++ ++ A better solution would be to hash the term through a character ++ pointer (since *any* memory location can be legally read as a ++ character), but I'm too lazy right now. Performance might also ++ suffer if we do that. */ ++ ++ typedef union ++ { ++ MachineWord w; ++ header_type header; ++ ATerm term; ++ ATermList list; ++ int i; ++ double d; ++ void* p; ++ } Aliaser; ++ ++ #define GET_WORD(t, n) (((Aliaser*) (((MachineWord*) t) + n))->w) ++ + #define HASHNUMBER3(t)\ +! FINISH(COMBINE(START(GET_WORD(t, 0)), GET_WORD(t, 2))) + + #define HASHNUMBER4(t)\ +! FINISH(COMBINE(COMBINE(START(GET_WORD(t, 0)), \ +! GET_WORD(t, 2)), GET_WORD(t, 3))) + + #define HASHINT(val) \ + FINISH(COMBINE(START( (AT_INT<header = header; + CHECK_HEADER(protoAppl->header); + +! if (args != PROTO_APPL_ARGS) { + for (i=0; iheader = header; + CHECK_HEADER(protoAppl->header); + +! if (args != (ATerm *) PROTO_APPL_ARGS) { + for (i=0; i