[clang-tools-extra] [clang-tidy] Add bugprone-container-bounds-check-overflow check (PR #206349)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Jun 28 10:10:29 PDT 2026
https://github.com/Harald-R created https://github.com/llvm/llvm-project/pull/206349
While working on a parser, I noticed that the `offset + size < buffer.size()` pattern was often used to check whether some data was within the boundary of the buffer. If the addition overflows, the check could misbehave. Doing a small experiment with an AI auto-complete in a fresh project, I also noticed that this pattern has been suggested for checking the boundary, which could lead to it appearing more often in various projects.
This PR introduces a clang-tidy check for the following cases, with the associated fix-it suggestions:
```
(a + b < size()) -> (a < size() && b < size() - a)
(a + b <= size()) -> (a <= size() && b <= size() - a)
(a + b > size()) -> (a > size() || b > size() - a)
(a + b >= size()) -> (a >= size() || b >= size() - a)
(size() < a + b) -> (size() < a || size() - a < b)
(size() <= a + b) -> (size() <= a || size() - a <= b)
(size() > a + b) -> (size() > a && size() - a > b)
(size() >= a + b) -> (size() >= a && size() - a >= b)
```
`size()` represents a member method of an object. Since this `size()` method check might be too generic, I also introduced an option `IgnoredContainers`, if someone might want to bypass this check for particular cases.
I would note that the check is restricted to unsigned addition only, where the type size of the addition is the same as the type size of the method call's result. If the addition's result has a smaller type, then there is no overflow possible (since it would get promoted to the larger type). If the addition's result has a larger type, then it looks like the method call's result would need to be promoted, which indicates a bigger problem to me (since the result of `size()` would have a smaller number of values possible than the addition result); not sure whether this scenario should be covered by this check.
Signed additions are ignored by the check, as overflows in these cases represent undefined behavior (see [here](https://en.cppreference.com/c/language/operator_arithmetic), section `Overflows`). The check could also be extended to warn the user about possible overflows for signed additions, if desired.
If this check is accepted, it could also be extended in the future to potentially catch other overflow / underflow scenarios (e.g. `size() - 1` could underflow if `size() == 0`).
To be noted that I have used AI suggestions in the implementation of this check. I have checked, refined, and improved the implementation multiple times and tried to cover many scenarios with unit tests, to avoid issues. I am however new to the AST matcher API and clang-tidy in general, so I would appreciate a thorough review. Thanks!
>From 75e1073aa1eb1ec766800560619dde0c57611fbf Mon Sep 17 00:00:00 2001
From: Harald-R <rotuna.razvan at gmail.com>
Date: Wed, 24 Jun 2026 13:56:25 +0300
Subject: [PATCH] Add bugprone-container-bounds-check-overflow check
---
.../bugprone/BugproneTidyModule.cpp | 3 +
.../clang-tidy/bugprone/CMakeLists.txt | 1 +
.../ContainerBoundsCheckOverflowCheck.cpp | 147 ++++++++++++++++++
.../ContainerBoundsCheckOverflowCheck.h | 37 +++++
clang-tools-extra/docs/ReleaseNotes.rst | 6 +
.../container-bounds-check-overflow.rst | 33 ++++
.../docs/clang-tidy/checks/list.rst | 1 +
.../container-bounds-check-overflow.cpp | 93 +++++++++++
8 files changed, 321 insertions(+)
create mode 100644 clang-tools-extra/clang-tidy/bugprone/ContainerBoundsCheckOverflowCheck.cpp
create mode 100644 clang-tools-extra/clang-tidy/bugprone/ContainerBoundsCheckOverflowCheck.h
create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/container-bounds-check-overflow.rst
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/container-bounds-check-overflow.cpp
diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
index 3aa39d10ceb5d..485749a13b47f 100644
--- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
@@ -21,6 +21,7 @@
#include "ChainedComparisonCheck.h"
#include "CommandProcessorCheck.h"
#include "ComparePointerToMemberVirtualFunctionCheck.h"
+#include "ContainerBoundsCheckOverflowCheck.h"
#include "CopyConstructorInitCheck.h"
#include "CopyConstructorMutatesArgumentCheck.h"
#include "CrtpConstructorAccessibilityCheck.h"
@@ -150,6 +151,8 @@ class BugproneModule : public ClangTidyModule {
"bugprone-command-processor");
CheckFactories.registerCheck<ComparePointerToMemberVirtualFunctionCheck>(
"bugprone-compare-pointer-to-member-virtual-function");
+ CheckFactories.registerCheck<ContainerBoundsCheckOverflowCheck>(
+ "bugprone-container-bounds-check-overflow");
CheckFactories.registerCheck<CopyConstructorInitCheck>(
"bugprone-copy-constructor-init");
CheckFactories.registerCheck<CopyConstructorMutatesArgumentCheck>(
diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
index 43e85b1407f21..8db97682e1505 100644
--- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
@@ -18,6 +18,7 @@ add_clang_library(clangTidyBugproneModule STATIC
ChainedComparisonCheck.cpp
CommandProcessorCheck.cpp
ComparePointerToMemberVirtualFunctionCheck.cpp
+ ContainerBoundsCheckOverflowCheck.cpp
CopyConstructorInitCheck.cpp
CopyConstructorMutatesArgumentCheck.cpp
CrtpConstructorAccessibilityCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/bugprone/ContainerBoundsCheckOverflowCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ContainerBoundsCheckOverflowCheck.cpp
new file mode 100644
index 0000000000000..6f6fb3210b6eb
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/bugprone/ContainerBoundsCheckOverflowCheck.cpp
@@ -0,0 +1,147 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "ContainerBoundsCheckOverflowCheck.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::bugprone {
+
+ContainerBoundsCheckOverflowCheck::ContainerBoundsCheckOverflowCheck(
+ StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ IgnoredContainers(utils::options::parseStringList(
+ Options.get("IgnoredContainers", ""))) {}
+
+void ContainerBoundsCheckOverflowCheck::storeOptions(
+ ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "IgnoredContainers",
+ utils::options::serializeStringList(IgnoredContainers));
+}
+
+void ContainerBoundsCheckOverflowCheck::registerMatchers(MatchFinder *Finder) {
+ auto RecordMatcher = cxxRecordDecl();
+ if (!IgnoredContainers.empty())
+ RecordMatcher = cxxRecordDecl(unless(hasAnyName(IgnoredContainers)));
+ auto SizeMethodCall =
+ cxxMemberCallExpr(
+ callee(cxxMethodDecl(hasName("size"))),
+ on(hasType(hasCanonicalType(hasDeclaration(RecordMatcher)))))
+ .bind("size_method_call");
+
+ // Operands must be unsigned integers, as overflow in signed integer addition
+ // is undefined behavior
+ auto Addition =
+ binaryOperator(hasOperatorName("+"), hasLHS(hasType(isUnsignedInteger())),
+ hasRHS(hasType(isUnsignedInteger())))
+ .bind("addition");
+ auto Comparison = hasAnyOperatorName("<", "<=", ">", ">=");
+ // Match cases: [Addition] </<=/>/>= [Size]
+ Finder->addMatcher(
+ binaryOperator(Comparison, hasLHS(Addition), hasRHS(SizeMethodCall))
+ .bind("comparison_addition_lhs"),
+ this);
+ // Match cases: [Size] </<=/>/>= [Addition]
+ Finder->addMatcher(
+ binaryOperator(Comparison, hasRHS(Addition), hasLHS(SizeMethodCall))
+ .bind("comparison_addition_rhs"),
+ this);
+}
+
+void ContainerBoundsCheckOverflowCheck::check(
+ const MatchFinder::MatchResult &Result) {
+ const auto *Addition = Result.Nodes.getNodeAs<BinaryOperator>("addition");
+ const auto *SizeMethodCall =
+ Result.Nodes.getNodeAs<CXXMemberCallExpr>("size_method_call");
+ if (!Addition || !SizeMethodCall)
+ return;
+ const auto *ComparisonAddLhs =
+ Result.Nodes.getNodeAs<BinaryOperator>("comparison_addition_lhs");
+ const auto *ComparisonAddRhs =
+ Result.Nodes.getNodeAs<BinaryOperator>("comparison_addition_rhs");
+ const auto NoComparison = !ComparisonAddLhs && !ComparisonAddRhs;
+ if (NoComparison)
+ return;
+
+ auto AdditionType = Addition->getType().getCanonicalType();
+ auto SizeMethodCallType = SizeMethodCall->getType().getCanonicalType();
+
+ auto &Context = *Result.Context;
+ // If the type of the addition is smaller than the type of the size() call,
+ // then the addition will be promoted to the size() type before the
+ // comparison, so there is no risk of overflow. The case where the type of the
+ // addition is larger than the type of the size() call is not handled by this
+ // check
+ if (Context.getTypeSize(AdditionType) !=
+ Context.getTypeSize(SizeMethodCallType))
+ return;
+
+ auto GetText = [&](SourceRange Range) -> StringRef {
+ return Lexer::getSourceText(CharSourceRange::getTokenRange(Range),
+ *Result.SourceManager, getLangOpts());
+ };
+ auto StrA = GetText(Addition->getLHS()->getSourceRange());
+ auto StrB = GetText(Addition->getRHS()->getSourceRange());
+ auto StrSize = GetText(SizeMethodCall->getSourceRange());
+
+ const auto *Comparison =
+ ComparisonAddLhs ? ComparisonAddLhs : ComparisonAddRhs;
+ // Introduce parentheses around the addition to avoid changing the order of
+ // operations when replacing the comparison with a logical AND/OR expression.
+ // The parentheses are only added if the original expression is not already
+ // wrapped in parentheses
+ bool NeedsParens = true;
+ const auto &Parents = Context.getParents(*Comparison);
+ if (!Parents.empty()) {
+ if (Parents[0].get<ParenExpr>() || Parents[0].get<IfStmt>() ||
+ Parents[0].get<WhileStmt>())
+ NeedsParens = false;
+ }
+
+ const auto ComparisonType = Comparison->getOpcodeStr();
+ std::string Replacement;
+ if (ComparisonAddLhs) {
+ // Matches cases where the addition is on the left side of the comparison
+ // (a + b < size()) -> (a < size() && b < size() - a)
+ // (a + b <= size()) -> (a <= size() && b <= size() - a)
+ // (a + b > size()) -> (a > size() || b > size() - a)
+ // (a + b >= size()) -> (a >= size() || b >= size() - a)
+ const auto *Expr =
+ (ComparisonType == "<" || ComparisonType == "<=") ? " && " : " || ";
+ Replacement =
+ ((NeedsParens ? "(" : "") + StrA + " " + ComparisonType.str() + " " +
+ StrSize + Expr + StrB + " " + ComparisonType.str() + " " + StrSize +
+ " - " + StrA + (NeedsParens ? ")" : ""))
+ .str();
+ } else {
+ // Matches cases where the addition is on the right side of the comparison,
+ // (size() < a + b) -> (size() < a || size() - a < b)
+ // (size() <= a + b) -> (size() <= a || size() - a <= b)
+ // (size() > a + b) -> (size() > a && size() - a > b)
+ // (size() >= a + b) -> (size() >= a && size() - a >= b)
+ const auto *Expr =
+ (ComparisonType == "<" || ComparisonType == "<=") ? " || " : " && ";
+ Replacement =
+ ((NeedsParens ? "(" : "") + StrSize + " " + ComparisonType.str() + " " +
+ StrA + Expr + StrSize + " - " + StrA + " " + ComparisonType.str() +
+ " " + StrB + (NeedsParens ? ")" : ""))
+ .str();
+ }
+
+ auto Diag = diag(Comparison->getOperatorLoc(),
+ "potential overflow in unsigned integer addition "
+ "before comparison");
+
+ Diag << FixItHint::CreateReplacement(Comparison->getSourceRange(),
+ Replacement);
+}
+
+} // namespace clang::tidy::bugprone
diff --git a/clang-tools-extra/clang-tidy/bugprone/ContainerBoundsCheckOverflowCheck.h b/clang-tools-extra/clang-tidy/bugprone/ContainerBoundsCheckOverflowCheck.h
new file mode 100644
index 0000000000000..47d454ae7afff
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/bugprone/ContainerBoundsCheckOverflowCheck.h
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_CONTAINERBOUNDSCHECKOVERFLOWCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_CONTAINERBOUNDSCHECKOVERFLOWCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::bugprone {
+
+/// Check for potential overflow in unsigned integer addition before comparison with a container's size() method.
+/// For example a + b > v.size() can overflow if a and b are large enough, leading to incorrect behavior
+///
+/// For the user-facing documentation see:
+/// https://clang.llvm.org/extra/clang-tidy/checks/bugprone/container-bounds-check-overflow.html
+class ContainerBoundsCheckOverflowCheck : public ClangTidyCheck {
+public:
+ ContainerBoundsCheckOverflowCheck(StringRef Name, ClangTidyContext *Context);
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+ bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+ return LangOpts.CPlusPlus;
+ }
+
+private:
+ const std::vector<StringRef> IgnoredContainers;
+};
+
+} // namespace clang::tidy::bugprone
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_CONTAINERBOUNDSCHECKOVERFLOWCHECK_H
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 2a980cc089a65..f1f8aae26b031 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -221,6 +221,12 @@ New checks
Finds assignments within selection statements.
+- New :doc:`bugprone-container-bounds-check-overflow
+ <clang-tidy/checks/bugprone/container-bounds-check-overflow>` check.
+
+ Finds potential overflow in unsigned integer addition before comparison
+ with a container's ``size()`` method.
+
- New :doc:`bugprone-missing-end-comparison
<clang-tidy/checks/bugprone/missing-end-comparison>` check.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/container-bounds-check-overflow.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/container-bounds-check-overflow.rst
new file mode 100644
index 0000000000000..887a1784800b1
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/container-bounds-check-overflow.rst
@@ -0,0 +1,33 @@
+.. title:: clang-tidy - bugprone-container-bounds-check-overflow
+
+bugprone-container-bounds-check-overflow
+========================================
+
+This check finds potential overflow in unsigned integer addition before comparison with a container's
+``size()`` method. It flags all of the following combinations:
+- ``a + b < v.size()``
+- ``a + b <= v.size()``
+- ``a + b > v.size()``
+- ``a + b >= v.size()``
+- ``v.size() < a + b``
+- ``v.size() <= a + b``
+- ``v.size() > a + b``
+- ``v.size() >= a + b``
+
+The addition ``a + b`` can overflow if ``a`` and ``b`` are large enough, leading to incorrect behavior.
+For example, if ``a`` is ``UINT_MAX`` and ``b`` is ``1``, then ``a + b`` will wrap around to ``0``,
+and the comparison can be true, even if the container is empty.
+
+The comparison is flagged only if size of the unsigned integers being added is the same
+as the size of the container's ``size()`` return type. Smaller types are promoted to the size
+of the container's ``size()`` return type before the addition, so they are safe from overflow.
+
+Options
+-------
+
+.. option:: IgnoredContainers
+
+ When set, the check will ignore the specified containers. The value is a
+ comma-separated list of fully qualified container names. For example, to ignore
+ ``std::array`` and ``CustomClass``, set the option to ``::std::array,::CustomClass``.
+ The default is empty, meaning no containers are ignored.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index 2a44dc78fbc89..2aac5b79b2b8d 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -90,6 +90,7 @@ Clang-Tidy Checks
:doc:`bugprone-chained-comparison <bugprone/chained-comparison>`,
:doc:`bugprone-command-processor <bugprone/command-processor>`,
:doc:`bugprone-compare-pointer-to-member-virtual-function <bugprone/compare-pointer-to-member-virtual-function>`,
+ :doc:`bugprone-container-bounds-check-overflow <bugprone/container-bounds-check-overflow>`, "Yes"
:doc:`bugprone-copy-constructor-init <bugprone/copy-constructor-init>`, "Yes"
:doc:`bugprone-copy-constructor-mutates-argument <bugprone/copy-constructor-mutates-argument>`,
:doc:`bugprone-crtp-constructor-accessibility <bugprone/crtp-constructor-accessibility>`, "Yes"
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/container-bounds-check-overflow.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/container-bounds-check-overflow.cpp
new file mode 100644
index 0000000000000..704f861e189a6
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/container-bounds-check-overflow.cpp
@@ -0,0 +1,93 @@
+// RUN: %check_clang_tidy %s bugprone-container-bounds-check-overflow %t -- -config='{CheckOptions: { bugprone-container-bounds-check-overflow.IgnoredContainers: "::CustomClass"}}'
+
+#include <cstddef>
+#include <vector>
+#include <string>
+
+namespace {
+
+class CustomClass {
+public:
+ size_t size() const {
+ return 0;
+ }
+};
+
+}
+
+void positives(size_t a, size_t b, const std::vector<int> &v) {
+ if (a + b > v.size()) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: potential overflow in unsigned integer addition before comparison [bugprone-container-bounds-check-overflow]
+ // CHECK-FIXES: if (a > v.size() || b > v.size() - a) {}
+ if (a + b >= v.size()) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: potential overflow in unsigned integer addition before comparison [bugprone-container-bounds-check-overflow]
+ // CHECK-FIXES: if (a >= v.size() || b >= v.size() - a) {}
+ if (a + b < v.size()) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: potential overflow in unsigned integer addition before comparison [bugprone-container-bounds-check-overflow]
+ // CHECK-FIXES: if (a < v.size() && b < v.size() - a) {}
+ if (a + b <= v.size()) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: potential overflow in unsigned integer addition before comparison [bugprone-container-bounds-check-overflow]
+ // CHECK-FIXES: if (a <= v.size() && b <= v.size() - a) {}
+ if (v.size() < a + b) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: potential overflow in unsigned integer addition before comparison [bugprone-container-bounds-check-overflow]
+ // CHECK-FIXES: if (v.size() < a || v.size() - a < b) {}
+ if (v.size() <= a + b) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: potential overflow in unsigned integer addition before comparison [bugprone-container-bounds-check-overflow]
+ // CHECK-FIXES: if (v.size() <= a || v.size() - a <= b) {}
+ if (v.size() > a + b) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: potential overflow in unsigned integer addition before comparison [bugprone-container-bounds-check-overflow]
+ // CHECK-FIXES: if (v.size() > a && v.size() - a > b) {}
+ if (v.size() >= a + b) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: potential overflow in unsigned integer addition before comparison [bugprone-container-bounds-check-overflow]
+ // CHECK-FIXES: if (v.size() >= a && v.size() - a >= b) {}
+
+ // Introduces parantheses to avoid changing the order of operations
+ if (true && a + b > v.size()) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: potential overflow in unsigned integer addition before comparison [bugprone-container-bounds-check-overflow]
+ // CHECK-FIXES: if (true && (a > v.size() || b > v.size() - a)) {}
+ if (a + b > v.size() && true) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: potential overflow in unsigned integer addition before comparison [bugprone-container-bounds-check-overflow]
+ // CHECK-FIXES: if ((a > v.size() || b > v.size() - a) && true) {}
+
+ // Avoid introducing parantheses if the comparison is already wrapped in one
+ while(a + b > v.size()) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: potential overflow in unsigned integer addition before comparison [bugprone-container-bounds-check-overflow]
+ // CHECK-FIXES: while(a > v.size() || b > v.size() - a) {}
+ auto result = a + b > v.size();
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: potential overflow in unsigned integer addition before comparison [bugprone-container-bounds-check-overflow]
+ // CHECK-FIXES: auto result = (a > v.size() || b > v.size() - a);
+ result = (a + b > v.size());
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: potential overflow in unsigned integer addition before comparison [bugprone-container-bounds-check-overflow]
+ // CHECK-FIXES: result = (a > v.size() || b > v.size() - a);
+ (void)result;
+
+ // Confirm the fix works well with different named variables
+ size_t x = 42;
+ size_t y = 123;
+ std::string s = "Hello, world!";
+ if (x + y > s.size()) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: potential overflow in unsigned integer addition before comparison [bugprone-container-bounds-check-overflow]
+ // CHECK-FIXES: if (x > s.size() || y > s.size() - x) {}
+}
+
+void negatives(size_t a, size_t b, const std::vector<int> &v) {
+ // Cannot overflow because of the comparison order
+ if (a > v.size() || b > v.size() - a) {}
+ if (b > v.size() || a > v.size() - b) {}
+
+ // Cannot overflow because the operands of '+' are smaller than the result of size(); the addition result gets promoted to size_t before the comparison
+ unsigned short x = 42;
+ unsigned short y = 123;
+ if (x + y > v.size()) {}
+
+ // Intentionally ignored class
+ CustomClass c;
+ if (a + b > c.size()) {}
+ if (a + b >= c.size()) {}
+ if (a + b < c.size()) {}
+ if (a + b <= c.size()) {}
+ if (c.size() < a + b) {}
+ if (c.size() <= a + b) {}
+ if (c.size() > a + b) {}
+ if (c.size() >= a + b) {}
+}
More information about the cfe-commits
mailing list