[clang-tools-extra] 7b7a6b6 - Revert "[clang-tidy] Add check bugprone-multiple-new-in-one-expression."
Balázs Kéri via cfe-commits
cfe-commits at lists.llvm.org
Tue May 2 02:23:51 PDT 2023
Author: Balázs Kéri
Date: 2023-05-02T11:23:31+02:00
New Revision: 7b7a6b641afdb9cae4ca1bb033ad65ee8177c9cb
URL: https://github.com/llvm/llvm-project/commit/7b7a6b641afdb9cae4ca1bb033ad65ee8177c9cb
DIFF: https://github.com/llvm/llvm-project/commit/7b7a6b641afdb9cae4ca1bb033ad65ee8177c9cb.diff
LOG: Revert "[clang-tidy] Add check bugprone-multiple-new-in-one-expression."
This reverts commit 1aa36da15369678d94add0f64809b11f95795efd.
Added:
Modified:
clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/docs/clang-tidy/checks/list.rst
Removed:
clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.cpp
clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.h
clang-tools-extra/docs/clang-tidy/checks/bugprone/multiple-new-in-one-expression.rst
clang-tools-extra/test/clang-tidy/checkers/bugprone/multiple-new-in-one-expression.cpp
################################################################################
diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
index 5e9c7d0add4f8..60666287cf307 100644
--- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
@@ -36,7 +36,6 @@
#include "MisplacedPointerArithmeticInAllocCheck.h"
#include "MisplacedWideningCastCheck.h"
#include "MoveForwardingReferenceCheck.h"
-#include "MultipleNewInOneExpressionCheck.h"
#include "MultipleStatementMacroCheck.h"
#include "NoEscapeCheck.h"
#include "NonZeroEnumToBoolConversionCheck.h"
@@ -134,8 +133,6 @@ class BugproneModule : public ClangTidyModule {
"bugprone-misplaced-widening-cast");
CheckFactories.registerCheck<MoveForwardingReferenceCheck>(
"bugprone-move-forwarding-reference");
- CheckFactories.registerCheck<MultipleNewInOneExpressionCheck>(
- "bugprone-multiple-new-in-one-expression");
CheckFactories.registerCheck<MultipleStatementMacroCheck>(
"bugprone-multiple-statement-macro");
CheckFactories.registerCheck<RedundantBranchConditionCheck>(
diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
index e70d1b426a1c6..5af5a59e5340f 100644
--- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
@@ -31,7 +31,6 @@ add_clang_library(clangTidyBugproneModule
MisplacedPointerArithmeticInAllocCheck.cpp
MisplacedWideningCastCheck.cpp
MoveForwardingReferenceCheck.cpp
- MultipleNewInOneExpressionCheck.cpp
MultipleStatementMacroCheck.cpp
NoEscapeCheck.cpp
NonZeroEnumToBoolConversionCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.cpp
deleted file mode 100644
index 47b9667859903..0000000000000
--- a/clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-//===--- MultipleNewInOneExpressionCheck.cpp - clang-tidy------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "MultipleNewInOneExpressionCheck.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
-#include "clang/Lex/Lexer.h"
-
-using namespace clang::ast_matchers;
-using namespace clang;
-
-namespace {
-
-// Determine if the result of an expression is "stored" in some way.
-// It is true if the value is stored into a variable or used as initialization
-// or passed to a function or constructor.
-// For this use case compound assignments are not counted as a "store" (the 'E'
-// expression should have pointer type).
-bool isExprValueStored(const Expr *E, ASTContext &C) {
- E = E->IgnoreParenCasts();
- // Get first non-paren, non-cast parent.
- ParentMapContext &PMap = C.getParentMapContext();
- DynTypedNodeList P = PMap.getParents(*E);
- if (P.size() != 1)
- return false;
- const Expr *ParentE;
- while ((ParentE = P[0].get<Expr>()) && ParentE->IgnoreParenCasts() == E) {
- P = PMap.getParents(P[0]);
- if (P.size() != 1)
- return false;
- }
-
- if (const auto *ParentVarD = P[0].get<VarDecl>())
- return ParentVarD->getInit()->IgnoreParenCasts() == E;
-
- if (!ParentE)
- return false;
-
- if (const auto *BinOp = dyn_cast<BinaryOperator>(ParentE))
- return BinOp->getOpcode() == BO_Assign &&
- BinOp->getRHS()->IgnoreParenCasts() == E;
-
- return isa<CallExpr, CXXConstructExpr>(ParentE);
-}
-
-} // namespace
-
-namespace clang {
-namespace tidy {
-namespace bugprone {
-
-AST_MATCHER_P(CXXTryStmt, hasHandlerFor,
- ast_matchers::internal::Matcher<QualType>, InnerMatcher) {
- for (unsigned NH = Node.getNumHandlers(), I = 0; I < NH; ++I) {
- const CXXCatchStmt *CatchS = Node.getHandler(I);
- // Check for generic catch handler (match anything).
- if (CatchS->getCaughtType().isNull())
- return true;
- ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder);
- if (InnerMatcher.matches(CatchS->getCaughtType(), Finder, &Result)) {
- *Builder = std::move(Result);
- return true;
- }
- }
- return false;
-}
-
-AST_MATCHER(CXXNewExpr, mayThrow) {
- FunctionDecl *OperatorNew = Node.getOperatorNew();
- if (!OperatorNew)
- return false;
- return !OperatorNew->getType()->castAs<FunctionProtoType>()->isNothrow();
-}
-
-void MultipleNewInOneExpressionCheck::registerMatchers(MatchFinder *Finder) {
- auto BadAllocType =
- recordType(hasDeclaration(cxxRecordDecl(hasName("::std::bad_alloc"))));
- auto ExceptionType =
- recordType(hasDeclaration(cxxRecordDecl(hasName("::std::exception"))));
- auto BadAllocReferenceType = referenceType(pointee(BadAllocType));
- auto ExceptionReferenceType = referenceType(pointee(ExceptionType));
-
- auto CatchBadAllocType =
- qualType(hasCanonicalType(anyOf(BadAllocType, BadAllocReferenceType,
- ExceptionType, ExceptionReferenceType)));
- auto BadAllocCatchingTryBlock = cxxTryStmt(hasHandlerFor(CatchBadAllocType));
-
- auto NewExprMayThrow = cxxNewExpr(mayThrow());
- auto HasNewExpr1 = expr(anyOf(NewExprMayThrow.bind("new1"),
- hasDescendant(NewExprMayThrow.bind("new1"))));
- auto HasNewExpr2 = expr(anyOf(NewExprMayThrow.bind("new2"),
- hasDescendant(NewExprMayThrow.bind("new2"))));
-
- Finder->addMatcher(
- callExpr(
- hasAnyArgument(
- expr(HasNewExpr1).bind("arg1")),
- hasAnyArgument(
- expr(HasNewExpr2, unless(equalsBoundNode("arg1"))).bind("arg2")),
- hasAncestor(BadAllocCatchingTryBlock)),
- this);
- Finder->addMatcher(
- cxxConstructExpr(
- hasAnyArgument(
- expr(HasNewExpr1).bind("arg1")),
- hasAnyArgument(
- expr(HasNewExpr2, unless(equalsBoundNode("arg1"))).bind("arg2")),
- unless(isListInitialization()),
- hasAncestor(BadAllocCatchingTryBlock)),
- this);
- Finder->addMatcher(binaryOperator(hasLHS(HasNewExpr1), hasRHS(HasNewExpr2),
- unless(hasAnyOperatorName("&&", "||", ",")),
- hasAncestor(BadAllocCatchingTryBlock)),
- this);
- Finder->addMatcher(
- cxxNewExpr(mayThrow(),
- hasDescendant(NewExprMayThrow.bind("new2_in_new1")),
- hasAncestor(BadAllocCatchingTryBlock))
- .bind("new1"),
- this);
-}
-
-void MultipleNewInOneExpressionCheck::check(
- const MatchFinder::MatchResult &Result) {
- const auto *NewExpr1 = Result.Nodes.getNodeAs<CXXNewExpr>("new1");
- const auto *NewExpr2 = Result.Nodes.getNodeAs<CXXNewExpr>("new2");
- const auto *NewExpr2InNewExpr1 =
- Result.Nodes.getNodeAs<CXXNewExpr>("new2_in_new1");
- if (!NewExpr2)
- NewExpr2 = NewExpr2InNewExpr1;
- assert(NewExpr1 && NewExpr2 && "Bound nodes not found.");
-
- // No warning if both allocations are not stored.
- // The value may be intentionally not stored (no deallocations needed or
- // self-destructing object).
- if (!isExprValueStored(NewExpr1, *Result.Context) &&
- !isExprValueStored(NewExpr2, *Result.Context))
- return;
-
- // In C++17 sequencing of a 'new' inside constructor arguments of another
- // 'new' is fixed. Still a leak can happen if the returned value from the
- // first 'new' is not saved (yet) and the second fails.
- if (getLangOpts().CPlusPlus17 && NewExpr2InNewExpr1)
- diag(NewExpr1->getBeginLoc(),
- "memory allocation may leak if an other allocation is sequenced after "
- "it and throws an exception")
- << NewExpr1->getSourceRange() << NewExpr2->getSourceRange();
- else
- diag(NewExpr1->getBeginLoc(),
- "memory allocation may leak if an other allocation is sequenced after "
- "it and throws an exception; order of these allocations is undefined")
- << NewExpr1->getSourceRange() << NewExpr2->getSourceRange();
-}
-
-} // namespace bugprone
-} // namespace tidy
-} // namespace clang
diff --git a/clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.h b/clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.h
deleted file mode 100644
index eba6c84d818ca..0000000000000
--- a/clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===--- MultipleNewInOneExpressionCheck.h - clang-tidy----------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_MULTIPLENEWINONEEXPRESSIONCHECK_H
-#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_MULTIPLENEWINONEEXPRESSIONCHECK_H
-
-#include "../ClangTidyCheck.h"
-
-namespace clang {
-namespace tidy {
-namespace bugprone {
-
-/// For the user-facing documentation see:
-/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone/multiple-new-in-one-expression.html
-class MultipleNewInOneExpressionCheck : public ClangTidyCheck {
-public:
- MultipleNewInOneExpressionCheck(StringRef Name, ClangTidyContext *Context)
- : ClangTidyCheck(Name, Context) {}
- bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
- return LangOpts.CPlusPlus;
- }
- void registerMatchers(ast_matchers::MatchFinder *Finder) override;
- void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
-};
-
-} // namespace bugprone
-} // namespace tidy
-} // namespace clang
-
-#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_MULTIPLENEWINONEEXPRESSIONCHECK_H
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index e4220b3134714..5695d59e89153 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -106,12 +106,6 @@ Improvements to clang-tidy
New checks
^^^^^^^^^^
-- New :doc:`bugprone-multiple-new-in-one-expression
- <clang-tidy/checks/bugprone/multiple-new-in-one-expression>` check.
-
- Finds multiple ``new`` operator calls in a single expression, where the allocated
- memory by the first ``new`` may leak if the second allocation fails and throws exception.
-
- New :doc:`bugprone-non-zero-enum-to-bool-conversion
<clang-tidy/checks/bugprone/non-zero-enum-to-bool-conversion>` check.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/multiple-new-in-one-expression.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/multiple-new-in-one-expression.rst
deleted file mode 100644
index b9b8984ef6584..0000000000000
--- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/multiple-new-in-one-expression.rst
+++ /dev/null
@@ -1,99 +0,0 @@
-.. title:: clang-tidy - bugprone-multiple-new-in-one-expression
-
-bugprone-multiple-new-in-one-expression
-=======================================
-
-Finds multiple ``new`` operator calls in a single expression, where the
-allocated memory by the first ``new`` may leak if the second allocation fails
-and throws exception.
-
-C++ does often not specify the exact order of evaluation of the operands of an
-operator or arguments of a function. Therefore if a first allocation succeeds
-and a second fails, in an exception handler it is not possible to tell which
-allocation has failed and free the memory. Even if the order is fixed the result
-of a first ``new`` may be stored in a temporary location that is not reachable
-at the time when a second allocation fails. It is best to avoid any expression
-that contains more than one ``operator new`` call, if exception handling is
-used to check for allocation errors.
-
-Different rules apply for are the short-circuit operators ``||`` and ``&&`` and
-the ``,`` operator, where evaluation of one side must be completed before the
-other starts. Expressions of a list-initialization (initialization or
-construction using ``{`` and ``}`` characters) are evaluated in fixed order.
-Similarly, condition of a ``?`` operator is evaluated before the branches are
-evaluated.
-
-The check reports warning if two ``new`` calls appear in one expression at
-
diff erent sides of an operator, or if ``new`` calls appear in
diff erent
-arguments of a function call (that can be an object construction with ``()``
-syntax). These ``new`` calls can be nested at any level.
-For any warning to be emitted the ``new`` calls should be in a code block where
-exception handling is used with catch for ``std::bad_alloc`` or
-``std::exception``. At ``||``, ``&&``, ``,``, ``?`` (condition and one branch)
-operators no warning is emitted. No warning is emitted if both of the memory
-allocations are not assigned to a variable or not passed directly to a function.
-The reason is that in this case the memory may be intentionally not freed or the
-allocated objects can be self-destructing objects.
-
-Examples:
-
-.. code-block:: c++
-
- struct A {
- int Var;
- };
- struct B {
- B();
- B(A *);
- int Var;
- };
- struct C {
- int *X1;
- int *X2;
- };
-
- void f(A *, B *);
- int f1(A *);
- int f1(B *);
- bool f2(A *);
-
- void foo() {
- A *PtrA;
- B *PtrB;
- try {
- // Allocation of 'B'/'A' may fail after memory for 'A'/'B' was allocated.
- f(new A, new B); // warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception; order of these allocations is undefined
-
- // List (aggregate) initialization is used.
- C C1{new int, new int}; // no warning
-
- // Allocation of 'B'/'A' may fail after memory for 'A'/'B' was allocated but not yet passed to function 'f1'.
- int X = f1(new A) + f1(new B); // warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception; order of these allocations is undefined
-
- // Allocation of 'B' may fail after memory for 'A' was allocated.
- // From C++17 on memory for 'B' is allocated first but still may leak if allocation of 'A' fails.
- PtrB = new B(new A); // warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception
-
- // 'new A' and 'new B' may be performed in any order.
- // 'new B'/'new A' may fail after memory for 'A'/'B' was allocated but not assigned to 'PtrA'/'PtrB'.
- (PtrA = new A)->Var = (PtrB = new B)->Var; // warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception; order of these allocations is undefined
-
- // Evaluation of 'f2(new A)' must be finished before 'f1(new B)' starts.
- // If 'new B' fails the allocated memory for 'A' is supposedly handled correctly because function 'f2' could take the ownership.
- bool Z = f2(new A) || f1(new B); // no warning
-
- X = (f2(new A) ? f1(new A) : f1(new B)); // no warning
-
- // No warning if the result of both allocations is not passed to a function
- // or stored in a variable.
- (new A)->Var = (new B)->Var; // no warning
-
- // No warning if at least one non-throwing allocation is used.
- f(new(std::nothrow) A, new B); // no warning
- } catch(std::bad_alloc) {
- }
-
- // No warning if the allocation is outside a try block (or no catch handler exists for std::bad_alloc).
- // (The fact if exceptions can escape from 'foo' is not taken into account.)
- f(new A, new B); // no warning
- }
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index 6a58bb932e9ec..3ddd257e70de6 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -102,7 +102,6 @@ Clang-Tidy Checks
`bugprone-misplaced-pointer-arithmetic-in-alloc <bugprone/misplaced-pointer-arithmetic-in-alloc.html>`_, "Yes"
`bugprone-misplaced-widening-cast <bugprone/misplaced-widening-cast.html>`_,
`bugprone-move-forwarding-reference <bugprone/move-forwarding-reference.html>`_, "Yes"
- `bugprone-multiple-new-in-one-expression <bugprone/multiple-new-in-one-expression.html>`_,
`bugprone-multiple-statement-macro <bugprone/multiple-statement-macro.html>`_,
`bugprone-no-escape <bugprone/no-escape.html>`_,
`bugprone-non-zero-enum-to-bool-conversion <bugprone/non-zero-enum-to-bool-conversion.html>`_,
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/multiple-new-in-one-expression.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/multiple-new-in-one-expression.cpp
deleted file mode 100644
index 8ac77af328f21..0000000000000
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/multiple-new-in-one-expression.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-// RUN: %check_clang_tidy -std=c++11 -check-suffixes=ALL,CPP11 %s bugprone-multiple-new-in-one-expression %t
-// RUN: %check_clang_tidy -std=c++17 -check-suffixes=ALL,CPP17 %s bugprone-multiple-new-in-one-expression %t
-
-namespace std {
-typedef __typeof__(sizeof(0)) size_t;
-enum class align_val_t : std::size_t {};
-class exception {};
-class bad_alloc : public exception {};
-struct nothrow_t {};
-extern const nothrow_t nothrow;
-} // namespace std
-
-void *operator new(std::size_t, const std::nothrow_t &) noexcept;
-void *operator new(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept;
-void *operator new(std::size_t, void *) noexcept;
-void *operator new(std::size_t, char);
-
-struct B;
-
-struct A { int VarI; int *PtrI; B *PtrB; };
-
-struct B { int VarI; };
-
-struct G {
- G(A*, B*) {}
- int operator+=(A *) { return 3; };
-};
-
-struct H {
- int *a;
- int *b;
-};
-
-int f(int);
-int f(A*);
-int f(A*, B*);
-int f(int, B*);
-int f(G, G);
-int f(B*);
-int f(const H &);
-void f1(void *, void *);
-A *g(A *);
-
-G operator+(const G&, const G&);
-
-void test_function_parameter(A *XA, B *XB) {
- (void)f(new A, new B);
- try {
- (void)f(new A, new B);
- }
- catch (A) {};
- try {
- (void)f(new A, new B);
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception; order of these allocations is undefined [
- (void)f(f(new A, new B));
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- int X = f(new A, new B);
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- X = f(new A, new B);
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:11: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- X = 1 + f(new A, new B);
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
-
- (void)f(g(new A), new B);
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
-
- (void)f(1 + f(new A), new B);
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:19: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- (void)f(XA = new A, new B);
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:18: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- (void)f(1 + f(new A), XB = new B);
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:19: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- }
- catch (std::exception) {}
-}
-
-void test_operator(G *G1) {
- (void)(f(new A) + f(new B));
- try {
- (void)(f(new A) + f(new B));
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:14: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- (void)f(f(new A) + f(new B));
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- int X = f(new A) + f(new B);
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- X = f(new A) + f(new B);
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:11: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- X = 1 + f(new A) + 1 + f(new B);
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
-
- (void)(f(g(new A)) + f(new B));
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:16: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
-
- (void)(f(1 + f(new A)) + f(new B));
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:20: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- (void)(f(1 + f(new A)) + f(1 + f(new B)));
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:20: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
-
- (void)((new A)->VarI + (new A)->VarI);
-
- (void)(f(new A) + ((*G1) += new A));
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:14: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- }
- catch (std::bad_alloc) {}
-}
-
-void test_construct() {
- (void)(G(new A, new B));
- try {
- (void)(G(new A, new B));
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:14: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- (void)(G(new A, nullptr) + G(nullptr, new B));
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:14: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- f(G(new A, nullptr), G(new A, nullptr));
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:9: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
-
- (void)new G(new A, nullptr);
- // CHECK-MESSAGES-CPP11: :[[@LINE-1]]:11: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- // CHECK-MESSAGES-CPP17: :[[@LINE-2]]:11: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception [
- (void)new G(nullptr, (new A)->PtrB);
- G *Z = new G(new A, nullptr);
- // CHECK-MESSAGES-CPP11: :[[@LINE-1]]:12: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- // CHECK-MESSAGES-CPP17: :[[@LINE-2]]:12: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception [
- Z = new G(g(new A), nullptr);
- // CHECK-MESSAGES-CPP11: :[[@LINE-1]]:9: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- // CHECK-MESSAGES-CPP17: :[[@LINE-2]]:9: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception [
- G *Z1, *Z2 = new G(nullptr, (new A)->PtrB), *Z3;
- // CHECK-MESSAGES-CPP11: :[[@LINE-1]]:18: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- // CHECK-MESSAGES-CPP17: :[[@LINE-2]]:18: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception [
- }
- catch (const std::bad_alloc &) {}
-}
-
-void test_new_assign() {
- A *X, *Y;
- (X = new A)->VarI = (Y = new A)->VarI;
- try {
- (X = new A)->VarI = (Y = new A)->VarI;
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- (new A)->VarI = (Y = new A)->VarI;
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:6: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- (X = new A)->VarI = (new A)->VarI;
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- (new A)->VarI = (new A)->VarI;
- (new A)->PtrI = new int;
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:6: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- (X = new A)->VarI += (new A)->VarI;
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- }
- catch (...) {}
-}
-
-void test_operator_fixed_order(unsigned int L) {
- (void)(f((f(new A) || f(0)) + f(new B[L])));
- try {
- (void)(f(new A) || f(new B));
- (void)(f(new A) && f(new B));
- (void)(f(new A) || f(new B) || f(new A));
-
- (void)(f(new A), f(new B));
-
- int Y = f(0, new B) ? f(new A) : f(new B);
- Y = f(new A) ? 1 : f(new B);
- Y = f(new A) ? f(new B) : 1;
-
- G g{new A, new B};
- H h{new int, new int};
- f({new int, new int});
- (void)f({new A, new B}, {nullptr, nullptr});
- (void)f({new A, new B}, {new A, nullptr});
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:14: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
-
- (void)(f((f(new A) || f(0)) + f(new B[L])));
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:17: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- }
- catch (std::bad_alloc) {}
-}
-
-void test_cast() {
- try {
- f1(static_cast<void *>(new A), new B);
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:28: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- }
- catch (std::bad_alloc &) {}
-}
-
-void test_nothrow(void *P) {
- try {
- (void)f(new(std::nothrow) A, new B);
- (void)f(new A, new(std::nothrow) B);
- (void)f(new(static_cast<std::align_val_t>(8), std::nothrow) A, new B);
- (void)f(new(P) A, new B);
- (void)f(new('a') A, new B);
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
- }
- catch (std::exception) {}
-}
More information about the cfe-commits
mailing list