Skip to content

Commit 86882b6

Browse files
authored
Merge branch 'main' into fix-154408
2 parents d4f9768 + ef68d15 commit 86882b6

File tree

58 files changed

+1127
-229
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1127
-229
lines changed

bolt/lib/Core/MCPlusBuilder.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ using namespace bolt;
3030
using namespace MCPlus;
3131

3232
namespace opts {
33+
cl::opt<bool>
34+
TerminalHLT("terminal-x86-hlt",
35+
cl::desc("Assume that execution stops at x86 HLT instruction"),
36+
cl::init(true), cl::Hidden, cl::cat(BoltCategory));
37+
3338
cl::opt<bool>
3439
TerminalTrap("terminal-trap",
3540
cl::desc("Assume that execution stops at trap instruction"),
@@ -132,10 +137,13 @@ bool MCPlusBuilder::equals(const MCSpecifierExpr &A, const MCSpecifierExpr &B,
132137
}
133138

134139
bool MCPlusBuilder::isTerminator(const MCInst &Inst) const {
135-
return (opts::TerminalTrap && Info->get(Inst.getOpcode()).isTrap()) ||
136-
Analysis->isTerminator(Inst)
137-
? !isX86HLT(Inst)
138-
: false;
140+
if (isX86HLT(Inst))
141+
return opts::TerminalHLT;
142+
143+
if (Info->get(Inst.getOpcode()).isTrap())
144+
return opts::TerminalTrap;
145+
146+
return Analysis->isTerminator(Inst);
139147
}
140148

141149
void MCPlusBuilder::setTailCall(MCInst &Inst) const {

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ extern cl::opt<bool> KeepNops;
8484
extern cl::opt<bool> Lite;
8585
extern cl::list<std::string> ReorderData;
8686
extern cl::opt<bolt::ReorderFunctions::ReorderType> ReorderFunctions;
87+
extern cl::opt<bool> TerminalHLT;
8788
extern cl::opt<bool> TerminalTrap;
8889
extern cl::opt<bool> TimeBuild;
8990
extern cl::opt<bool> TimeRewrite;
@@ -2177,7 +2178,9 @@ void RewriteInstance::adjustCommandLineOptions() {
21772178
if (!opts::KeepNops.getNumOccurrences())
21782179
opts::KeepNops = true;
21792180

2180-
// Linux kernel may resume execution after a trap instruction in some cases.
2181+
// Linux kernel may resume execution after a trap or x86 HLT instruction.
2182+
if (!opts::TerminalHLT.getNumOccurrences())
2183+
opts::TerminalHLT = false;
21812184
if (!opts::TerminalTrap.getNumOccurrences())
21822185
opts::TerminalTrap = false;
21832186
}

bolt/test/X86/cfg_build_hlt.s

Lines changed: 0 additions & 17 deletions
This file was deleted.

bolt/test/X86/hlt-terminator.s

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
## Check that HLT instruction is handled differently depending on the flags.
2+
## It's a terminator in the user-level code, but the execution can resume in
3+
## ring 0.
4+
5+
# RUN: %clang %cflags %s -static -o %t.exe -nostdlib
6+
# RUN: llvm-bolt %t.exe --print-cfg --print-only=main --terminal-x86-hlt=0 \
7+
# RUN: -o %t.ring0 2>&1 | FileCheck %s --check-prefix=CHECK-RING0
8+
# RUN: llvm-bolt %t.exe --print-cfg --print-only=main \
9+
# RUN: -o %t.ring3 2>&1 | FileCheck %s --check-prefix=CHECK-RING3
10+
# RUN: llvm-objdump -d %t.ring0 --print-imm-hex | FileCheck %s --check-prefix=CHECK-BIN
11+
12+
# CHECK-RING0: BB Count : 1
13+
# CHECK-RING3: BB Count : 2
14+
15+
# CHECK-BIN: <main>:
16+
# CHECK-BIN-NEXT: f4 hlt
17+
# CHECK-BIN-NEXT: c3 retq
18+
19+
.global main
20+
.type main, %function
21+
main:
22+
hlt
23+
retq
24+
.size main, .-main

clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ void UnconventionalAssignOperatorCheck::registerMatchers(
2929
const auto HasGoodReturnType =
3030
cxxMethodDecl(returns(hasCanonicalType(lValueReferenceType(pointee(
3131
unless(isConstQualified()),
32-
anyOf(autoType(), hasDeclaration(equalsBoundNode("class"))))))));
32+
anyOf(autoType(),
33+
hasDeclaration(declaresSameEntityAsBoundNode("class"))))))));
3334

3435
const auto IsSelf = qualType(hasCanonicalType(
35-
anyOf(hasDeclaration(equalsBoundNode("class")),
36-
referenceType(pointee(hasDeclaration(equalsBoundNode("class")))))));
36+
anyOf(hasDeclaration(declaresSameEntityAsBoundNode("class")),
37+
referenceType(pointee(
38+
hasDeclaration(declaresSameEntityAsBoundNode("class")))))));
3739
const auto IsAssign =
3840
cxxMethodDecl(unless(anyOf(isDeleted(), isPrivate(), isImplicit())),
3941
hasName("operator="), ofClass(recordDecl().bind("class")))

clang-tools-extra/docs/clang-tidy/index.rst

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,107 @@ An overview of all the command-line options:
343343
some-check.SomeOption: 'some value'
344344
...
345345
346+
Clang-Tidy Automation
347+
=====================
348+
349+
:program:`clang-tidy` can analyze multiple source files by specifying them on
350+
the command line. For larger projects, automation scripts provide additional
351+
functionality like parallel execution and integration with version control
352+
systems.
353+
354+
Running Clang-Tidy in Parallel
355+
-------------------------------
356+
357+
:program:`clang-tidy` can process multiple files sequentially, but for projects
358+
with many source files, the :program:`run-clang-tidy.py` script provides
359+
parallel execution to significantly reduce analysis time. This script is
360+
included with clang-tidy and runs :program:`clang-tidy` over all files in a
361+
compilation database or a specified path concurrently.
362+
363+
The script requires a compilation database (``compile_commands.json``) which
364+
can be generated by build systems like CMake (using
365+
``-DCMAKE_EXPORT_COMPILE_COMMANDS=ON``) or by tools like `Bear`_.
366+
367+
The script supports most of the same options as :program:`clang-tidy` itself,
368+
including ``-checks=``, ``-fix``, ``-header-filter=``, and configuration
369+
options. Run ``run-clang-tidy.py --help`` for a complete list of available
370+
options.
371+
372+
Example invocations:
373+
374+
.. code-block:: console
375+
376+
# Run clang-tidy on all files in the compilation database in parallel
377+
$ run-clang-tidy.py -p=build/
378+
379+
# Run with specific checks and apply fixes
380+
$ run-clang-tidy.py -p=build/ -fix -checks=-*,readability-*
381+
382+
# Run on specific files/directories with header filtering
383+
$ run-clang-tidy.py -p=build/ -header-filter=src/ src/
384+
385+
# Run with parallel execution (uses all CPU cores by default)
386+
$ run-clang-tidy.py -p=build/ -j 4
387+
388+
Running Clang-Tidy on Diff
389+
---------------------------
390+
391+
The :program:`clang-tidy-diff.py` script allows you to run
392+
:program:`clang-tidy` on the lines that have been modified in your working
393+
directory or in a specific diff. Importantly, :program:`clang-tidy-diff.py` only reports
394+
diagnostics for changed lines; :program:`clang-tidy` still analyzes the entire
395+
file and filters out unchanged lines after analysis, so this does not improve
396+
performance. This is particularly useful for code reviews and continuous
397+
integration, as it focuses analysis on the changed code rather than the entire
398+
codebase.
399+
400+
The script can work with various diff sources:
401+
402+
* Git working directory changes
403+
* Output from ``git diff``
404+
* Output from ``svn diff``
405+
* Patch files
406+
407+
Example invocations:
408+
409+
.. code-block:: console
410+
411+
# Run clang-tidy on all changes in the working directory
412+
$ git diff -U0 --no-color HEAD^ | clang-tidy-diff.py -p1
413+
414+
# Run with specific checks and apply fixes
415+
$ git diff -U0 --no-color HEAD^ | clang-tidy-diff.py -p1 -fix \
416+
-checks=-*,readability-*
417+
418+
# Run on staged changes
419+
$ git diff -U0 --no-color --cached | clang-tidy-diff.py -p1
420+
421+
# Run on changes between two commits
422+
$ git diff -U0 --no-color HEAD~2 HEAD | clang-tidy-diff.py -p1
423+
424+
# Run on a patch file
425+
$ clang-tidy-diff.py -p1 < changes.patch
426+
427+
The ``-p1`` option tells the script to strip one level of path prefix from
428+
the diff, which is typically needed for Git diffs. The script supports most of
429+
the same options as :program:`clang-tidy` itself, including ``-checks=``,
430+
``-fix``, ``-header-filter=``, and configuration options.
431+
432+
While :program:`clang-tidy-diff.py` is useful for focusing on recent changes,
433+
relying solely on it may lead to incomplete analysis. Since the script only
434+
reports warnings from the modified lines, it may miss issues that are caused
435+
by the changes but manifest elsewhere in the code. For example, changes that
436+
only add lines to a function may cause it to violate size limits (e.g.,
437+
`readability-function-size <checks/readability/function-size.html>`_), but the
438+
diagnostic will be reported at the function declaration, which may not be in
439+
the diff and thus filtered out. Modifications to header files may also affect
440+
many implementation files, but only warnings in the modified header lines will
441+
be reported.
442+
443+
For comprehensive analysis, especially before merging significant changes,
444+
consider running :program:`clang-tidy` on the entire affected files or the
445+
whole project using :program:`run-clang-tidy.py`.
446+
346447
.. _clang-tidy-nolint:
347448

