Skip to content

Commit 5bab4a5

Browse files
committed
merge main into amd-staging
Change-Id: I4bb3852d8287591175bab69a2a5d95558c9464a4
2 parents c9765dc + 9d95e26 commit 5bab4a5

File tree

338 files changed

+23454
-13498
lines changed

Some content is hidden

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

338 files changed

+23454
-13498
lines changed

.github/workflows/release-binaries.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,14 @@ jobs:
420420
attestations: write # For artifact attestations
421421

422422
steps:
423+
- name: Checkout Release Scripts
424+
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
425+
with:
426+
sparse-checkout: |
427+
llvm/utils/release/github-upload-release.py
428+
llvm/utils/git/requirements.txt
429+
sparse-checkout-cone-mode: false
430+
423431
- name: 'Download artifact'
424432
uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1
425433
with:
@@ -442,14 +450,6 @@ jobs:
442450
name: ${{ needs.prepare.outputs.release-binary-filename }}-attestation
443451
path: ${{ needs.prepare.outputs.release-binary-filename }}.jsonl
444452

445-
- name: Checkout Release Scripts
446-
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
447-
with:
448-
sparse-checkout: |
449-
llvm/utils/release/github-upload-release.py
450-
llvm/utils/git/requirements.txt
451-
sparse-checkout-cone-mode: false
452-
453453
- name: Install Python Requirements
454454
run: |
455455
pip install --require-hashes -r ./llvm/utils/git/requirements.txt

.github/workflows/release-documentation.yml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,20 @@ jobs:
7272
ref: main
7373
fetch-depth: 0
7474
path: www-releases
75+
persist-credentials: false
7576

7677
- name: Upload Release Notes
7778
if: env.upload
7879
env:
79-
WWW_RELEASES_TOKEN: ${{ secrets.WWW_RELEASES_TOKEN }}
80+
GH_TOKEN: ${{ secrets.WWW_RELEASES_TOKEN }}
8081
run: |
81-
mkdir -p ../www-releases/${{ inputs.release-version }}
82-
mv ./docs-build/html-export/* ../www-releases/${{ inputs.release-version }}
83-
cd ../www-releases
82+
mkdir -p www-releases/${{ inputs.release-version }}
83+
mv ./docs-build/html-export/* www-releases/${{ inputs.release-version }}
84+
cd www-releases
85+
git checkout -b ${{ inputs.release-version }}
8486
git add ${{ inputs.release-version }}
8587
git config user.email "[email protected]"
8688
git config user.name "llvmbot"
8789
git commit -a -m "Add ${{ inputs.release-version }} documentation"
88-
git push "https://[email protected]/${{ github.repository_owner }}/www-releases" main:main
90+
git push --force "https://[email protected]/llvmbot/www-releases.git" HEAD:refs/heads/${{ inputs.release-version }}
91+
gh pr create -f -B main -H ${{ inputs.release-version }} -R llvmbot/www-releases

clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
#include "SuspiciousStringviewDataUsageCheck.h"
7979
#include "SwappedArgumentsCheck.h"
8080
#include "SwitchMissingDefaultCaseCheck.h"
81+
#include "TaggedUnionMemberCountCheck.h"
8182
#include "TerminatingContinueCheck.h"
8283
#include "ThrowKeywordMissingCheck.h"
8384
#include "TooSmallLoopVariableCheck.h"
@@ -229,6 +230,8 @@ class BugproneModule : public ClangTidyModule {
229230
"bugprone-suspicious-stringview-data-usage");
230231
CheckFactories.registerCheck<SwappedArgumentsCheck>(
231232
"bugprone-swapped-arguments");
233+
CheckFactories.registerCheck<TaggedUnionMemberCountCheck>(
234+
"bugprone-tagged-union-member-count");
232235
CheckFactories.registerCheck<TerminatingContinueCheck>(
233236
"bugprone-terminating-continue");
234237
CheckFactories.registerCheck<ThrowKeywordMissingCheck>(

clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ add_clang_library(clangTidyBugproneModule
7373
SuspiciousSemicolonCheck.cpp
7474
SuspiciousStringCompareCheck.cpp
7575
SwappedArgumentsCheck.cpp
76+
TaggedUnionMemberCountCheck.cpp
7677
TerminatingContinueCheck.cpp
7778
ThrowKeywordMissingCheck.cpp
7879
TooSmallLoopVariableCheck.cpp
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
//===--- TaggedUnionMemberCountCheck.cpp - clang-tidy ---------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "TaggedUnionMemberCountCheck.h"
10+
#include "../utils/OptionsUtils.h"
11+
#include "clang/ASTMatchers/ASTMatchFinder.h"
12+
#include "llvm/ADT/STLExtras.h"
13+
#include "llvm/ADT/SmallSet.h"
14+
15+
using namespace clang::ast_matchers;
16+
17+
namespace clang::tidy::bugprone {
18+
19+
static constexpr llvm::StringLiteral StrictModeOptionName = "StrictMode";
20+
static constexpr llvm::StringLiteral EnableCountingEnumHeuristicOptionName =
21+
"EnableCountingEnumHeuristic";
22+
static constexpr llvm::StringLiteral CountingEnumPrefixesOptionName =
23+
"CountingEnumPrefixes";
24+
static constexpr llvm::StringLiteral CountingEnumSuffixesOptionName =
25+
"CountingEnumSuffixes";
26+
27+
static constexpr bool StrictModeOptionDefaultValue = false;
28+
static constexpr bool EnableCountingEnumHeuristicOptionDefaultValue = true;
29+
static constexpr llvm::StringLiteral CountingEnumPrefixesOptionDefaultValue =
30+
"";
31+
static constexpr llvm::StringLiteral CountingEnumSuffixesOptionDefaultValue =
32+
"count";
33+
34+
static constexpr llvm::StringLiteral RootMatchBindName = "root";
35+
static constexpr llvm::StringLiteral UnionMatchBindName = "union";
36+
static constexpr llvm::StringLiteral TagMatchBindName = "tags";
37+
38+
namespace {
39+
40+
AST_MATCHER_P2(RecordDecl, fieldCountOfKindIsOne,
41+
ast_matchers::internal::Matcher<FieldDecl>, InnerMatcher,
42+
StringRef, BindName) {
43+
// BoundNodesTreeBuilder resets itself when a match occurs.
44+
// So to avoid losing previously saved binds, a temporary instance
45+
// is used for matching.
46+
//
47+
// For precedence, see commit: 5b07de1a5faf4a22ae6fd982b877c5e7e3a76559
48+
clang::ast_matchers::internal::BoundNodesTreeBuilder TempBuilder;
49+
50+
const FieldDecl *FirstMatch = nullptr;
51+
for (const FieldDecl *Field : Node.fields()) {
52+
if (InnerMatcher.matches(*Field, Finder, &TempBuilder)) {
53+
if (FirstMatch) {
54+
return false;
55+
} else {
56+
FirstMatch = Field;
57+
}
58+
}
59+
}
60+
61+
if (FirstMatch) {
62+
Builder->setBinding(BindName, clang::DynTypedNode::create(*FirstMatch));
63+
return true;
64+
}
65+
return false;
66+
}
67+
68+
} // namespace
69+
70+
TaggedUnionMemberCountCheck::TaggedUnionMemberCountCheck(
71+
StringRef Name, ClangTidyContext *Context)
72+
: ClangTidyCheck(Name, Context),
73+
StrictMode(
74+
Options.get(StrictModeOptionName, StrictModeOptionDefaultValue)),
75+
EnableCountingEnumHeuristic(
76+
Options.get(EnableCountingEnumHeuristicOptionName,
77+
EnableCountingEnumHeuristicOptionDefaultValue)),
78+
CountingEnumPrefixes(utils::options::parseStringList(
79+
Options.get(CountingEnumPrefixesOptionName,
80+
CountingEnumPrefixesOptionDefaultValue))),
81+
CountingEnumSuffixes(utils::options::parseStringList(
82+
Options.get(CountingEnumSuffixesOptionName,
83+
CountingEnumSuffixesOptionDefaultValue))) {
84+
if (!EnableCountingEnumHeuristic) {
85+
if (Options.get(CountingEnumPrefixesOptionName))
86+
configurationDiag("%0: Counting enum heuristic is disabled but "
87+
"%1 is set")
88+
<< Name << CountingEnumPrefixesOptionName;
89+
if (Options.get(CountingEnumSuffixesOptionName))
90+
configurationDiag("%0: Counting enum heuristic is disabled but "
91+
"%1 is set")
92+
<< Name << CountingEnumSuffixesOptionName;
93+
}
94+
}
95+
96+
void TaggedUnionMemberCountCheck::storeOptions(
97+
ClangTidyOptions::OptionMap &Opts) {
98+
Options.store(Opts, StrictModeOptionName, StrictMode);
99+
Options.store(Opts, EnableCountingEnumHeuristicOptionName,
100+
EnableCountingEnumHeuristic);
101+
Options.store(Opts, CountingEnumPrefixesOptionName,
102+
utils::options::serializeStringList(CountingEnumPrefixes));
103+
Options.store(Opts, CountingEnumSuffixesOptionName,
104+
utils::options::serializeStringList(CountingEnumSuffixes));
105+
}
106+
107+
void TaggedUnionMemberCountCheck::registerMatchers(MatchFinder *Finder) {
108+
109+
auto UnionField = fieldDecl(hasType(qualType(
110+
hasCanonicalType(recordType(hasDeclaration(recordDecl(isUnion())))))));
111+
112+
auto EnumField = fieldDecl(hasType(
113+
qualType(hasCanonicalType(enumType(hasDeclaration(enumDecl()))))));
114+
115+
auto hasOneUnionField = fieldCountOfKindIsOne(UnionField, UnionMatchBindName);
116+
auto hasOneEnumField = fieldCountOfKindIsOne(EnumField, TagMatchBindName);
117+
118+
Finder->addMatcher(recordDecl(anyOf(isStruct(), isClass()), hasOneUnionField,
119+
hasOneEnumField, unless(isImplicit()))
120+
.bind(RootMatchBindName),
121+
this);
122+
}
123+
124+
bool TaggedUnionMemberCountCheck::isCountingEnumLikeName(StringRef Name) const {
125+
if (llvm::any_of(CountingEnumPrefixes, [Name](StringRef Prefix) -> bool {
126+
return Name.starts_with_insensitive(Prefix);
127+
}))
128+
return true;
129+
if (llvm::any_of(CountingEnumSuffixes, [Name](StringRef Suffix) -> bool {
130+
return Name.ends_with_insensitive(Suffix);
131+
}))
132+
return true;
133+
return false;
134+
}
135+
136+
std::pair<const std::size_t, const EnumConstantDecl *>
137+
TaggedUnionMemberCountCheck::getNumberOfEnumValues(const EnumDecl *ED) {
138+
llvm::SmallSet<llvm::APSInt, 16> EnumValues;
139+
140+
const EnumConstantDecl *LastEnumConstant = nullptr;
141+
for (const EnumConstantDecl *Enumerator : ED->enumerators()) {
142+
EnumValues.insert(Enumerator->getInitVal());
143+
LastEnumConstant = Enumerator;
144+
}
145+
146+
if (EnableCountingEnumHeuristic && LastEnumConstant &&
147+
isCountingEnumLikeName(LastEnumConstant->getName()) &&
148+
(LastEnumConstant->getInitVal() == (EnumValues.size() - 1))) {
149+
return {EnumValues.size() - 1, LastEnumConstant};
150+
}
151+
152+
return {EnumValues.size(), nullptr};
153+
}
154+
155+
void TaggedUnionMemberCountCheck::check(
156+
const MatchFinder::MatchResult &Result) {
157+
const auto *Root = Result.Nodes.getNodeAs<RecordDecl>(RootMatchBindName);
158+
const auto *UnionField =
159+
Result.Nodes.getNodeAs<FieldDecl>(UnionMatchBindName);
160+
const auto *TagField = Result.Nodes.getNodeAs<FieldDecl>(TagMatchBindName);
161+
162+
assert(Root && "Root is missing!");
163+
assert(UnionField && "UnionField is missing!");
164+
assert(TagField && "TagField is missing!");
165+
if (!Root || !UnionField || !TagField)
166+
return;
167+
168+
const auto *UnionDef =
169+
UnionField->getType().getCanonicalType().getTypePtr()->getAsRecordDecl();
170+
const auto *EnumDef = llvm::dyn_cast<EnumDecl>(
171+
TagField->getType().getCanonicalType().getTypePtr()->getAsTagDecl());
172+
173+
assert(UnionDef && "UnionDef is missing!");
174+
assert(EnumDef && "EnumDef is missing!");
175+
if (!UnionDef || !EnumDef)
176+
return;
177+
178+
const std::size_t UnionMemberCount = llvm::range_size(UnionDef->fields());
179+
auto [TagCount, CountingEnumConstantDecl] = getNumberOfEnumValues(EnumDef);
180+
181+
if (UnionMemberCount > TagCount) {
182+
diag(Root->getLocation(),
183+
"tagged union has more data members (%0) than tags (%1)!")
184+
<< UnionMemberCount << TagCount;
185+
} else if (StrictMode && UnionMemberCount < TagCount) {
186+
diag(Root->getLocation(),
187+
"tagged union has fewer data members (%0) than tags (%1)!")
188+
<< UnionMemberCount << TagCount;
189+
}
190+
191+
if (CountingEnumConstantDecl) {
192+
diag(CountingEnumConstantDecl->getLocation(),
193+
"assuming that this constant is just an auxiliary value and not "
194+
"used for indicating a valid union data member",
195+
DiagnosticIDs::Note);
196+
}
197+
}
198+
199+
} // namespace clang::tidy::bugprone
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//===--- TaggedUnionMemberCountCheck.h - clang-tidy -------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_TAGGEDUNIONMEMBERCOUNTCHECK_H
10+
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_TAGGEDUNIONMEMBERCOUNTCHECK_H
11+
12+
#include "../ClangTidyCheck.h"
13+
14+
namespace clang::tidy::bugprone {
15+
16+
/// Gives warnings for tagged unions, where the number of tags is
17+
/// different from the number of data members inside the union.
18+
///
19+
/// For the user-facing documentation see:
20+
/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone/tagged-union-member-count.html
21+
class TaggedUnionMemberCountCheck : public ClangTidyCheck {
22+
public:
23+
TaggedUnionMemberCountCheck(StringRef Name, ClangTidyContext *Context);
24+
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
25+
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
26+
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
27+
28+
private:
29+
const bool StrictMode;
30+
const bool EnableCountingEnumHeuristic;
31+
const std::vector<StringRef> CountingEnumPrefixes;
32+
const std::vector<StringRef> CountingEnumSuffixes;
33+
34+
std::pair<const std::size_t, const EnumConstantDecl *>
35+
getNumberOfEnumValues(const EnumDecl *ED);
36+
bool isCountingEnumLikeName(StringRef Name) const;
37+
};
38+
39+
} // namespace clang::tidy::bugprone
40+
41+
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_TAGGEDUNIONMEMBERCOUNTCHECK_H

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,12 @@ Improvements to clang-tidy
103103
New checks
104104
^^^^^^^^^^
105105

106+
- New :doc:`bugprone-tagged-union-member-count
107+
<clang-tidy/checks/bugprone/tagged-union-member-count>` check.
108+
109+
Gives warnings for tagged unions, where the number of tags is
110+
different from the number of data members inside the union.
111+
106112
New check aliases
107113
^^^^^^^^^^^^^^^^^
108114

0 commit comments

Comments
 (0)