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