llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-static-analyzer-1 Author: Ziqing Luo (ziqingluo-90) <details> <summary>Changes</summary> Previously, Static Analyzer initializes empty type fields with zeroes. This can cause problems when those fields have no unique addresses. For example, https://github.com/llvm/llvm-project/issues/137252. rdar://146753089 --- Full diff: https://github.com/llvm/llvm-project/pull/138594.diff 2 Files Affected: - (modified) clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (+7-1) - (added) clang/test/Analysis/issue-137252.cpp (+45) ``````````diff diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index 92ce3fa2225c8..219d7b4d2278c 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "clang/AST/ASTContext.h" #include "clang/AST/AttrIterator.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/ParentMap.h" @@ -700,6 +701,7 @@ void ExprEngine::handleConstructor(const Expr *E, if (CE) { // FIXME: Is it possible and/or useful to do this before PreStmt? StmtNodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx); + ASTContext &Ctx = LCtx->getAnalysisDeclContext()->getASTContext(); for (ExplodedNode *N : DstPreVisit) { ProgramStateRef State = N->getState(); if (CE->requiresZeroInitialization()) { @@ -715,7 +717,11 @@ void ExprEngine::handleConstructor(const Expr *E, // actually make things worse. Placement new makes this tricky as well, // since it's then possible to be initializing one part of a multi- // dimensional array. - State = State->bindDefaultZero(Target, LCtx); + const CXXRecordDecl *TargetHeldRecord = + Target.getType(Ctx)->getPointeeCXXRecordDecl(); + + if (!TargetHeldRecord || !TargetHeldRecord->isEmpty()) + State = State->bindDefaultZero(Target, LCtx); } Bldr.generateNode(CE, N, State, /*tag=*/nullptr, diff --git a/clang/test/Analysis/issue-137252.cpp b/clang/test/Analysis/issue-137252.cpp new file mode 100644 index 0000000000000..8064e3f54d9fd --- /dev/null +++ b/clang/test/Analysis/issue-137252.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus -verify %s -DEMPTY_CLASS + +// expected-no-diagnostics + +// This test reproduces the issue that previously the static analyzer +// initialized an [[__no_unique_address__]] empty field to zero, +// over-writing a non-empty field with the same offset. + +namespace std { +#ifdef EMPTY_CLASS + + template <typename T> + class default_delete { + T dump(); + static T x; + }; + template <class _Tp, class _Dp = default_delete<_Tp> > +#else + + struct default_delete {}; + template <class _Tp, class _Dp = default_delete > +#endif + class unique_ptr { + [[__no_unique_address__]] _Tp * __ptr_; + [[__no_unique_address__]] _Dp __deleter_; + + public: + explicit unique_ptr(_Tp* __p) noexcept + : __ptr_(__p), + __deleter_() {} + + ~unique_ptr() { + delete __ptr_; + } + }; +} + +struct X {}; + +int main() +{ + std::unique_ptr<X> a(new X()); // previously leak falsely reported + return 0; +} `````````` </details> https://github.com/llvm/llvm-project/pull/138594 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits