Skip to content

Commit

Permalink
[AutoBump] Merge with ea050ab (Oct 30)
Browse files Browse the repository at this point in the history
  • Loading branch information
jorickert committed Jan 31, 2025
2 parents 6de5a66 + ea050ab commit 1353852
Show file tree
Hide file tree
Showing 1,613 changed files with 145,974 additions and 18,785 deletions.
3 changes: 3 additions & 0 deletions bolt/lib/Core/BinaryFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2577,6 +2577,7 @@ struct CFISnapshot {
case MCCFIInstruction::OpAdjustCfaOffset:
case MCCFIInstruction::OpWindowSave:
case MCCFIInstruction::OpNegateRAState:
case MCCFIInstruction::OpNegateRAStateWithPC:
case MCCFIInstruction::OpLLVMDefAspaceCfa:
case MCCFIInstruction::OpLabel:
llvm_unreachable("unsupported CFI opcode");
Expand Down Expand Up @@ -2715,6 +2716,7 @@ struct CFISnapshotDiff : public CFISnapshot {
case MCCFIInstruction::OpAdjustCfaOffset:
case MCCFIInstruction::OpWindowSave:
case MCCFIInstruction::OpNegateRAState:
case MCCFIInstruction::OpNegateRAStateWithPC:
case MCCFIInstruction::OpLLVMDefAspaceCfa:
case MCCFIInstruction::OpLabel:
llvm_unreachable("unsupported CFI opcode");
Expand Down Expand Up @@ -2864,6 +2866,7 @@ BinaryFunction::unwindCFIState(int32_t FromState, int32_t ToState,
case MCCFIInstruction::OpAdjustCfaOffset:
case MCCFIInstruction::OpWindowSave:
case MCCFIInstruction::OpNegateRAState:
case MCCFIInstruction::OpNegateRAStateWithPC:
case MCCFIInstruction::OpLLVMDefAspaceCfa:
case MCCFIInstruction::OpLabel:
llvm_unreachable("unsupported CFI opcode");
Expand Down
2 changes: 2 additions & 0 deletions bolt/test/X86/pre-aggregated-perf.test
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ REQUIRES: system-linux

RUN: yaml2obj %p/Inputs/blarge.yaml &> %t.exe
RUN: perf2bolt %t.exe -o %t --pa -p %p/Inputs/pre-aggregated.txt -w %t.new \
RUN: --show-density \
RUN: --profile-density-threshold=9 --profile-density-cutoff-hot=970000 \
RUN: --profile-use-dfs | FileCheck %s --check-prefix=CHECK-P2B

CHECK-P2B: BOLT-INFO: 4 out of 7 functions in the binary (57.1%) have non-empty execution profile
CHECK-P2B: BOLT-INFO: Functions with density >= 21.7 account for 97.00% total sample counts.

RUN: perf2bolt %t.exe -o %t --pa -p %p/Inputs/pre-aggregated.txt -w %t.new \
RUN: --show-density \
RUN: --profile-density-cutoff-hot=970000 \
RUN: --profile-use-dfs 2>&1 | FileCheck %s --check-prefix=CHECK-WARNING

Expand Down
3 changes: 3 additions & 0 deletions clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include "MultipleStatementMacroCheck.h"
#include "NoEscapeCheck.h"
#include "NonZeroEnumToBoolConversionCheck.h"
#include "NondeterministicPointerIterationOrderCheck.h"
#include "NotNullTerminatedResultCheck.h"
#include "OptionalValueConversionCheck.h"
#include "ParentVirtualCallCheck.h"
Expand Down Expand Up @@ -174,6 +175,8 @@ class BugproneModule : public ClangTidyModule {
"bugprone-multiple-new-in-one-expression");
CheckFactories.registerCheck<MultipleStatementMacroCheck>(
"bugprone-multiple-statement-macro");
CheckFactories.registerCheck<NondeterministicPointerIterationOrderCheck>(
"bugprone-nondeterministic-pointer-iteration-order");
CheckFactories.registerCheck<OptionalValueConversionCheck>(
"bugprone-optional-value-conversion");
CheckFactories.registerCheck<PointerArithmeticOnPolymorphicObjectCheck>(
Expand Down
1 change: 1 addition & 0 deletions clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ add_clang_library(clangTidyBugproneModule STATIC
MultipleNewInOneExpressionCheck.cpp
MultipleStatementMacroCheck.cpp
NoEscapeCheck.cpp
NondeterministicPointerIterationOrderCheck.cpp
NonZeroEnumToBoolConversionCheck.cpp
NotNullTerminatedResultCheck.cpp
OptionalValueConversionCheck.cpp
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//===----- NondeterministicPointerIterationOrderCheck.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 "NondeterministicPointerIterationOrderCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/Lex/Lexer.h"

using namespace clang::ast_matchers;

namespace clang::tidy::bugprone {

void NondeterministicPointerIterationOrderCheck::registerMatchers(
MatchFinder *Finder) {

auto LoopVariable = varDecl(hasType(
qualType(hasCanonicalType(anyOf(referenceType(), pointerType())))));

auto RangeInit = declRefExpr(to(varDecl(
hasType(recordDecl(hasAnyName("std::unordered_set", "std::unordered_map",
"std::unordered_multiset",
"std::unordered_multimap"))
.bind("recorddecl")))));

Finder->addMatcher(cxxForRangeStmt(hasLoopVariable(LoopVariable),
hasRangeInit(RangeInit.bind("rangeinit")))
.bind("cxxForRangeStmt"),
this);

auto SortFuncM = callee(functionDecl(hasAnyName(
"std::is_sorted", "std::nth_element", "std::sort", "std::partial_sort",
"std::partition", "std::stable_partition", "std::stable_sort")));

auto IteratesPointerEltsM = hasArgument(
0,
cxxMemberCallExpr(on(hasType(cxxRecordDecl(has(fieldDecl(hasType(qualType(
hasCanonicalType(pointsTo(hasCanonicalType(pointerType()))))))))))));

Finder->addMatcher(
callExpr(allOf(SortFuncM, IteratesPointerEltsM)).bind("sortsemantic"),
this);
}

void NondeterministicPointerIterationOrderCheck::check(
const MatchFinder::MatchResult &Result) {
const auto *ForRangePointers =
Result.Nodes.getNodeAs<CXXForRangeStmt>("cxxForRangeStmt");

if ((ForRangePointers) && !(ForRangePointers->getBeginLoc().isMacroID())) {
const auto *RangeInit = Result.Nodes.getNodeAs<Stmt>("rangeinit");
if (const auto *ClassTemplate =
Result.Nodes.getNodeAs<ClassTemplateSpecializationDecl>(
"recorddecl")) {
const TemplateArgumentList &TemplateArgs =
ClassTemplate->getTemplateArgs();
const bool IsAlgoArgPointer =
TemplateArgs[0].getAsType()->isPointerType();

if (IsAlgoArgPointer) {
SourceRange R = RangeInit->getSourceRange();
diag(R.getBegin(), "iteration of pointers is nondeterministic") << R;
}
}
return;
}
const auto *SortPointers = Result.Nodes.getNodeAs<Stmt>("sortsemantic");

if ((SortPointers) && !(SortPointers->getBeginLoc().isMacroID())) {
SourceRange R = SortPointers->getSourceRange();
diag(R.getBegin(), "sorting pointers is nondeterministic") << R;
}
}

} // namespace clang::tidy::bugprone
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//=== NondeterministicPointerIterationOrderCheck.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_NONDETERMINISTIC_POINTER_ITERATION_ORDER_CHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_NONDETERMINISTIC_POINTER_ITERATION_ORDER_CHECK_H

#include "../ClangTidyCheck.h"

namespace clang::tidy::bugprone {

/// Finds nondeterministic usages of pointers in unordered containers. The
/// check also finds calls to sorting-like algorithms on a container of
/// pointers.
///
/// For the user-facing documentation see:
/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone/nondeterministic-pointer-iteration-order.html
class NondeterministicPointerIterationOrderCheck : public ClangTidyCheck {
public:
NondeterministicPointerIterationOrderCheck(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;
std::optional<TraversalKind> getCheckTraversalKind() const override {
return TK_IgnoreUnlessSpelledInSource;
}
};

} // namespace clang::tidy::bugprone

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_NONDETERMINISTIC_POINTER_ITERATION_ORDER_CHECK_H
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,13 @@ unsigned getNumberOfDesignated(const InitListExpr *SyntacticInitList) {
});
}

AST_MATCHER(CXXRecordDecl, isAggregate) { return Node.isAggregate(); }
AST_MATCHER(CXXRecordDecl, isAggregate) {
return Node.hasDefinition() && Node.isAggregate();
}

AST_MATCHER(CXXRecordDecl, isPOD) { return Node.isPOD(); }
AST_MATCHER(CXXRecordDecl, isPOD) {
return Node.hasDefinition() && Node.isPOD();
}

AST_MATCHER(InitListExpr, isFullyDesignated) {
if (const InitListExpr *SyntacticForm =
Expand Down
24 changes: 16 additions & 8 deletions clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@ AST_MATCHER(EnumDecl, hasSequentialInitialValues) {
return !AllEnumeratorsArePowersOfTwo;
}

std::string getName(const EnumDecl *Decl) {
if (!Decl->getDeclName())
return "<unnamed>";

return Decl->getQualifiedNameAsString();
}

} // namespace

EnumInitialValueCheck::EnumInitialValueCheck(StringRef Name,
Expand Down Expand Up @@ -160,10 +167,11 @@ void EnumInitialValueCheck::registerMatchers(MatchFinder *Finder) {
void EnumInitialValueCheck::check(const MatchFinder::MatchResult &Result) {
if (const auto *Enum = Result.Nodes.getNodeAs<EnumDecl>("inconsistent")) {
DiagnosticBuilder Diag =
diag(Enum->getBeginLoc(),
"initial values in enum %0 are not consistent, consider explicit "
"initialization of all, none or only the first enumerator")
<< Enum;
diag(
Enum->getBeginLoc(),
"initial values in enum '%0' are not consistent, consider explicit "
"initialization of all, none or only the first enumerator")
<< getName(Enum);
for (const EnumConstantDecl *ECD : Enum->enumerators())
if (ECD->getInitExpr() == nullptr) {
const SourceLocation EndLoc = Lexer::getLocForEndOfToken(
Expand All @@ -183,16 +191,16 @@ void EnumInitialValueCheck::check(const MatchFinder::MatchResult &Result) {
if (Loc.isInvalid() || Loc.isMacroID())
return;
DiagnosticBuilder Diag = diag(Loc, "zero initial value for the first "
"enumerator in %0 can be disregarded")
<< Enum;
"enumerator in '%0' can be disregarded")
<< getName(Enum);
cleanInitialValue(Diag, ECD, *Result.SourceManager, getLangOpts());
return;
}
if (const auto *Enum = Result.Nodes.getNodeAs<EnumDecl>("sequential")) {
DiagnosticBuilder Diag =
diag(Enum->getBeginLoc(),
"sequential initial value in %0 can be ignored")
<< Enum;
"sequential initial value in '%0' can be ignored")
<< getName(Enum);
for (const EnumConstantDecl *ECD : llvm::drop_begin(Enum->enumerators()))
cleanInitialValue(Diag, ECD, *Result.SourceManager, getLangOpts());
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "../utils/FixItHintUtils.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Lex/Lexer.h"
#include "clang/Tooling/FixIt.h"
#include <queue>
Expand All @@ -26,6 +27,8 @@ AST_MATCHER(Stmt, isMacroExpansion) {
return SM.isMacroBodyExpansion(Loc) || SM.isMacroArgExpansion(Loc);
}

AST_MATCHER(Stmt, isC23) { return Finder->getASTContext().getLangOpts().C23; }

bool isNULLMacroExpansion(const Stmt *Statement, ASTContext &Context) {
SourceManager &SM = Context.getSourceManager();
const LangOptions &LO = Context.getLangOpts();
Expand Down Expand Up @@ -298,6 +301,11 @@ void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) {
hasCastKind(CK_FloatingToBoolean),
hasCastKind(CK_PointerToBoolean),
hasCastKind(CK_MemberPointerToBoolean)),
// Exclude cases of C23 comparison result.
unless(allOf(isC23(),
hasSourceExpression(ignoringParens(
binaryOperator(hasAnyOperatorName(
">", ">=", "==", "!=", "<", "<=")))))),
// Exclude case of using if or while statements with variable
// declaration, e.g.:
// if (int var = functionCall()) {}
Expand Down
16 changes: 14 additions & 2 deletions clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ New checks
Warns about code that tries to cast between pointers by means of
``std::bit_cast`` or ``memcpy``.

- New :doc:`bugprone-nondeterministic-pointer-iteration-order
<clang-tidy/checks/bugprone/nondeterministic-pointer-iteration-order>`
check.

Finds nondeterministic usages of pointers in unordered containers.

- New :doc:`bugprone-tagged-union-member-count
<clang-tidy/checks/bugprone/tagged-union-member-count>` check.

Expand Down Expand Up @@ -210,6 +216,10 @@ Changes in existing checks
a false positive when only an implicit conversion happened inside an
initializer list.

- Improved :doc:`modernize-use-designated-initializers
<clang-tidy/checks/modernize/use-designated-initializers>` check to fix a
crash when a class is declared but not defined.

- Improved :doc:`modernize-use-nullptr
<clang-tidy/checks/modernize/use-nullptr>` check to also recognize
``NULL``/``__null`` (but not ``0``) when used with a templated type.
Expand Down Expand Up @@ -243,13 +253,15 @@ Changes in existing checks

- Improved :doc:`readability-enum-initial-value
<clang-tidy/checks/readability/enum-initial-value>` check by only issuing
diagnostics for the definition of an ``enum``, and by fixing a typo in the
diagnostics for the definition of an ``enum``, by not emitting a redundant
file path for anonymous enums in the diagnostic, and by fixing a typo in the
diagnostic.

- Improved :doc:`readability-implicit-bool-conversion
<clang-tidy/checks/readability/implicit-bool-conversion>` check
by adding the option `UseUpperCaseLiteralSuffix` to select the
case of the literal suffix in fixes.
case of the literal suffix in fixes and fixing false positive for implicit
conversion of comparison result in C23.

- Improved :doc:`readability-redundant-smartptr-get
<clang-tidy/checks/readability/redundant-smartptr-get>` check to
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
.. title:: clang-tidy - bugprone-nondeterministic-pointer-iteration-order

bugprone-nondeterministic-pointer-iteration-order
=================================================

Finds nondeterministic usages of pointers in unordered containers.

One canonical example is iteration across a container of pointers.

.. code-block:: c++

{
int a = 1, b = 2;
std::unordered_set<int *> UnorderedPtrSet = {&a, &b};
for (auto i : UnorderedPtrSet)
f(i);
}
Another such example is sorting a container of pointers.

.. code-block:: c++

{
int a = 1, b = 2;
std::vector<int *> VectorOfPtr = {&a, &b};
std::sort(VectorOfPtr.begin(), VectorOfPtr.end());
}
Iteration of a containers of pointers may present the order of different
pointers differently across different runs of a program. In some cases this
may be acceptable behavior, in others this may be unexpected behavior. This
check is advisory for this reason.

This check only detects range-based for loops over unordered sets and maps. It
also detects calls sorting-like algorithms on containers holding pointers.
Other similar usages will not be found and are false negatives.

Limitations:

* This check currently does not check if a nondeterministic iteration order is
likely to be a mistake, and instead marks all such iterations as bugprone.
* std::reference_wrapper is not considered yet.
* Only for loops are considered, other iterators can be included in
improvements.
1 change: 1 addition & 0 deletions clang-tools-extra/docs/clang-tidy/checks/list.rst
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ Clang-Tidy Checks
:doc:`bugprone-multiple-new-in-one-expression <bugprone/multiple-new-in-one-expression>`,
:doc:`bugprone-multiple-statement-macro <bugprone/multiple-statement-macro>`,
:doc:`bugprone-no-escape <bugprone/no-escape>`,
:doc:`bugprone-nondeterministic-pointer-iteration-order <bugprone/nondeterministic-pointer-iteration-order>`,
:doc:`bugprone-non-zero-enum-to-bool-conversion <bugprone/non-zero-enum-to-bool-conversion>`,
:doc:`bugprone-not-null-terminated-result <bugprone/not-null-terminated-result>`, "Yes"
:doc:`bugprone-optional-value-conversion <bugprone/optional-value-conversion>`, "Yes"
Expand Down
7 changes: 3 additions & 4 deletions clang-tools-extra/modularize/CoverageChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,9 @@ bool CoverageChecker::collectModuleHeaders(const Module &Mod) {
return false;
}

for (auto &HeaderKind : Mod.Headers)
for (auto &Header : HeaderKind)
ModuleMapHeadersSet.insert(
ModularizeUtilities::getCanonicalPath(Header.Entry.getName()));
for (const auto &Header : Mod.getAllHeaders())
ModuleMapHeadersSet.insert(
ModularizeUtilities::getCanonicalPath(Header.Entry.getName()));

for (auto *Submodule : Mod.submodules())
collectModuleHeaders(*Submodule);
Expand Down
Loading

0 comments on commit 1353852

Please sign in to comment.