r184814 - [analyzer] Don't initialize virtual base classes more than once.

David Blaikie dblaikie at gmail.com
Mon Jun 24 20:19:25 PDT 2013


On Mon, Jun 24, 2013 at 6:56 PM, Jordan Rose <jordan_rose at apple.com> 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
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits



More information about the cfe-commits mailing list