<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">The analyzer does not give any guarantees about which functions will be inlined. Some of this is due to the lack of full implementation for some language features (such as destructors support) but there are other reasons for this as well, such as performance considerations. The main issue that will never completely go away is that you cannot assume that definitions of all methods/functions you call are available. They might be defined in another translation unit or in a library that the user does not have access to. <div class=""><br class=""></div><div class="">If you want to get more familiar with code that makes those decisions look at ExprEngine::defaultEvalCall which performs call evaluation. If first tries to get the function definition by calling getRuntimeDefinition(); the definition might not always be available. Afterwards, we consult a long list of policies to decide if a function whose definition we can access should be inlined. Take a look at ExprEngine::shouldInlineCall and mayInlineDecl.<div class=""><br class=""></div><div class="">The checkers/analysis built on top of the clang static analyzer have to be written to support cases where the implementation details of some functions are not available. These are usually treated in a conservative way to avoid false positives. A constructor is no different in that respect. How do your analysis treat method calls which cannot be inlined?</div><div class=""><br class=""></div><div class="">I hope this answers the question. Let me know if you need more pointers!</div><div class="">Anna.</div><div class=""><br class=""><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Sep 17, 2015, at 10:06 AM, scott constable <<a href="mailto:sdconsta@syr.edu" class="">sdconsta@syr.edu</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Anna,<div class=""><br class=""></div><div class="">Although I think I understand the issue, I'm still frustrated by the inconsistency it creates. For instance, I have observed that implicitly defined copy constructors are not inlined, whereas explicitly defined copy constructors are. Until just recently, I thought that explicitly defined constructors were always inlined, but apparently this is not the case when evaluating a CXXNewExpr. These inconsistencies seem to make it impossible to develop a uniform way to handle constructors in my analysis.</div><div class=""><br class=""></div><div class="">By the way, I'm using clang SA for data-flow analysis. So if I have a class defined as</div><div class=""><br class=""></div><div class=""><div class="">class MyClass {</div><div class="">public:</div><div class=""><span class="" style="white-space:pre"> MyClass</span>(int x, int y, int z) {</div><div class=""><span class="" style="white-space:pre"> </span>a = x;</div><div class=""><span class="" style="white-space:pre"> </span>b = y;</div><div class=""><span class="" style="white-space:pre"> </span>c = z;</div><div class=""><span class="" style="white-space:pre"> </span>}</div><div class="">private:</div><div class=""><span class="" style="white-space:pre"> </span>int a;</div><div class=""><span class="" style="white-space:pre"> </span>int b;</div><div class=""><span class="" style="white-space:pre"> </span>int c;</div><div class="">};</div></div><div class=""><br class=""></div><div class="">then a call</div><div class=""><br class=""></div><div class="">...</div><div class="">MyClass C(i1, i2, i3);</div><div class="">...</div><div class=""><br class=""></div><div class="">where argument i2 is tainted should produce an object C where C.b is tainted. As long as the constructor is inlined, this works just as expected. If it's not, I have no idea how to properly model this behavior. Is there another way to tackle this that I may not have considered?</div><div class=""><br class=""></div><div class="">~Scott</div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Mon, Sep 14, 2015 at 2:31 PM, Anna Zaks via cfe-dev <span dir="ltr" class=""><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank" class="">cfe-dev@lists.llvm.org</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="">Scott,<div class=""><br class=""></div><div class="">I suspect that the analyzer does not step into the constructor during the analysis but instead treats it as an opaque function. The temporary variable destructor support is lacking, so we choose not to “inline” or step into the constructors in some cases as well.</div><div class=""><br class=""></div><div class="">When this program is analyzed, objectCreate() is analyzed and the constructor of S is also analyzed as a top-level function. You can pass <span style="font-family:monospace;font-size:small;background-color:rgb(255,255,255)" class="">-analyzer-display-progress</span> option to the analyzer to see the order in which the top-level functions are being analyzed. (<a href="http://clang-analyzer.llvm.org/checker_dev_manual.html" target="_blank" class="">http://clang-analyzer.llvm.org/checker_dev_manual.html</a>)</div><div class=""><br class=""></div><div class="">Anna.</div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="h5"><div class="">On Sep 10, 2015, at 10:29 AM, scott constable via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank" class="">cfe-dev@lists.llvm.org</a>> wrote:</div><br class=""></div></div><div class=""><div class=""><div class="h5"><div dir="ltr" class="">Hi All,<div class=""><br class=""></div><div class="">It seems that the clang static analyzer does not correctly handle C++ constructors. For example, I have the following code:</div><div class=""><br class=""></div><div class=""><div class="">struct S {</div><div class=""><span style="white-space:pre-wrap" class=""> </span>S(int x, int y, int z) {</div><div class=""><span style="white-space:pre-wrap" class=""> </span>a = x;</div><div class=""><span style="white-space:pre-wrap" class=""> </span>b = y;</div><div class=""><span style="white-space:pre-wrap" class=""> </span>c = z;</div><div class=""><span style="white-space:pre-wrap" class=""> </span>}</div><div class=""><span style="white-space:pre-wrap" class=""> </span>int a;</div><div class=""><span style="white-space:pre-wrap" class=""> </span>int b;</div><div class=""><span style="white-space:pre-wrap" class=""> </span>int c;</div><div class="">};</div><div class=""><br class=""></div><div class="">void objectCreate() {</div><div class=""><span style="white-space:pre-wrap" class=""> </span>S *newS = new S(12, 0, 15);</div><div class=""><span style="white-space:pre-wrap" class=""> </span>if (newS->b)</div><div class=""><span style="white-space:pre-wrap" class=""> </span>newS->c++;</div><div class=""><span style="white-space:pre-wrap" class=""> </span>else</div><div class=""><span style="white-space:pre-wrap" class=""> </span>newS->a++;</div><div class=""><span style="white-space:pre-wrap" class=""> </span>delete newS;</div><div class="">}</div></div><div class=""><br class=""></div><div class="">Since newS->b initializes to 0, the expression "newS->a++" should never execute. However, the analyzer in fact generates two new states and evaluates both branches. If I replace the newS->b condition with the integer literal 0, then only the first branch is evaluated, as I would expect. I dug into this further, and found that newS's constructor is called AFTER objectCreate() has been evaluated. In other words, newS's constructor is called after "delete newS". This is clearly the wrong behavior.</div><div class=""><br class=""></div><div class="">This is not the first time I have observed C++ constructors being handled incorrectly. I also posted several weeks ago with the same observation regarding implicit copy constructors.</div><div class=""><br class=""></div><div class="">Any help would be so very appreciated, as this has been driving me crazy!</div><div class=""><br class=""></div><div class="">~Scott Constable</div></div></div></div>
_______________________________________________<br class="">cfe-dev mailing list<br class=""><a href="mailto:cfe-dev@lists.llvm.org" target="_blank" class="">cfe-dev@lists.llvm.org</a><br class=""><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" target="_blank" class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br class=""></div></blockquote></div><br class=""></div></div><br class="">_______________________________________________<br class="">
cfe-dev mailing list<br class="">
<a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a><br class="">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br class="">
<br class=""></blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></div></div></div></body></html>