<div dir="ltr">Anna,<div><br></div><div>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><br></div><div>By the way, I'm using clang SA for data-flow analysis. So if I have a class defined as</div><div><br></div><div><div>class MyClass {</div><div>public:</div><div><span class="" style="white-space:pre"> MyClass</span>(int x, int y, int z) {</div><div><span class="" style="white-space:pre"> </span>a = x;</div><div><span class="" style="white-space:pre"> </span>b = y;</div><div><span class="" style="white-space:pre"> </span>c = z;</div><div><span class="" style="white-space:pre"> </span>}</div><div>private:</div><div><span class="" style="white-space:pre"> </span>int a;</div><div><span class="" style="white-space:pre"> </span>int b;</div><div><span class="" style="white-space:pre"> </span>int c;</div><div>};</div></div><div><br></div><div>then a call</div><div><br></div><div>...</div><div>MyClass C(i1, i2, i3);</div><div>...</div><div><br></div><div>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><br></div><div>~Scott</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Sep 14, 2015 at 2:31 PM, Anna Zaks via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">Scott,<div><br></div><div>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><br></div><div>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)">-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">http://clang-analyzer.llvm.org/checker_dev_manual.html</a>)</div><div><br></div><div>Anna.</div><div><br><div><blockquote type="cite"><div><div class="h5"><div>On Sep 10, 2015, at 10:29 AM, scott constable via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:</div><br></div></div><div><div><div class="h5"><div dir="ltr">Hi All,<div><br></div><div>It seems that the clang static analyzer does not correctly handle C++ constructors. For example, I have the following code:</div><div><br></div><div><div>struct S {</div><div><span style="white-space:pre-wrap"> </span>S(int x, int y, int z) {</div><div><span style="white-space:pre-wrap"> </span>a = x;</div><div><span style="white-space:pre-wrap"> </span>b = y;</div><div><span style="white-space:pre-wrap"> </span>c = z;</div><div><span style="white-space:pre-wrap"> </span>}</div><div><span style="white-space:pre-wrap"> </span>int a;</div><div><span style="white-space:pre-wrap"> </span>int b;</div><div><span style="white-space:pre-wrap"> </span>int c;</div><div>};</div><div><br></div><div>void objectCreate() {</div><div><span style="white-space:pre-wrap"> </span>S *newS = new S(12, 0, 15);</div><div><span style="white-space:pre-wrap"> </span>if (newS->b)</div><div><span style="white-space:pre-wrap"> </span>newS->c++;</div><div><span style="white-space:pre-wrap"> </span>else</div><div><span style="white-space:pre-wrap"> </span>newS->a++;</div><div><span style="white-space:pre-wrap"> </span>delete newS;</div><div>}</div></div><div><br></div><div>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><br></div><div>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><br></div><div>Any help would be so very appreciated, as this has been driving me crazy!</div><div><br></div><div>~Scott Constable</div></div></div></div>
_______________________________________________<br>cfe-dev mailing list<br><a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br></div></blockquote></div><br></div></div><br>_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
<br></blockquote></div><br></div>