Skip to content

Commit 7a6d02d

Browse files
Possibility to control if VarDecl should be generated for all variables or not
via alwaysGenerateVarDecl in cabs2cil.ml and cleanup of print code
1 parent 2ef6d86 commit 7a6d02d

File tree

3 files changed

+60
-60
lines changed

3 files changed

+60
-60
lines changed

src/cil.ml

Lines changed: 31 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3238,12 +3238,6 @@ class type cilPrinter = object
32383238
* in formals of function types, and the formals and locals for function
32393239
* definitions. *)
32403240

3241-
method pVDeclPhony: unit -> varinfo -> bool -> doc
3242-
(** Invoked for each variable declaration. Note that variable
3243-
* declarations are all the [GVar], [GVarDecl], [GFun], all the [varinfo]
3244-
* in formals of function types, and the formals and locals for function
3245-
* definitions. *)
3246-
32473241
method pVar: varinfo -> doc
32483242
(** Invoked on each variable use. *)
32493243

@@ -3346,32 +3340,14 @@ class defaultCilPrinterClass : cilPrinter = object (self)
33463340

33473341
(* variable declaration *)
33483342
method pVDecl () (v:varinfo) =
3349-
if not v.vhasdeclinstruction then
3350-
let stom, rest = separateStorageModifiers v.vattr in
3351-
(* First the storage modifiers *)
3352-
text (if v.vinline then "__inline " else "")
3353-
++ d_storage () v.vstorage
3354-
++ (self#pAttrs () stom)
3355-
++ (self#pType (Some (text v.vname)) () v.vtype)
3356-
++ text " "
3357-
++ self#pAttrs () rest
3358-
else
3359-
text " "
3360-
3361-
3362-
(* variable declaration *)
3363-
method pVDeclPhony () (v:varinfo) ph =
3364-
if ph || not v.vhasdeclinstruction then
3365-
let stom, rest = separateStorageModifiers v.vattr in
3366-
(* First the storage modifiers *)
3367-
text (if v.vinline then "__inline " else "")
3368-
++ d_storage () v.vstorage
3369-
++ (self#pAttrs () stom)
3370-
++ (self#pType (Some (text v.vname)) () v.vtype)
3371-
++ text " "
3372-
++ self#pAttrs () rest
3373-
else
3374-
text " "
3343+
let stom, rest = separateStorageModifiers v.vattr in
3344+
(* First the storage modifiers *)
3345+
text (if v.vinline then "__inline " else "")
3346+
++ d_storage () v.vstorage
3347+
++ (self#pAttrs () stom)
3348+
++ (self#pType (Some (text v.vname)) () v.vtype)
3349+
++ text " "
3350+
++ self#pAttrs () rest
33753351

33763352
(*** L-VALUES ***)
33773353
method pLval () (lv:lval) = (* lval (base is 1st field) *)
@@ -3626,10 +3602,13 @@ class defaultCilPrinterClass : cilPrinter = object (self)
36263602
++ text printInstrTerminator
36273603

36283604
end
3629-
| VarDecl(varinfo,l) ->
3630-
self#pLineDirective l
3631-
++ self#pVDeclPhony () varinfo true
3632-
++ chr ';'
3605+
| VarDecl(v, l) ->
3606+
self#pLineDirective l
3607+
++ self#pVDecl () v
3608+
++ (match v.vinit.init with
3609+
| None -> text ";"
3610+
| Some i -> text " = " ++
3611+
self#pInit () i ++ text ";")
36333612
(* In cabs2cil we have turned the call to builtin_va_arg into a
36343613
* three-argument call: the last argument is the address of the
36353614
* destination *)
@@ -3813,15 +3792,21 @@ class defaultCilPrinterClass : cilPrinter = object (self)
38133792

38143793
method private pStmtNext (next: stmt) () (s: stmt) =
38153794
(* print the labels *)
3816-
((docList ~sep:line (fun l -> self#pLabel () l)) () s.labels)
3817-
(* print the statement itself. If the labels are non-empty and the
3818-
* statement is empty, print a semicolon *)
3819-
++
3820-
(if s.skind = Instr [] && s.labels <> [] then
3821-
text ";"
3822-
else
3823-
(if s.labels <> [] then line else nil)
3824-
++ self#pStmtKind next () s.skind)
3795+
let labels = ((docList ~sep:line (fun l -> self#pLabel () l)) () s.labels) in
3796+
if s.skind = Instr [] && s.labels <> [] then
3797+
(* If the labels are non-empty and the statement is empty, print a semicolon *)
3798+
labels ++ text ";"
3799+
else
3800+
let pre =
3801+
if s.labels <> [] then
3802+
(match s.skind with
3803+
| Instr (VarDecl(_)::_)-> text ";" (* first instruction is VarDecl, insert semicolon *)
3804+
| _ -> nil)
3805+
++ line
3806+
else
3807+
nil (* no labels, no new line needed *)
3808+
in
3809+
labels ++ pre ++ self#pStmtKind next () s.skind
38253810

38263811
method private pLabel () = function
38273812
Label (s, _, true) -> text (s ^ ": ")
@@ -4248,7 +4233,7 @@ class defaultCilPrinterClass : cilPrinter = object (self)
42484233
| None -> self#pVDecl () vi ++ text ";"
42494234
| Some i -> self#pVDecl () vi ++ text " = " ++
42504235
self#pInit () i ++ text ";")
4251-
() f.slocals)
4236+
() (List.filter (fun v -> not v.vhasdeclinstruction) f.slocals))
42524237
++ line ++ line
42534238
(* the body *)
42544239
++ ((* remember the declaration *) currentFormals <- f.sformals;

src/cil.mli

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2163,8 +2163,6 @@ class type cilPrinter = object
21632163
* in formals of function types, and the formals and locals for function
21642164
* definitions. *)
21652165

2166-
method pVDeclPhony: unit -> varinfo -> bool -> Pretty.doc
2167-
21682166
method pVar: varinfo -> Pretty.doc
21692167
(** Invoked on each variable use. *)
21702168

src/frontc/cabs2cil.ml

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,15 @@ let forceRLArgEval = ref false
6767
(** Leave a certain global alone. Use a negative number to disable. *)
6868
let nocil: int ref = ref (-1)
6969

70+
(** Set to true to generate VarDecl "instructions" for all local variables
71+
* In some circumstances, it is unavoidable to generate VarDecls (namely
72+
* for variable length arrays (VLAs)). In these cases, we generate a VarDecl
73+
* even if alwaysGenerateVarDecl is false.
74+
* Under certain conditions (involving GNU computed gotos), it is not possible
75+
* to generate VarDecls for all locals, in these cases we do not generate them
76+
* *)
77+
let alwaysGenerateVarDecl = true
78+
7079
(** Indicates whether we're allowed to duplicate small chunks. *)
7180
let allowDuplication: bool ref = ref true
7281

@@ -2662,7 +2671,6 @@ and makeVarSizeVarInfo (ldecl : location)
26622671
ldecl spec_res (n,ndt,a), empty, false
26632672
| Some (ndt', se, len) ->
26642673
let vi = makeVarInfoCabs ~isformal:false ~isglobal:false ldecl spec_res (n,ndt',a) in
2665-
vi.vhasdeclinstruction <- true;
26662674
vi.vtype <- insertArrayLengths vi.vtype len; (* patch the correct length for the array back-in *)
26672675
vi, se, true
26682676
else
@@ -5467,7 +5475,7 @@ and createGlobal (specs : (typ * storage * bool * A.attribute list))
54675475
*)
54685476

54695477
(* Must catch the Static local variables. Make them global *)
5470-
and createLocal ((_, sto, _, _) as specs)
5478+
and createLocal ?allow_var_decl:(allow_var_decl=true) ((_, sto, _, _) as specs)
54715479
((((n, ndt, a, cloc) : A.name),
54725480
(inite: A.init_expression)) as init_name)
54735481
: chunk =
@@ -5554,15 +5562,23 @@ and createLocal ((_, sto, _, _) as specs)
55545562
let vi,se0,isvarsize =
55555563
makeVarSizeVarInfo loc specs (n, ndt, a) in
55565564
let vi = alphaConvertVarAndAddToEnv true vi in (* Replace vi *)
5557-
let se1 =
5558-
if isvarsize then begin (* Variable-sized array *)
5559-
ignore (warn "Variable-sized local variable %s" vi.vname);
5560-
if inite != A.NO_INIT then
5561-
E.s (error "Variable-sized array cannot have initializer");
5562-
se0 +++ VarDecl(vi, !currentLoc)
5563-
end else
5564-
empty
5565+
let sevarsize = (* Chunk that is needed to pull out things for variable-length arrays *)
5566+
if isvarsize then
5567+
begin
5568+
ignore (warn "Variable-sized local variable %s" vi.vname);
5569+
if inite != A.NO_INIT then
5570+
E.s (error "Variable-sized array cannot have initializer")
5571+
else if not allow_var_decl then
5572+
E.s (error "VLAs in conjunction with computed gotos are unsupported.")
5573+
else
5574+
se0
5575+
end
5576+
else
5577+
empty
55655578
in
5579+
let makevdecl = (isvarsize || alwaysGenerateVarDecl && allow_var_decl) in
5580+
let se1 = if makevdecl then sevarsize +++ VarDecl(vi, !currentLoc) else sevarsize in
5581+
vi.vhasdeclinstruction <- makevdecl;
55665582
if inite = A.NO_INIT then
55675583
se1 (* skipChunk *)
55685584
else begin
@@ -6518,8 +6534,9 @@ and doStatement (s : A.statement) : chunk =
65186534
@@ s2c(mkStmt(Goto (ref switch, loc')))
65196535

65206536
| None -> begin
6521-
(* Make a temporary variable *)
6522-
let vchunk = createLocal
6537+
(* Make a temporary variable, avoiding generation of VarDecl if possible *)
6538+
(* as this is unsupported (see below) *)
6539+
let vchunk = createLocal ~allow_var_decl:false
65236540
(!upointType, NoStorage, false, [])
65246541
(("__compgoto", A.JUSTBASE, [], loc), A.NO_INIT)
65256542
in

0 commit comments

Comments
 (0)