[PATCH] Analyzer: model trivial copy constructors directly

Anna Zaks ganna at apple.com
Mon Jan 28 18:43:59 PST 2013


On Jan 24, 2013, at 5:35 PM, Jordan Rose <jordan_rose at apple.com> wrote:

> Hi, Anna. This is the analyzer patch I was working on: modeling the evaluation of a trivial copy constructor with a bind. The idea is pretty straightforward, but I wondered if you had any opinions on the design. Does it make sense to do this as a replacement for defaultEvalCall in VisitCXXConstructExpr? Is there another place to fit it in that would make more sense?
> 
> (Part of why I'm hesitant is because this is modifying Core when it could just be a core checker in theory. That requires talking about switching to evalCall(CallEvent), though, instead of the current limited evalCall(CallExpr). In practice, I don't think checkers can properly model a user-level bind right now, and using BodyFarm wouldn't work because you can't copy structs by value in C++.)
> 

I think it's fine to implement this in the core. That is where the C++ semantics are being interpreted now.

> Besides making it cheaper to process these constructors (which in C don't even have the preCall/postCall overhead), this eliminates the spurious warning for copying a not-fully-initialized POD struct, which would match our C behavior. (It's not such an uncommon thing to do.)
> 
> CGPoint p;
> p.x = 0;
> CGPoint p2 = p; // no-warning
> 
> This is <rdar://problem/12305288>. If we don't want to do this at all, though, I'll just not emit the warning when in a trivial copy-or-move constructor.
> 
> What do you think?
> Jordan
> 
> <trivial-copy-ctors.patch>

+  /// Models a trivial copy or move constructor call with a simple bind.
Does this deal with move constructors as well? Are there test cases?

Could you add a comment on when this if statement is needed and when it is not needed?
+  if (const Loc *L = dyn_cast<Loc>(&V))
+    V = Pred->getState()->getSVal(*L);

+    // Note that we have to be careful here because constructors embedded
+    // in DeclStmts are not marked as lvalues.
+    if (!E->isGLValue())
+      if (const MemRegion *MR = ThisV.getAsRegion())
+        if (isa<CXXTempObjectRegion>(MR))
I do not fully understand what the comment means and why the test for CXXTempObjectRegion is needed (if I comment it out all tests pass). So maybe better comment and more tests?

+  ExplodedNodeSet Dst;
+  Bldr.takeNodes(Pred);
:( You could possibly just pass Src and Dst to performTrivialCopy to avoid this, but I don't think there is a great solution here other than finishing transitioning to Builders everywhere.



More information about the cfe-commits mailing list