<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<br>
<br>
<div class="moz-cite-prefix">On 6/12/18 7:05 AM, Rafael·Stahl wrote:<br>
</div>
<blockquote type="cite"
cite="mid:92b3d997-1f2e-47fd-84c0-a4c1b75072e3@tum.de">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<p>Alright thanks for the info. As I see it number 2 should
already be solved, but number 1 is still not clear to me.</p>
<p>The issue is that there is no direct binding available, as is
with the non-global case.</p>
<p>- Non-global: Will return direct binding from
getBindingForField. The initialization earlier in main caused
this direct binding.<br>
</p>
<p>- Global: Does not find direct binding in getBindingForField
and cannot resolve FieldInit to a constant.<br>
</p>
</blockquote>
<br>
Well, there never is a direct binding for anything unless it was put
there during analysis, which is not the case for global
initializers. That's the exact problem you're solving.<br>
<br>
I guess the difference here is that you can't evaluate the
initializer expression in compile time (because the actual numeric
value for address of the global is not known before the program is
run), but during analysis we don't care about the precise numeric
value of the address. The SVal that represents the address of a
global variable (loc::MemRegionVal that wraps a VarRegion) says
exactly that: "it's the address of that global variable" without
specifying what this address is.<br>
<br>
So you'd have to step away from the constant folding methods used by
the compiler (eg. EvaluateAsInt) and implement analyzer-specific
constant folding that works similarly but collapses the expression
to a concrete value in the analyzer's sense rather than to a
compile-time constant value. So that DeclRefExpr(VarDecl) would
collapse to a loc::MemRegionVal(VarRegion) which is
State->getLValue(VarDecl, LCtx), where LCtx is obviously ignored
for global variables.<br>
<br>
<blockquote type="cite"
cite="mid:92b3d997-1f2e-47fd-84c0-a4c1b75072e3@tum.de">
<p> </p>
<p>Now I could add some code to the case where getConstantVal
fails to look at the FieldInit Expr and return a new FieldRegion
in a loc::MemRegionVal if I find UnaryOp(&) ->
DeclRefExpr(FieldDecl). The issue is that this is very tailored
to the example and does not work in general. I feel like the
SVal for the FieldInit Expr should be available somewhere but I
cannot figure out where.</p>
<p>There is ProgramState::getSVal(const Stmt*, const
LocationContext*) but not sure if this is applicable here - also
because the RegionStore doesn't seem to have any ProgramState or
LocationContext.<br>
</p>
<p>Rafael<br>
</p>
<br>
<div class="moz-cite-prefix">On 12.06.2018 01:59, Artem Dergachev
wrote:<br>
</div>
<blockquote type="cite"
cite="mid:26972ab8-cc6d-f876-f845-9644a46fb211@gmail.com">
<meta http-equiv="Content-Type" content="text/html;
charset=UTF-8">
Hmm. It sounds as if we need to fix both things here, and both
of them are something that you already know how to solve:<br>
<br>
1. Be able to constant-fold "gs.sub" to "&gsubs",<br>
2. Be able to constant-fold "(&gsubs)->p" to
"0x80008000".<br>
<br>
I guess the confusion arises because steps 1 and 2 are separated
in time; they are in fact two independent loads. They interact
through the Environment: we compute the sub-expression, put its
value into the Environment, then later when we need to perform
the second load we can retrieve the value from the Environment.
Once we perform the first load correctly, it becomes irrelevant
that such load ever happened; ExprEngine, like checkers, is
stateless. The problem becomes as easy as loading "gsubs.p"
because the analyzer knows, in path-sensitive manner, that the
sub-expression "gs.sub" has evaluated to "&gsubs"; that'd be
already encoded in the MemRegion structure.<br>
<br>
So i think we don't need to retroactively create anything.
Instead, we simply need to perform every step precisely. Which
is anyway a good thing because there's always code that never
gets to the second step.<br>
<br>
Sorry if the answer is not spot-on; i'm not sure i fully
understood the question.<br>
<br>
<div class="moz-cite-prefix">On 6/7/18 1:52 AM, Rafael·Stahl via
cfe-dev wrote:<br>
</div>
<blockquote type="cite"
cite="mid:de6031d6-cfba-34d4-9d0b-e839caba988a@tum.de">Hi, <br>
<br>
continuing my effort to make the analyzer understand more
constants, I did take a look at the following case: <br>
<br>
<br>
struct SubS { <br>
   int *p; <br>
}; <br>
<br>
struct S { <br>
   struct SubS *sub; <br>
}; <br>
<br>
struct SubS const gsubs = { <br>
   .p = 0x80008000 <br>
}; <br>
struct S const gs = { <br>
   .sub = &gsubs <br>
}; <br>
<br>
int main() { <br>
   struct SubS subs = { <br>
       .p = 0x80008000 <br>
   }; <br>
   struct S s = { <br>
       .sub = &subs <br>
   }; <br>
<br>
   *s.sub->p; <br>
   *gs.sub->p; <br>
} <br>
<br>
Here, the analyzer recognizes the dereference via s, but not
gs. This seems to be the case because region information will
be stored for subs, but not for gsubs. <br>
<br>
I'm not sure how to solve this issue. Could we retroactively
create the region information whenever we encounter constants
like this? Or rather add something to the getBinding functions
that manually resolves this case? For the latter it seems like
the analyzer should already understand what is happening
without many additions, but it's unclear to me how it
connects. <br>
<br>
Best regards <br>
Rafael <br>
<br>
<br>
<!--'"--><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" moz-do-not-send="true">cfe-dev@lists.llvm.org</a>
<a class="moz-txt-link-freetext" href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" moz-do-not-send="true">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a>
</pre>
</blockquote>
<br>
</blockquote>
<br>
</blockquote>
<br>
</body>
</html>