348449
Suppressing Undesired Diagnostics
@@ -465,5 +566,6 @@ example, ``NOLINTBEGIN(check-name)`` can be paired with
465566
:program:`clang-tidy` will generate a ``clang-tidy-nolint`` error diagnostic if
466567
any ``NOLINTBEGIN``/``NOLINTEND`` comment violates these requirements.
467568

569+
.. _Bear: https://github.com/rizsotto/Bear
468570
.. _LibTooling: https://clang.llvm.org/docs/LibTooling.html
469571
.. _How To Setup Tooling For LLVM: https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html

clang-tools-extra/test/clang-tidy/checkers/misc/unconventional-assign-operator.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,11 @@ struct TemplateAssignment {
176176
}
177177
};
178178
}
179+
180+
namespace GH153770 {
181+
struct A;
182+
struct A {
183+
A() = default;
184+
A& operator=(const A&) = default;
185+
};
186+
} // namespace GH153770

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ Bug Fixes to C++ Support
232232
"intializing multiple members of union" coincide (#GH149985).
233233
- Fix a crash when using ``explicit(bool)`` in pre-C++11 language modes. (#GH152729)
234234
- Fix the parsing of variadic member functions when the ellipis immediately follows a default argument.(#GH153445)
235+
- Fixed a bug that caused ``this`` captured by value in a lambda with a dependent explicit object parameter to not be
236+
instantiated properly. (#GH154054)
235237

236238
Bug Fixes to AST Handling
237239
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/ASTMatchers/ASTMatchers.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5739,6 +5739,14 @@ AST_POLYMORPHIC_MATCHER_P(equalsBoundNode,
57395739
return Builder->removeBindings(Predicate);
57405740
}
57415741

5742+
/// Matches a declaration if it declares the same entity as the node previously
5743+
/// bound to \p ID.
5744+
AST_MATCHER_P(Decl, declaresSameEntityAsBoundNode, std::string, ID) {
5745+
return Builder->removeBindings([&](const internal::BoundNodesMap &Nodes) {
5746+
return !clang::declaresSameEntity(&Node, Nodes.getNodeAs<Decl>(ID));
5747+
});
5748+
}
5749+
57425750
/// Matches the condition variable statement in an if statement.
57435751
///
57445752
/// Given

clang/lib/ASTMatchers/Dynamic/Registry.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ RegistryMaps::RegistryMaps() {
240240
REGISTER_MATCHER(enumDecl);
241241
REGISTER_MATCHER(enumType);
242242
REGISTER_MATCHER(equalsBoundNode);
243+
REGISTER_MATCHER(declaresSameEntityAsBoundNode);
243244
REGISTER_MATCHER(equalsIntegralValue);
244245
REGISTER_MATCHER(explicitCastExpr);
245246
REGISTER_MATCHER(exportDecl);

0 commit comments

Comments
 (0)