martong created this revision. martong added a reviewer: NoQ. Herald added subscribers: cfe-commits, steakhal, Charusso, gamesh411, dkrupp, donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, rnkovacs, szepet, baloghadamsoftware, xazax.hun, whisperity. Herald added a reviewer: Szelethus. Herald added a project: clang.
Skip analysis of inherited constructors as top-level functions because we cannot model the parameters. CXXInheritedCtorInitExpr doesn't take arguments and doesn't model parameter initialization because there is none: the arguments in the outer CXXConstructExpr directly initialize the parameters of the base class constructor, and no copies are made. (Making a copy of the parameter is incorrect, at least if it's done in an observable way.) The derived class constructor doesn't even exist in the formal model. E.g., in: struct X { X *p = this; ~X() {} }; struct A { A(X x) : b(x.p == &x) {} bool b; }; struct B : A { using A::A; }; B b = X{}; ... b.b is initialized to true. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D75678 Files: clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp clang/test/Analysis/cxx-inherited-ctor-init-expr.cpp Index: clang/test/Analysis/cxx-inherited-ctor-init-expr.cpp =================================================================== --- clang/test/Analysis/cxx-inherited-ctor-init-expr.cpp +++ clang/test/Analysis/cxx-inherited-ctor-init-expr.cpp @@ -57,3 +57,19 @@ clang_analyzer_eval(b.z == 3); // expected-warning{{TRUE}} } } // namespace arguments_with_constructors + +namespace inherited_constructor_crash { +class a { +public: + a(int); +}; +struct b : a { + using a::a; // Ihnerited ctor. +}; +void c() { + int d; + // This construct expr utilizes the inherited ctor. + // Note that d must be uninitialized to cause the crash. + (b(d)); // expected-warning{{1st function call argument is an uninitialized value}} +} +} // namespace inherited_constructor_crash Index: clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp =================================================================== --- clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -504,6 +504,27 @@ if (VisitedAsTopLevel.count(D)) return true; + // Skip analysis of inherited constructors as top-level functions because we + // cannot model the parameters. + // + // CXXInheritedCtorInitExpr doesn't take arguments and doesn't model + // parameter initialization because there is none: the arguments in the outer + // CXXConstructExpr directly initialize the parameters of the base class + // constructor, and no copies are made. (Making a copy of the parameter is + // incorrect, at least if it's done in an observable way.) The derived class + // constructor doesn't even exist in the formal model. + // E.g., in: + // + // struct X { X *p = this; ~X() {} }; + // struct A { A(X x) : b(x.p == &x) {} bool b; }; + // struct B : A { using A::A; }; + // B b = X{}; + // + // ... b.b is initialized to true. + if (const auto *CD = dyn_cast<CXXConstructorDecl>(D)) + if (CD->isInheritingConstructor()) + return true; + // We want to re-analyse the functions as top level in the following cases: // - The 'init' methods should be reanalyzed because // ObjCNonNilReturnValueChecker assumes that '[super init]' never returns
Index: clang/test/Analysis/cxx-inherited-ctor-init-expr.cpp =================================================================== --- clang/test/Analysis/cxx-inherited-ctor-init-expr.cpp +++ clang/test/Analysis/cxx-inherited-ctor-init-expr.cpp @@ -57,3 +57,19 @@ clang_analyzer_eval(b.z == 3); // expected-warning{{TRUE}} } } // namespace arguments_with_constructors + +namespace inherited_constructor_crash { +class a { +public: + a(int); +}; +struct b : a { + using a::a; // Ihnerited ctor. +}; +void c() { + int d; + // This construct expr utilizes the inherited ctor. + // Note that d must be uninitialized to cause the crash. + (b(d)); // expected-warning{{1st function call argument is an uninitialized value}} +} +} // namespace inherited_constructor_crash Index: clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp =================================================================== --- clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -504,6 +504,27 @@ if (VisitedAsTopLevel.count(D)) return true; + // Skip analysis of inherited constructors as top-level functions because we + // cannot model the parameters. + // + // CXXInheritedCtorInitExpr doesn't take arguments and doesn't model + // parameter initialization because there is none: the arguments in the outer + // CXXConstructExpr directly initialize the parameters of the base class + // constructor, and no copies are made. (Making a copy of the parameter is + // incorrect, at least if it's done in an observable way.) The derived class + // constructor doesn't even exist in the formal model. + // E.g., in: + // + // struct X { X *p = this; ~X() {} }; + // struct A { A(X x) : b(x.p == &x) {} bool b; }; + // struct B : A { using A::A; }; + // B b = X{}; + // + // ... b.b is initialized to true. + if (const auto *CD = dyn_cast<CXXConstructorDecl>(D)) + if (CD->isInheritingConstructor()) + return true; + // We want to re-analyse the functions as top level in the following cases: // - The 'init' methods should be reanalyzed because // ObjCNonNilReturnValueChecker assumes that '[super init]' never returns
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits