<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
Note that the surrounding statement is not necessarily in the same
block. Say, your algorithm would fail to find full statement 'x ? y
: z;' by looking at its sub-expression 'y'.<br>
<br>
As far as i'm aware, no existing data flow analyses operate the way
you describe.<br>
<br>
<div class="moz-cite-prefix">On 9/8/20 7:15 AM, Andrew Sutton via
cfe-dev wrote:<br>
</div>
<blockquote type="cite"
cite="mid:CAFVAEf2bZRxhQWOKVFEs8DLOZvkNeuo1ZK=A-nA_WoGPW=MzcA@mail.gmail.com">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<div dir="ltr">I ran into exactly this problem last week. I wanted
to visit top-level statements (and expressions since
expression-statements are just expressions) and recursively work
through their ASTs. I just wrote a small pre-pass over the CFG
elements that would construct a set of top-level statements by
noting which expressions occurred as subexpressions and then
extract the statements from there.
<div>
<div><br>
</div>
<div>There's probably a better way to do this, but here's what
my implementation of that function looks like.<br>
<div><br>
</div>
<div> void findStatements(CFGBlock *B,
llvm::SmallVectorImpl<const Stmt *> &SS) {<br>
llvm::SmallDenseMap<const Stmt*, bool> Map;<br>
<br>
// Mark subexpressions of each element in the block.<br>
for (auto I = B->begin(); I != B->end(); ++I)
{<br>
CFGElement E = *I;<br>
if (auto SE = E.getAs<CFGStmt>()) {<br>
const Stmt *S = SE->getStmt();<br>
for (const Stmt *K : S->children())<br>
Map[K] = true;<br>
}<br>
}<br>
<br>
// Any expressions not in Map are statements.<br>
for (auto I = B->begin(); I != B->end(); ++I)
{<br>
CFGElement E = *I;<br>
if (auto SE = E.getAs<CFGStmt>()) {<br>
const Stmt *S = SE->getStmt();<br>
if (Map.find(S) == Map.end())<br>
SS.push_back(S);<br>
}<br>
}<br>
}<br>
</div>
</div>
</div>
<div><br>
</div>
<div>Andrew Sutton</div>
<div><br>
</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Tue, Sep 8, 2020 at 9:44 AM
Stefan Schulze Frielinghaus via cfe-dev <<a
href="mailto:cfe-dev@lists.llvm.org" moz-do-not-send="true">cfe-dev@lists.llvm.org</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi
all,<br>
<br>
I'm trying to iterate over all top-level functions of a C file
and perform<br>
control-flow analysis of each function body. My current
approach looks as<br>
follows:<br>
<br>
class MyASTVisitor : public DeclVisitor<MyASTVisitor> {<br>
ASTContext &Context;<br>
public:<br>
explicit MyASTVisitor(ASTContext &Context) :
Context(Context) { }<br>
<br>
void VisitFunctionDecl(FunctionDecl *FD) {<br>
if (!FD->hasBody())<br>
return;<br>
<br>
FD->getNameInfo().getName().dump();<br>
<br>
const CFG::BuildOptions opts;<br>
auto CFG = CFG::buildCFG(FD, FD->getBody(),
&Context, opts);<br>
CFG->dump(Context.getLangOpts(), true);<br>
// perform the actual analysis over the CFG<br>
}<br>
};<br>
<br>
class MyConsumer : public ASTConsumer {<br>
MyASTVisitor Visitor;<br>
public:<br>
explicit MyConsumer(ASTContext &Context) :
Visitor(Context) { }<br>
<br>
bool HandleTopLevelDecl(DeclGroupRef DR) override {<br>
for (auto *I : DR)<br>
Visitor.Visit(I);<br>
return true;<br>
}<br>
};<br>
<br>
What confuses me right now is how the CFG is structured.
Consider the<br>
following C code:<br>
<br>
extern int *pi;<br>
extern unsigned char *pc;<br>
void foo(void) {<br>
*(pi=(int *)pc, pi) = 42;<br>
}<br>
<br>
The dump of the corresponding CFG looks as follows:<br>
<br>
[B2 (ENTRY)]<br>
Succs (1): B1<br>
<br>
[B1]<br>
1: pi = (int *)pc<br>
2: pi (ImplicitCastExpr, LValueToRValue, int *)<br>
3: ... , [B1.2]<br>
4: *([B1.3]) = 42<br>
Preds (1): B2<br>
Succs (1): B0<br>
<br>
[B0 (EXIT)]<br>
Preds (1): B1<br>
<br>
The single statement<br>
*(pi=(int *)pc, pi) = 42;<br>
is broken up into 4 statements in the CFG. That means, if I
iterate over each<br>
statement of a block like<br>
<br>
for (const CFGBlock *block : *CFG) {<br>
for (const auto &I : *block) {<br>
if (Optional<CFGStmt> cs = I.getAs<CFGStmt>())<br>
TF.Visit(cs->getStmt());<br>
}<br>
}<br>
<br>
and the transfer functions TF recursively visit each
subexpression, I will<br>
visit some of them twice. My plan was actually to construct
transfer functions<br>
of type ConstStmtVisitor in order to examine each statement
recursively. In<br>
the past I ran into a similar problem which was related to
wrongly set<br>
CFG::BuildOptions. However, this does not seem to be the case
this time.<br>
<br>
Is it possible to construct a CFG where statements are not
split? Or is there<br>
another approach to walk over all statements of a basic block
exactly one time?<br>
<br>
Cheers,<br>
Stefan<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank"
moz-do-not-send="true">cfe-dev@lists.llvm.org</a><br>
<a
href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev"
rel="noreferrer" target="_blank" moz-do-not-send="true">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote>
</div>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<pre class="moz-quote-pre" wrap="">_______________________________________________
cfe-dev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>
<a class="moz-txt-link-freetext" href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a>
</pre>
</blockquote>
<br>
</body>
</html>