Skip to content

Commit abe64c5

Browse files
authored
Merge pull request #211 from goblint/issue-183
Fix location tracking for for loop expressions
2 parents 7797529 + 2b982a0 commit abe64c5

File tree

6 files changed

+27
-16
lines changed

6 files changed

+27
-16
lines changed

src/frontc/cabs.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,8 @@ and statement =
221221
| IF of expression * statement * statement * cabsloc * cabsloc (* second cabsloc is just for expression *)
222222
| WHILE of expression * statement * cabsloc * cabsloc (* second cabsloc is just for expression *)
223223
| DOWHILE of expression * statement * cabsloc * cabsloc (* second cabsloc is just for expression *)
224-
| FOR of for_clause * expression * expression * statement * cabsloc * cabsloc (* second cabsloc is just for expression *)
224+
| FOR of for_clause * cabsloc * expression * cabsloc * expression * cabsloc * statement * cabsloc * cabsloc
225+
(* for_clause, for_clause_loc, condition, condition_loc, increment, increment_loc, body, loop_loc, expr_loc *)
225226
| BREAK of cabsloc
226227
| CONTINUE of cabsloc
227228
| RETURN of expression * cabsloc * cabsloc (* second cabsloc is just for expression *)

src/frontc/cabs2cil.ml

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6853,24 +6853,31 @@ and doStatement (s : A.statement) : chunk =
68536853
exitLoop ();
68546854
loopChunk (s' @@ s'')
68556855

6856-
| A.FOR(fc1,e2,e3,s,loc,eloc) -> begin
6856+
| A.FOR(fc1,fc_loc,e2,e2_loc,e3,e3_loc,s,loc,eloc) -> begin
68576857
let loc' = convLoc loc in
68586858
let eloc' = convLoc eloc in
6859-
currentLoc := loc'; (* For loop statement location is not synthetic. *)
6860-
currentExpLoc := SynthetizeLoc.doLoc eloc';
6859+
let fc_loc' = convLoc fc_loc in
6860+
let e2_loc' = convLoc e2_loc in
6861+
let e3_loc' = convLoc e3_loc in
6862+
currentLoc := loc'; (* For loop statement location is not synthetic (see se1 comment below). *)
6863+
currentExpLoc := SynthetizeLoc.doLoc fc_loc';
68616864
enterScope (); (* Just in case we have a declaration *)
68626865
let (se1, _, _) =
68636866
match fc1 with
68646867
FC_EXP e1 -> doExp false e1 ADrop
6865-
| FC_DECL d1 -> (doDecl false false d1, zero, voidType)
6868+
| FC_DECL d1 -> (doDecl false false d1, zero, voidType) (* doDecl may modify currentLoc and currentExpLoc! *)
68666869
in
68676870
(* First instruction (assignment) in for loop initializer has non-synthetic statement location before for loop.
68686871
Its expression location inside for loop parentheses is synthetic.
68696872
All other instructions are fully synthetic. *)
68706873
let se1 = SynthetizeLoc.eDoChunkHead (SynthetizeLoc.doChunkTail se1) in
6871-
let (se3, _, _) = doExp false e3 ADrop in
6872-
let se3 = SynthetizeLoc.doChunkHead se3 in
6874+
(* Reset both locations due to doDecl (see above). *)
6875+
currentLoc := loc'; (* TODO: Why is statement location not synthetic here? Not needed? *)
6876+
currentExpLoc := SynthetizeLoc.doLoc e3_loc';
6877+
let (se3, _, _) = doExp false e3 ADrop in (* doExp does doChunkTail *)
6878+
let se3 = SynthetizeLoc.doChunkHead se3 in (* So just doChunkHead is enough *)
68736879
startLoop false;
6880+
(* TODO: Are these locations ever used in doStatement? Why not synthetic? *)
68746881
currentLoc := loc';
68756882
currentExpLoc := eloc';
68766883
let s' = doStatement s in
@@ -6880,6 +6887,8 @@ and doStatement (s : A.statement) : chunk =
68806887
let break_cond = breakChunk loc' in (* TODO: use eloc'? *)
68816888
exitLoop ();
68826889
let res =
6890+
currentLoc := SynthetizeLoc.doLoc loc';
6891+
currentExpLoc := SynthetizeLoc.doLoc e2_loc';
68836892
match e2 with
68846893
A.NOTHING -> (* This means true *)
68856894
se1 @@ loopChunk (consLabLoopCondition s' @@ s'')

src/frontc/cabshelper.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ begin
9090
| IF(_,_,_,loc,_) -> loc
9191
| WHILE(_,_,loc,_) -> loc
9292
| DOWHILE(_,_,loc,_) -> loc
93-
| FOR(_,_,_,_,loc,_) -> loc
93+
| FOR(_,_,_,_,_,_,_,loc,_) -> loc
9494
| BREAK(loc) -> loc
9595
| CONTINUE(loc) -> loc
9696
| RETURN(_,loc,_) -> loc

src/frontc/cabsvisit.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ and childrenStatement vis s =
372372
let e' = ve e in
373373
let s1' = vs l s1 in
374374
if e' != e || s1' != s1 then DOWHILE (e', s1', l, el) else s
375-
| FOR (fc1, e2, e3, s4, l, el) ->
375+
| FOR (fc1, fc_loc, e2, e2_loc, e3, e3_loc, s4, l, el) ->
376376
let _ = vis#vEnterScope () in
377377
let fc1' =
378378
match fc1 with
@@ -392,7 +392,7 @@ and childrenStatement vis s =
392392
let s4' = vs l s4 in
393393
let _ = vis#vExitScope () in
394394
if fc1' != fc1 || e2' != e2 || e3' != e3 || s4' != s4
395-
then FOR (fc1', e2', e3', s4', l, el) else s
395+
then FOR (fc1', fc_loc, e2', e2_loc, e3', e3_loc, s4', l, el) else s
396396
| BREAK _ | CONTINUE _ | GOTO _ -> s
397397
| RETURN (e, l, el) ->
398398
let e' = ve e in

src/frontc/cparser.mly

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ let transformOffsetOf (speclist, dtype) member =
384384
%type <Cabs.statement list> block_element_list
385385
%type <string list> local_labels local_label_names
386386
%type <string list> old_parameter_list_ne
387+
%type <Cabs.for_clause * cabsloc> for_clause
387388

388389
%type <Cabs.init_name> init_declarator
389390
%type <Cabs.init_name list> init_declarator_list
@@ -952,9 +953,9 @@ statement_no_null:
952953
{WHILE (smooth_expression (fst $2), $4, joinLoc $1 $5, joinLoc (snd $2) $3)}
953954
| DO statement WHILE paren_comma_expression SEMICOLON
954955
{DOWHILE (smooth_expression (fst $4), $2, joinLoc $1 $5, joinLoc (snd $4) $5)}
955-
| FOR LPAREN for_clause opt_expression
956-
SEMICOLON opt_expression RPAREN statement location
957-
{FOR ($3, $4, $6, $8, joinLoc $1 $9, joinLoc $2 $7)}
956+
| FOR LPAREN for_clause location opt_expression location
957+
SEMICOLON location opt_expression location RPAREN statement location
958+
{let (fc, fc_loc) = $3 in FOR (fc, fc_loc, $5, joinLoc $4 $6, $9, joinLoc $8 $10, $12, joinLoc $1 $13, joinLoc $2 $11)}
958959
| IDENT COLON attribute_nocv_list location statement_no_null
959960
{(* The only attribute that should appear here
960961
is "unused". For now, we drop this on the
@@ -989,8 +990,8 @@ statement_no_null:
989990

990991

991992
for_clause:
992-
opt_expression SEMICOLON { FC_EXP $1 }
993-
| declaration { FC_DECL $1 }
993+
location opt_expression SEMICOLON { (FC_EXP $2, joinLoc $1 $3) }
994+
| location declaration location { (FC_DECL $2, joinLoc $1 $3) }
994995
;
995996

996997
declaration: /* ISO 6.7.*/

src/frontc/cprint.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ and print_statement stat =
633633
print_expression_level 0 exp;
634634
print ");";
635635
new_line ();
636-
| FOR (fc1, exp2, exp3, stat, loc, eloc) ->
636+
| FOR (fc1, _, exp2, _, exp3, _, stat, loc, eloc) ->
637637
setLoc(loc);
638638
printl ["for";"("];
639639
(match fc1 with

0 commit comments

Comments
 (0)