Skip to content

Commit 252ef02

Browse files
committed
Instrument: fix the handling of declarations in while loop conditions
This fixes the handling of "while (T var = expr)" C++ constructs. TN: V816-018 Change-Id: Icd1a0a47f9608ed1472aaa7f255c96973540da20
1 parent 52f3ca4 commit 252ef02

File tree

4 files changed

+58
-6
lines changed

4 files changed

+58
-6
lines changed

tools/gnatcov/clang-extensions.ads

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ package Clang.Extensions is
3939
function Get_For_Inc (C : Cursor_T) return Cursor_T
4040
with Import, Convention => C, External_Name => "clang_getForInc";
4141

42+
function Get_Cond_Var (C : Cursor_T) return Cursor_T
43+
with Import, Convention => C, External_Name => "clang_getCondVar";
44+
45+
function Get_Var_Init_Expr (C : Cursor_T) return Cursor_T
46+
with Import, Convention => C, External_Name => "clang_getVarInitExpr";
47+
4248
function Get_Then (C : Cursor_T) return Cursor_T
4349
with Import, Convention => C, External_Name => "clang_getThen";
4450

tools/gnatcov/clang-wrapper.cc

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,15 @@ MakeCXCursorWithNull (const Stmt *S, CXCursor C)
5959
return clang_getNullCursor ();
6060
}
6161

62+
CXCursor
63+
MakeCXCursorWithNull (const Decl *decl, CXCursor C)
64+
{
65+
if (decl)
66+
return MakeCXCursor (decl, getCursorTU (C));
67+
else
68+
return clang_getNullCursor ();
69+
}
70+
6271
/* Most of the functions are getters around existing clang functions of a
6372
similar name, for the accepted type(s). For instance, clang_getCond will
6473
simply call getCond on the given node, if this is a statement or an
@@ -181,6 +190,40 @@ clang_getForInc (CXCursor C)
181190
return clang_getNullCursor ();
182191
}
183192

193+
extern "C" CXCursor
194+
clang_getCondVar (CXCursor C)
195+
{
196+
const Stmt *stmt;
197+
const WhileStmt *while_stmt;
198+
const VarDecl *decl;
199+
200+
if (clang_isStatement (C.kind)
201+
&& (stmt = cxcursor::getCursorStmt (C))
202+
&& stmt->getStmtClass () == Stmt::WhileStmtClass)
203+
{
204+
while_stmt = cast<WhileStmt> (stmt);
205+
if (decl = while_stmt->getConditionVariable ())
206+
return MakeCXCursorWithNull (decl, C);
207+
}
208+
return clang_getNullCursor ();
209+
}
210+
211+
extern "C" CXCursor
212+
clang_getVarInitExpr (CXCursor C)
213+
{
214+
const Decl *decl;
215+
const VarDecl *var_decl;
216+
217+
if (clang_isDeclaration (C.kind)
218+
&& (decl = cxcursor::getCursorDecl (C))
219+
&& decl->getKind () == Decl::Kind::Var)
220+
{
221+
var_decl = cast<VarDecl> (decl);
222+
return MakeCXCursorWithNull (var_decl->getInit (), C);
223+
}
224+
return clang_getNullCursor ();
225+
}
226+
184227
extern "C" CXCursor
185228
clang_getThen (CXCursor C)
186229
{

tools/gnatcov/instrument-c.adb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1898,16 +1898,24 @@ package body Instrument.C is
18981898
when Cursor_While_Stmt =>
18991899
declare
19001900
While_Body : constant Cursor_T := Get_Body (N);
1901+
Cond_Var : constant Cursor_T := Get_Cond_Var (N);
19011902
Cond : constant Cursor_T := Get_Cond (N);
19021903
Inner_Dominant : constant Dominant_Info := ('S', N);
19031904

19041905
begin
19051906
UIC.Pass.Curlify (N => While_Body,
19061907
Rew => UIC.Rewriter);
1908+
1909+
-- If the loop condition is a declaration, instrument its
1910+
-- initialization expression.
1911+
19071912
Extend_Statement_Sequence
19081913
(N, 'W',
1909-
Insertion_N => Cond,
1914+
Insertion_N => (if Is_Null (Cond_Var)
1915+
then Cond
1916+
else Get_Var_Init_Expr (Cond_Var)),
19101917
Instr_Scheme => Instr_Expr);
1918+
19111919
Process_Decisions_Defer (Cond, 'W');
19121920
Set_Statement_Entry;
19131921
Traverse_Statements

tools/gnatcov/instrument-c.ads

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,6 @@ package Instrument.C is
119119
-- very well be a goto pointing inside the loop, making it skip the
120120
-- execution of the witness statement, but we would still be executing the
121121
-- condition of the loop on the second iteration.
122-
--
123-
-- TODO??? we still have to figure out what should be done with such valid
124-
-- C++ constructs:
125-
--
126-
-- while (int i = calc()){}
127122

128123
type C_Source_Statement is record
129124
LL_SCO : Nat;

0 commit comments

Comments
 (0)