Hello,
It seems to me that there's a small issue in mergecil.ml related to
merging a global definition with a previously seen tentative definition
(i.e. with an init set to None), in oneFilePass2. Namely, the new
definition is kept, but the actual initializer is not placed in
emittedVarDefn. Thus, if we ever encounter a third definition different
from the second, the clash won't be noticed. This can be seen with
three files containing int x; int x = 2; and int x = 3; respectively.
cilly --save-temps --merge first_def.c second_def.c third_def.c will
then produce a uncompilable C file in a.cil.c containing the two
conflicting definition.
The attached patch (against cil 1.3.7) takes care of that, and gets rid
of the comment saying that the old tentative definition ought to be
replaced by a GVarDecl by actually doing it.
(Disclaimer: this implies a traversal of the whole list of globals.
I've used a List.rev (List.map_rev ...), i.e. two traversals, but
tail-recursive, to avoid blowing up the stack, but this is untested for
big programs)
Regards,
--
E tutto per oggi, a la prossima volta.
Virgile
--- mergecil.ml 2009-04-24 20:50:33.000000000 +0200
+++ mergecil.new 2010-02-10 11:44:07.597579893 +0100
@@ -1296,6 +1296,8 @@
* before knowing that we can throw them away, then we mark this flag so
* that we can make another pass over the file *)
let repeatPass2 = ref false in
+
+ let replaceTentativeDefn = ref false in
(* Keep a pointer to the contents of the file so far *)
let savedTheFile = !theFile in
@@ -1363,9 +1365,8 @@
false (* do not emit *)
)
else if prevInitOpt = None then (
- (* We have an initializer, but the previous one didn't.
- We should really convert the previous global from GVar
- to GVarDecl, but that's not convenient to do here. *)
+ H.replace emittedVarDefn vi'.vname (vi', init.init,l);
+ replaceTentativeDefn:=true;
true
)
else (
@@ -1670,6 +1671,23 @@
in
(* Now do the real PASS 2 *)
List.iter processOneGlobal f.globals;
+ if !replaceTentativeDefn then begin
+ theFile:=
+ (* Just stay tail-recursive here, the list of globals can be huge. *)
+ List.rev
+ (List.rev_map
+ (function
+ GVar(vi,{init=None},loc) as g ->
+ (try
+ let (_,init,_) = H.find emittedVarDefn vi.vname in
+ (match init with
+ None -> g
+ | Some _ -> GVarDecl(vi,loc))
+ with Not_found -> g)
+ | g -> g)
+ !theFile)
+ end;
+
(* See if we must re-visit the globals in this file because an inline that
* is being removed was used before we saw the definition and we decided to
* remove it *)
------------------------------------------------------------------------------
SOLARIS 10 is the OS for Data Centers - provides features such as DTrace,
Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW
http://p.sf.net/sfu/solaris-dev2dev
_______________________________________________
CIL-users mailing list
CIL-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/cil-users