baloghadamsoftware created this revision.
baloghadamsoftware added reviewers: NoQ, vsavchenko.
baloghadamsoftware added a project: clang.
Herald added subscribers: ASDenysPetrov, martong, steakhal, Charusso, dkrupp, 
donat.nagy, mikhail.ramalho, a.sidorin, rnkovacs, szepet, xazax.hun, whisperity.
Herald added a reviewer: Szelethus.
baloghadamsoftware requested review of this revision.

For /C++/ constructor initializers `ExprEngine:computeUnderConstruction()` 
asserts that they are all member initializers. This is not neccessarily true 
when this function is used to get the return value for the construction context 
thus attempts to fetch return values of base and delegating constructor 
initializers result in assertions. This small patch fixes this issue.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D85351

Files:
  clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  clang/unittests/StaticAnalyzer/TestReturnValueUnderConstruction.cpp


Index: clang/unittests/StaticAnalyzer/TestReturnValueUnderConstruction.cpp
===================================================================
--- clang/unittests/StaticAnalyzer/TestReturnValueUnderConstruction.cpp
+++ clang/unittests/StaticAnalyzer/TestReturnValueUnderConstruction.cpp
@@ -54,16 +54,33 @@
                   R"(class C {
                      public:
                        C(int nn): n(nn) {}
+                       explicit C(): C(0) {}
                        virtual ~C() {}
                      private:
                        int n;
                      };
 
+                     class D: public C {
+                     public:
+                       D(int nn): C(nn) {}
+                       virtual ~D() {}
+                     };
+
                      C returnC(int m) {
                        C c(m);
                        return c;
                      }
 
+                     C returnC() {
+                       C c;
+                       return c;
+                     }
+
+                     D returnD(int m) {
+                       D d(m);
+                       return d;
+                     }
+
                      void foo() {
                        C c = returnC(1); 
                      })"));
Index: clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -132,10 +132,11 @@
     case ConstructionContext::SimpleConstructorInitializerKind: {
       const auto *ICC = cast<ConstructorInitializerConstructionContext>(CC);
       const auto *Init = ICC->getCXXCtorInitializer();
-      assert(Init->isAnyMemberInitializer());
       const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
       Loc ThisPtr = SVB.getCXXThis(CurCtor, LCtx->getStackFrame());
       SVal ThisVal = State->getSVal(ThisPtr);
+      if (Init->isBaseInitializer() || Init->isDelegatingInitializer())
+        return ThisVal;
 
       const ValueDecl *Field;
       SVal FieldVal;
@@ -364,6 +365,8 @@
     case ConstructionContext::CXX17ElidedCopyConstructorInitializerKind:
     case ConstructionContext::SimpleConstructorInitializerKind: {
       const auto *ICC = cast<ConstructorInitializerConstructionContext>(CC);
+      const auto *Init = ICC->getCXXCtorInitializer();
+      assert(Init->isAnyMemberInitializer());
       return addObjectUnderConstruction(State, ICC->getCXXCtorInitializer(),
                                         LCtx, V);
     }


Index: clang/unittests/StaticAnalyzer/TestReturnValueUnderConstruction.cpp
===================================================================
--- clang/unittests/StaticAnalyzer/TestReturnValueUnderConstruction.cpp
+++ clang/unittests/StaticAnalyzer/TestReturnValueUnderConstruction.cpp
@@ -54,16 +54,33 @@
                   R"(class C {
                      public:
                        C(int nn): n(nn) {}
+                       explicit C(): C(0) {}
                        virtual ~C() {}
                      private:
                        int n;
                      };
 
+                     class D: public C {
+                     public:
+                       D(int nn): C(nn) {}
+                       virtual ~D() {}
+                     };
+
                      C returnC(int m) {
                        C c(m);
                        return c;
                      }
 
+                     C returnC() {
+                       C c;
+                       return c;
+                     }
+
+                     D returnD(int m) {
+                       D d(m);
+                       return d;
+                     }
+
                      void foo() {
                        C c = returnC(1); 
                      })"));
Index: clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -132,10 +132,11 @@
     case ConstructionContext::SimpleConstructorInitializerKind: {
       const auto *ICC = cast<ConstructorInitializerConstructionContext>(CC);
       const auto *Init = ICC->getCXXCtorInitializer();
-      assert(Init->isAnyMemberInitializer());
       const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
       Loc ThisPtr = SVB.getCXXThis(CurCtor, LCtx->getStackFrame());
       SVal ThisVal = State->getSVal(ThisPtr);
+      if (Init->isBaseInitializer() || Init->isDelegatingInitializer())
+        return ThisVal;
 
       const ValueDecl *Field;
       SVal FieldVal;
@@ -364,6 +365,8 @@
     case ConstructionContext::CXX17ElidedCopyConstructorInitializerKind:
     case ConstructionContext::SimpleConstructorInitializerKind: {
       const auto *ICC = cast<ConstructorInitializerConstructionContext>(CC);
+      const auto *Init = ICC->getCXXCtorInitializer();
+      assert(Init->isAnyMemberInitializer());
       return addObjectUnderConstruction(State, ICC->getCXXCtorInitializer(),
                                         LCtx, V);
     }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to