On Mon, Jun 24, 2013 at 6:56 PM, Jordan Rose <[email protected]> wrote: > Author: jrose > Date: Mon Jun 24 20:55:59 2013 > New Revision: 184814 > > URL: http://llvm.org/viewvc/llvm-project?rev=184814&view=rev > Log: > [analyzer] Don't initialize virtual base classes more than once. > > In order to make sure virtual base classes are always initialized once, > the AST contains initializers for the base class in /all/ of its > descendents, not just the immediate descendents. However, at runtime, > the most-derived object is responsible for initializing all the virtual > base classes; all the other initializers will be ignored. > > The analyzer now checks to see if it's being called from another base > constructor, and if so does not perform virtual base initialization.
Vague/uninformed question: If you modelled the C1/C2/(C3?) ctors as they exist would this just come out more naturally? (maybe this is a sufficient model of that) > > <rdar://problem/14236851> > > Modified: > cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp > cfe/trunk/test/Analysis/ctor-inlining.mm > > Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=184814&r1=184813&r2=184814&view=diff > ============================================================================== > --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original) > +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Mon Jun 24 20:55:59 > 2013 > @@ -187,8 +187,26 @@ void ExprEngine::VisitCXXConstructExpr(c > > break; > } > - case CXXConstructExpr::CK_NonVirtualBase: > case CXXConstructExpr::CK_VirtualBase: > + // Make sure we are not calling virtual base class initializers twice. > + // Only the most-derived object should initialize virtual base classes. > + if (const Stmt *Outer = LCtx->getCurrentStackFrame()->getCallSite()) { > + const CXXConstructExpr *OuterCtor = dyn_cast<CXXConstructExpr>(Outer); > + if (OuterCtor) { > + switch (OuterCtor->getConstructionKind()) { > + case CXXConstructExpr::CK_NonVirtualBase: > + case CXXConstructExpr::CK_VirtualBase: > + // Bail out! > + destNodes.Add(Pred); > + return; > + case CXXConstructExpr::CK_Complete: > + case CXXConstructExpr::CK_Delegating: > + break; > + } > + } > + } > + // FALLTHROUGH > + case CXXConstructExpr::CK_NonVirtualBase: > case CXXConstructExpr::CK_Delegating: { > const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl()); > Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor, > > Modified: cfe/trunk/test/Analysis/ctor-inlining.mm > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/ctor-inlining.mm?rev=184814&r1=184813&r2=184814&view=diff > ============================================================================== > --- cfe/trunk/test/Analysis/ctor-inlining.mm (original) > +++ cfe/trunk/test/Analysis/ctor-inlining.mm Mon Jun 24 20:55:59 2013 > @@ -500,3 +500,37 @@ namespace ArrayMembers { > clang_analyzer_eval(c.values[2].x == 3); // expected-warning{{UNKNOWN}} > } > }; > + > +namespace VirtualInheritance { > + int counter; > + > + struct base { > + base() { > + ++counter; > + } > + }; > + > + struct virtual_subclass : public virtual base { > + virtual_subclass() {} > + }; > + > + struct double_subclass : public virtual_subclass { > + double_subclass() {} > + }; > + > + void test() { > + counter = 0; > + double_subclass obj; > + clang_analyzer_eval(counter == 1); // expected-warning{{TRUE}} > + } > + > + struct double_virtual_subclass : public virtual virtual_subclass { > + double_virtual_subclass() {} > + }; > + > + void testVirtual() { > + counter = 0; > + double_virtual_subclass obj; > + clang_analyzer_eval(counter == 1); // expected-warning{{TRUE}} > + } > +} > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
