<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Hi Lei,<div><br></div><div>The part that scares me is the recursive walk of the callee's body. That's not likely to have good enough performance for a compile-time warning. For a compile-time warning, I think it is fine to just check the body of the constructor, but if you want to analyze the bodies of called functions you'd need to be extremely clever to do it efficiently enough for it to be a compile-time warning. We really like compiler warnings to have highly predictable performance, and recursively walking the entire classes's method bodies is not really amendable to that.</div><div><br></div><div>If you think walking through all the bodies is necessary, then I'd leave it as a static analyzer checker. You'd certainly get better coverage. To handle the recursion, I'd probably make it a worklist (i.e., data recursive) to avoid stack blowup and to keep your memory footprint small. You should also employ dynamic programming to avoid analyzing the same methods again. The other nice thing about this approach is that it probably can be nicely generalized to global IPA once we have it.</div><div><br></div><div>One caveat about doing a recursive analysis of method bodies without any path-based analysis is that you are introducing additional risk of a false positive. There could be unreachable paths where a constructor can't actually transitively trigger a call to a virtual function because of the context, but your check may report an issue. I don't think this will typically be a problem, but it is something to consider.</div><div><br></div><div>Cheers,</div><div>Ted</div><div><br></div><div><div><div>On Sep 27, 2011, at 1:39 AM, 章磊 wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>Hi Ted,</div>
<div> </div>
<div>My goal is to check whether there is a virtual call (directly or indirectly) in construction or destruction.</div>
<div> </div>
<div>In my former patch i do this check to all the constructors and the destructor in checkASTDecl(const CXXRecordDecl ...). My way is walk through the ast body of ctor/dtor: if there is virtual call, warn it; if there is a call, walk through the callee's body recursively.</div>
<div> </div>
<div>I think it's ok to do this check without the analysis engine and the inline IPA.</div>
<div> </div>
<div>What you say?<br></div>
<div class="gmail_quote">在 2011年9月26日 下午9:37,Ted Kremenek <span dir="ltr"><<a href="mailto:kremenek@apple.com" target="_blank">kremenek@apple.com</a>></span>写道:<br>
<blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">
<div style="WORD-WRAP: break-word">
<div>
<div>
<div>On Sep 25, 2011, at 2:32 AM, 章磊 wrote:</div><br>
<blockquote type="cite"><span style="WORD-SPACING: 0px; FONT: medium Helvetica; TEXT-TRANSFORM: none; TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate">Hi Ted,<br><br>I tried to implement this as a compiler warning. But i had some<br>
problem in how to get the body of the ctor or dtor.<br><br>I implemented this in Sema::CheckConstructor and<br>Sema::CheckDestructor, but i can not get the body of them when there<br>is no body with the declaration yet.</span></blockquote>
<div><br></div></div>
<div>The idea how I thought this would be implemented was to do the analysis when processing CallExprs as we are building them. We should know up front when we are about to process a constructor body. Simply set/clear a Sema flag when processing the constructor body, and your check can consult that flag when processing a CallExpr to see if it needs to do the check. Alternatively, checking the DeclContext may be all that is needed to see if we are currently in a constructor body.</div>
<div><br></div>
<div>The advantage of this approach is that it keeps all the checking local. Walking the AST of a constructor body *after* we have constructed it is slow, and not really a great approach for doing compiler warnings in the frontend (if we can at all help it).</div>
<div>
<div><br></div>
<blockquote type="cite"><span style="WORD-SPACING: 0px; FONT: medium Helvetica; TEXT-TRANSFORM: none; TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate">And i also need the function body<br>
of the CallExpr in the ctor/dtor to do recursive analysis.<br></span></blockquote></div></div><br>
<div>Interesting. If your goal is to do inter procedural analysis, then this should remain a static analyzer check, or that should be a case caught beyond what a compiler warning should do. That wasn't clear to me before that this was something you wanted to do.</div>
<div><br></div>
<div>The tradeoffs between compiler and static analyzer warnings are fairly simple:</div>
<div><br></div>
<div>1) Compiler warnings have higher visibility because all users see them all the time when building their code.</div>
<div><br></div>
<div>2) The logic behind compiler warnings must be as fast as possible. Inter-procedural analysis is usually a show stopper, and ideally the checks are highly local. Sema is already "walking" all of the code as it builds the AST, so often the warning logic can be put in key places, essentially where the warning would be issued.</div>
<div><br></div>
<div><br></div></div></blockquote></div><br><br clear="all"><br>-- <br>Best regards!<br><br>Lei Zhang<br>
</blockquote></div><br></div></body></html>