let initial_state_only_globals =
  let module S =
    Computation.OptionRef
      (Relations_type.Model.Datatype)
      (struct
         let name = "only_globals"
         let dependencies =
           [ Ast.self; Parameters.LibEntry.self; Parameters.MainFunction.self ]
       end)
  in
function () ->
 let compute ()  =
  Value_parameters.debug ~level:2 "Computing globals values";
  let state = ref Relations_type.Model.empty in
  let complete_init last_bitsoffset typ _l lval =
    (* Now process the non initialized bits defaulting to 0 *)
    begin try
      let size_to_add, offset =
        bitsSizeOf typ - last_bitsoffset,
        Ival.inject_singleton (Int.of_int last_bitsoffset)
      in
      assert (size_to_add >= 0);
      if size_to_add <> 0 then
        let loc =
          match lval with
          | (Var vinfo, _ (* In case of a string this is not [NoOffset] ! *)-> let base = Base.create_varinfo vinfo in
            let loc =
              Location_Bits.inject base offset
            in
            make_loc
              loc
              (Int_Base.inject (Int.of_int size_to_add))
          | _ -> error "Whacky initializer ? Please report.";
              assert false
        in
        let v =
          if hasAttribute "volatile" (typeAttrs typ)
          then V.top_int
          else V.singleton_zero
        in
        state :=
          Relations_type.Model.add_binding
            ~with_alarms:CilE.warn_none_mode
            ~exact:true
            !state
            loc
            v
    with Cil.SizeOfError _ ->
      Value_parameters.result ~once:true ~current:true
        "cannot provide a default initializer: size is unknown"
    end
  in
  let rec eval_init lval init =
    match init with
    | SingleInit exp ->
        let loc = lval_to_loc ~with_alarms:CilE.warn_none_mode Relations_type.Model.empty lval
        in
        let exact = cardinal_zero_or_one loc in
        assert (if not exact then (Cil.warning "In global initialisation, the location can not be represented. Aborting@."; exit 1); true);
        let value =
          eval_expr ~with_alarms:(warn_all_quiet_mode ())
            Relations_type.Model.empty
            exp
        in
        let v =
          if hasAttribute "volatile" (typeAttrs (Cil.typeOfLval lval))
          then V.top_int
          else value
        in
        state :=
          Relations_type.Model.add_binding ~with_alarms:CilE.warn_none_mode ~exact
            !state loc v

    | CompoundInit (base_typ, l) ->
        if not (hasAttribute "volatile" (typeAttrs base_typ)) then
          let last_bitsoffset = foldLeftCompound
            ~implicit:false
            ~doinit:
            (fun off init typ (acc:int) ->
               let o,w = bitsOffset base_typ off in
               if acc<o then begin (* topify the padding bits *)
                 let vi, (base_off,_) =
                   (match lval with
                    | Var vinfo, abs_offset ->
                        vinfo,
                        (bitsOffset vinfo.vtype abs_offset)
                    | _ ->
                        Value_parameters.fatal "Whacky initializer?")
                 in
                 let loc_bits =
                   Location_Bits.inject
                     (Base.create_varinfo vi)
                     (Ival.inject_singleton (Int.of_int (base_off+acc)))
                 in
                 let loc_size = Int_Base.inject (Int.of_int (o-acc)) in
                 state := Relations_type.Model.add_binding_unspecified
                   !state
                   (make_loc loc_bits loc_size)
               end else assert (acc=o);
               if hasAttribute "volatile" (typeAttrs typ) then
                 Value_parameters.warning ~current:true ~once:true
                   "global initialization of volatile value ignored"
               else
                 eval_init (addOffsetLval off lval) init;
               o+w)
            ~ct:base_typ
            ~initl:l
            ~acc:0 in
          complete_init last_bitsoffset base_typ l lval
        else ()
  in
  Globals.Vars.iter
    (fun varinfo init ->
       if not varinfo.vlogic then begin
         CurrentLoc.set varinfo.vdecl;
         match init.init with
         | None (*when
                  isCompleteType varinfo.vtype*)

           -> (* Default to zero init thanks to ANSI p126 6.7.8.10 *)
             (* eval_init (Var varinfo, NoOffset) (makeZeroInit varinfo.vtype)*)
             if varinfo.vstorage = Extern then
               (* Must not initialize when the storage is extern. *)
               state := initialize_var_using_type varinfo !state
             else complete_init 0 varinfo.vtype [] (Var varinfo,NoOffset)
               (*       | None ->
               (* Cannot initialize with a default when type is incomplete. *)
                        ()*)

         | Some i ->
             eval_init (Var varinfo,NoOffset) i
       end);

  
  (** Bind the declared range for NULL to uninitialized *)

  if Int.le
    (Base.min_valid_absolute_address ())
    (Base.max_valid_absolute_address ())
  then begin
    let loc_bits = Location_Bits.inject_ival
      (Ival.inject_singleton (Base.min_valid_absolute_address ()))
    in
    let loc_size =
      Int_Base.inject
        (Int.length
           (Base.min_valid_absolute_address ())
           (Base.max_valid_absolute_address ()))
    in
    if true (* TODO: command line option *)
    then
      state :=
        Relations_type.Model.add_binding
          ~with_alarms:CilE.warn_none_mode
          ~exact:true
          !state
          (make_loc loc_bits loc_size)
          Cvalue_type.V.top_int
    else
      state :=
        Relations_type.Model.add_binding_unspecified
          (*          ~with_alarms:warn_none_mode
                      ~exact:true *)

          !state
          (make_loc loc_bits loc_size)
          (*          Cvalue_type.V.bottom *)
  end;
  let result = !state in
  result
in
 S.memo compute