Skip to content

Commit d5f5db9

Browse files
SC llvm teamSC llvm team
authored andcommitted
Merged main:e5de2a2df4f9 into amd-gfx:179d2f9505ff
Local branch amd-gfx 179d2f9 Merged main:d2b8acc10464 into amd-gfx:f8992209d7db Remote branch main e5de2a2 [clang-tidy][NFC] extract options verify to separately function (llvm#120768)
2 parents 179d2f9 + e5de2a2 commit d5f5db9

File tree

116 files changed

+4989
-585
lines changed

Some content is hidden

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

116 files changed

+4989
-585
lines changed

clang-tools-extra/clang-tidy/ClangTidy.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -646,9 +646,9 @@ void exportReplacements(const llvm::StringRef MainFilePath,
646646
YAML << TUD;
647647
}
648648

649-
NamesAndOptions
649+
ChecksAndOptions
650650
getAllChecksAndOptions(bool AllowEnablingAnalyzerAlphaCheckers) {
651-
NamesAndOptions Result;
651+
ChecksAndOptions Result;
652652
ClangTidyOptions Opts;
653653
Opts.Checks = "*";
654654
clang::tidy::ClangTidyContext Context(
@@ -661,7 +661,7 @@ getAllChecksAndOptions(bool AllowEnablingAnalyzerAlphaCheckers) {
661661
}
662662

663663
for (const auto &Factory : Factories)
664-
Result.Names.insert(Factory.getKey());
664+
Result.Checks.insert(Factory.getKey());
665665

666666
#if CLANG_TIDY_ENABLE_STATIC_ANALYZER
667667
SmallString<64> Buffer(AnalyzerCheckNamePrefix);
@@ -670,7 +670,7 @@ getAllChecksAndOptions(bool AllowEnablingAnalyzerAlphaCheckers) {
670670
AllowEnablingAnalyzerAlphaCheckers)) {
671671
Buffer.truncate(DefSize);
672672
Buffer.append(AnalyzerCheck);
673-
Result.Names.insert(Buffer);
673+
Result.Checks.insert(Buffer);
674674
}
675675
for (std::string OptionName : {
676676
#define GET_CHECKER_OPTIONS

clang-tools-extra/clang-tidy/ClangTidy.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,12 @@ class ClangTidyASTConsumerFactory {
5858
std::vector<std::string> getCheckNames(const ClangTidyOptions &Options,
5959
bool AllowEnablingAnalyzerAlphaCheckers);
6060

61-
struct NamesAndOptions {
62-
llvm::StringSet<> Names;
61+
struct ChecksAndOptions {
62+
llvm::StringSet<> Checks;
6363
llvm::StringSet<> Options;
6464
};
6565

66-
NamesAndOptions
66+
ChecksAndOptions
6767
getAllChecksAndOptions(bool AllowEnablingAnalyzerAlphaCheckers = true);
6868

6969
/// Returns the effective check-specific options.

clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,24 @@ static bool verifyFileExtensions(
526526
return AnyInvalid;
527527
}
528528

529+
static bool verifyOptions(const llvm::StringSet<> &ValidOptions,
530+
const ClangTidyOptions::OptionMap &OptionMap,
531+
StringRef Source) {
532+
bool AnyInvalid = false;
533+
for (auto Key : OptionMap.keys()) {
534+
if (ValidOptions.contains(Key))
535+
continue;
536+
AnyInvalid = true;
537+
auto &Output = llvm::WithColor::warning(llvm::errs(), Source)
538+
<< "unknown check option '" << Key << '\'';
539+
llvm::StringRef Closest = closest(Key, ValidOptions);
540+
if (!Closest.empty())
541+
Output << "; did you mean '" << Closest << '\'';
542+
Output << VerifyConfigWarningEnd;
543+
}
544+
return AnyInvalid;
545+
}
546+
529547
static SmallString<256> makeAbsolute(llvm::StringRef Input) {
530548
if (Input.empty())
531549
return {};
@@ -629,29 +647,17 @@ int clangTidyMain(int argc, const char **argv) {
629647
if (VerifyConfig) {
630648
std::vector<ClangTidyOptionsProvider::OptionsSource> RawOptions =
631649
OptionsProvider->getRawOptions(FileName);
632-
NamesAndOptions Valid =
650+
ChecksAndOptions Valid =
633651
getAllChecksAndOptions(AllowEnablingAnalyzerAlphaCheckers);
634652
bool AnyInvalid = false;
635653
for (const auto &[Opts, Source] : RawOptions) {
636654
if (Opts.Checks)
637-
AnyInvalid |= verifyChecks(Valid.Names, *Opts.Checks, Source);
638-
655+
AnyInvalid |= verifyChecks(Valid.Checks, *Opts.Checks, Source);
639656
if (Opts.HeaderFileExtensions && Opts.ImplementationFileExtensions)
640657
AnyInvalid |=
641658
verifyFileExtensions(*Opts.HeaderFileExtensions,
642659
*Opts.ImplementationFileExtensions, Source);
643-
644-
for (auto Key : Opts.CheckOptions.keys()) {
645-
if (Valid.Options.contains(Key))
646-
continue;
647-
AnyInvalid = true;
648-
auto &Output = llvm::WithColor::warning(llvm::errs(), Source)
649-
<< "unknown check option '" << Key << '\'';
650-
llvm::StringRef Closest = closest(Key, Valid.Options);
651-
if (!Closest.empty())
652-
Output << "; did you mean '" << Closest << '\'';
653-
Output << VerifyConfigWarningEnd;
654-
}
660+
AnyInvalid |= verifyOptions(Valid.Options, Opts.CheckOptions, Source);
655661
}
656662
if (AnyInvalid)
657663
return 1;

clang/docs/ReleaseNotes.rst

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,9 @@ New Compiler Flags
445445
- The ``-Warray-compare-cxx26`` warning has been added to warn about array comparison
446446
starting from C++26, this warning is enabled as an error by default.
447447

448+
- clang-cl and clang-dxc now support ``-fdiagnostics-color=[auto|never|always]``
449+
in addition to ``-f[no-]color-diagnostics``.
450+
448451
Deprecated Compiler Flags
449452
-------------------------
450453

@@ -705,6 +708,31 @@ Improvements to Clang's diagnostics
705708
- Fixed a bug where Clang hung on an unsupported optional scope specifier ``::`` when parsing
706709
Objective-C. Clang now emits a diagnostic message instead of hanging.
707710

711+
- The :doc:`ThreadSafetyAnalysis` now supports passing scoped capabilities into functions:
712+
an attribute on the scoped capability parameter indicates both the expected associated capabilities and,
713+
like in the case of attributes on the function declaration itself, their state before and after the call.
714+
715+
.. code-block:: c++
716+
717+
#include "mutex.h"
718+
719+
Mutex mu1, mu2;
720+
int a GUARDED_BY(mu1);
721+
722+
void require(MutexLocker& scope REQUIRES(mu1)) {
723+
scope.Unlock();
724+
a = 0; // Warning! Requires mu1.
725+
scope.Lock();
726+
}
727+
728+
void testParameter() {
729+
MutexLocker scope(&mu1), scope2(&mu2);
730+
require(scope2); // Warning! Mutex managed by 'scope2' is 'mu2' instead of 'mu1'
731+
require(scope); // OK.
732+
scope.Unlock();
733+
require(scope); // Warning! Requires mu1.
734+
}
735+
708736
Improvements to Clang's time-trace
709737
----------------------------------
710738

clang/docs/ThreadSafetyAnalysis.rst

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,13 @@ REQUIRES(...), REQUIRES_SHARED(...)
187187

188188
*Previously*: ``EXCLUSIVE_LOCKS_REQUIRED``, ``SHARED_LOCKS_REQUIRED``
189189

190-
``REQUIRES`` is an attribute on functions or methods, which
190+
``REQUIRES`` is an attribute on functions, methods or function parameters of
191+
reference to :ref:`scoped_capability`-annotated type, which
191192
declares that the calling thread must have exclusive access to the given
192193
capabilities. More than one capability may be specified. The capabilities
193194
must be held on entry to the function, *and must still be held on exit*.
195+
Additionally, if the attribute is on a function parameter, it declares that
196+
the scoped capability manages the specified capabilities in the given order.
194197

195198
``REQUIRES_SHARED`` is similar, but requires only shared access.
196199

@@ -211,17 +214,34 @@ must be held on entry to the function, *and must still be held on exit*.
211214
mu1.Unlock();
212215
}
213216

217+
void require(MutexLocker& scope REQUIRES(mu1)) {
218+
scope.Unlock();
219+
a = 0; // Warning! Requires mu1.
220+
scope.Lock();
221+
}
222+
223+
void testParameter() {
224+
MutexLocker scope(&mu1), scope2(&mu2);
225+
require(scope2); // Warning! Mutex managed by 'scope2' is 'mu2' instead of 'mu1'
226+
require(scope); // OK.
227+
scope.Unlock();
228+
require(scope); // Warning! Requires mu1.
229+
}
230+
214231

215232
ACQUIRE(...), ACQUIRE_SHARED(...), RELEASE(...), RELEASE_SHARED(...), RELEASE_GENERIC(...)
216233
------------------------------------------------------------------------------------------
217234

218235
*Previously*: ``EXCLUSIVE_LOCK_FUNCTION``, ``SHARED_LOCK_FUNCTION``,
219236
``UNLOCK_FUNCTION``
220237

221-
``ACQUIRE`` and ``ACQUIRE_SHARED`` are attributes on functions or methods
222-
declaring that the function acquires a capability, but does not release it.
238+
``ACQUIRE`` and ``ACQUIRE_SHARED`` are attributes on functions, methods
239+
or function parameters of reference to :ref:`scoped_capability`-annotated type,
240+
which declare that the function acquires a capability, but does not release it.
223241
The given capability must not be held on entry, and will be held on exit
224242
(exclusively for ``ACQUIRE``, shared for ``ACQUIRE_SHARED``).
243+
Additionally, if the attribute is on a function parameter, it declares that
244+
the scoped capability manages the specified capabilities in the given order.
225245

226246
``RELEASE``, ``RELEASE_SHARED``, and ``RELEASE_GENERIC`` declare that the
227247
function releases the given capability. The capability must be held on entry
@@ -249,6 +269,14 @@ shared for ``RELEASE_GENERIC``), and will no longer be held on exit.
249269
myObject.doSomething(); // Warning, mu is not locked.
250270
}
251271

272+
void release(MutexLocker& scope RELEASE(mu)) {
273+
} // Warning! Need to unlock mu.
274+
275+
void testParameter() {
276+
MutexLocker scope(&mu);
277+
release(scope);
278+
}
279+
252280
If no argument is passed to ``ACQUIRE`` or ``RELEASE``, then the argument is
253281
assumed to be ``this``, and the analysis will not check the body of the
254282
function. This pattern is intended for use by classes which hide locking
@@ -283,10 +311,13 @@ EXCLUDES(...)
283311

284312
*Previously*: ``LOCKS_EXCLUDED``
285313

286-
``EXCLUDES`` is an attribute on functions or methods, which declares that
314+
``EXCLUDES`` is an attribute on functions, methods or function parameters
315+
of reference to :ref:`scoped_capability`-annotated type, which declares that
287316
the caller must *not* hold the given capabilities. This annotation is
288317
used to prevent deadlock. Many mutex implementations are not re-entrant, so
289318
deadlock can occur if the function acquires the mutex a second time.
319+
Additionally, if the attribute is on a function parameter, it declares that
320+
the scoped capability manages the specified capabilities in the given order.
290321

291322
.. code-block:: c++
292323

@@ -305,6 +336,16 @@ deadlock can occur if the function acquires the mutex a second time.
305336
mu.Unlock();
306337
}
307338

339+
void exclude(MutexLocker& scope LOCKS_EXCLUDED(mu)) {
340+
scope.Unlock(); // Warning! mu is not locked.
341+
scope.Lock();
342+
} // Warning! mu still held at the end of function.
343+
344+
void testParameter() {
345+
MutexLocker scope(&mu);
346+
exclude(scope); // Warning, mu is held.
347+
}
348+
308349
Unlike ``REQUIRES``, ``EXCLUDES`` is optional. The analysis will not issue a
309350
warning if the attribute is missing, which can lead to false negatives in some
310351
cases. This issue is discussed further in :ref:`negative`.
@@ -393,6 +434,7 @@ class can be used as a capability. The string argument specifies the kind of
393434
capability in error messages, e.g. ``"mutex"``. See the ``Container`` example
394435
given above, or the ``Mutex`` class in :ref:`mutexheader`.
395436

437+
.. _scoped_capability:
396438

397439
SCOPED_CAPABILITY
398440
-----------------

clang/include/clang/AST/Stmt.h

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,16 +109,7 @@ class alignas(void *) Stmt {
109109

110110
//===--- Statement bitfields classes ---===//
111111

112-
enum { NumStmtBits = 9 };
113-
114-
#define STMT(CLASS, PARENT)
115-
#define STMT_RANGE(BASE, FIRST, LAST)
116-
#define LAST_STMT_RANGE(BASE, FIRST, LAST) \
117-
static_assert(llvm::isUInt<NumStmtBits>(StmtClass::LAST##Class), \
118-
"The number of 'StmtClass'es is strictly bound " \
119-
"by a bitfield of width NumStmtBits");
120-
#define ABSTRACT_STMT(STMT)
121-
#include "clang/AST/StmtNodes.inc"
112+
#define NumStmtBits 9
122113

123114
class StmtBitfields {
124115
friend class ASTStmtReader;

clang/include/clang/Analysis/Analyses/ThreadSafety.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,42 @@ class ThreadSafetyHandler {
223223
virtual void handleFunExcludesLock(StringRef Kind, Name FunName,
224224
Name LockName, SourceLocation Loc) {}
225225

226+
/// Warn when an actual underlying mutex of a scoped lockable does not match
227+
/// the expected.
228+
/// \param Loc -- The location of the call expression.
229+
/// \param DLoc -- The location of the function declaration.
230+
/// \param ScopeName -- The name of the scope passed to the function.
231+
/// \param Kind -- The kind of the expected mutex.
232+
/// \param Expected -- The name of the expected mutex.
233+
/// \param Actual -- The name of the actual mutex.
234+
virtual void handleUnmatchedUnderlyingMutexes(SourceLocation Loc,
235+
SourceLocation DLoc,
236+
Name ScopeName, StringRef Kind,
237+
Name Expected, Name Actual) {}
238+
239+
/// Warn when we get fewer underlying mutexes than expected.
240+
/// \param Loc -- The location of the call expression.
241+
/// \param DLoc -- The location of the function declaration.
242+
/// \param ScopeName -- The name of the scope passed to the function.
243+
/// \param Kind -- The kind of the expected mutex.
244+
/// \param Expected -- The name of the expected mutex.
245+
virtual void handleExpectMoreUnderlyingMutexes(SourceLocation Loc,
246+
SourceLocation DLoc,
247+
Name ScopeName, StringRef Kind,
248+
Name Expected) {}
249+
250+
/// Warn when we get more underlying mutexes than expected.
251+
/// \param Loc -- The location of the call expression.
252+
/// \param DLoc -- The location of the function declaration.
253+
/// \param ScopeName -- The name of the scope passed to the function.
254+
/// \param Kind -- The kind of the actual mutex.
255+
/// \param Actual -- The name of the actual mutex.
256+
virtual void handleExpectFewerUnderlyingMutexes(SourceLocation Loc,
257+
SourceLocation DLoc,
258+
Name ScopeName,
259+
StringRef Kind, Name Actual) {
260+
}
261+
226262
/// Warn that L1 cannot be acquired before L2.
227263
virtual void handleLockAcquiredBefore(StringRef Kind, Name L1Name,
228264
Name L2Name, SourceLocation Loc) {}

clang/include/clang/Basic/Attr.td

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3763,7 +3763,7 @@ def AcquireCapability : InheritableAttr {
37633763
Clang<"acquire_shared_capability", 0>,
37643764
GNU<"exclusive_lock_function">,
37653765
GNU<"shared_lock_function">];
3766-
let Subjects = SubjectList<[Function]>;
3766+
let Subjects = SubjectList<[Function, ParmVar]>;
37673767
let LateParsed = LateAttrParseStandard;
37683768
let TemplateDependent = 1;
37693769
let ParseArgumentsAsUnevaluated = 1;
@@ -3795,7 +3795,7 @@ def ReleaseCapability : InheritableAttr {
37953795
Clang<"release_shared_capability", 0>,
37963796
Clang<"release_generic_capability", 0>,
37973797
Clang<"unlock_function", 0>];
3798-
let Subjects = SubjectList<[Function]>;
3798+
let Subjects = SubjectList<[Function, ParmVar]>;
37993799
let LateParsed = LateAttrParseStandard;
38003800
let TemplateDependent = 1;
38013801
let ParseArgumentsAsUnevaluated = 1;
@@ -3819,7 +3819,7 @@ def RequiresCapability : InheritableAttr {
38193819
let TemplateDependent = 1;
38203820
let ParseArgumentsAsUnevaluated = 1;
38213821
let InheritEvenIfAlreadyPresent = 1;
3822-
let Subjects = SubjectList<[Function]>;
3822+
let Subjects = SubjectList<[Function, ParmVar]>;
38233823
let Accessors = [Accessor<"isShared", [Clang<"requires_shared_capability", 0>,
38243824
Clang<"shared_locks_required", 0>]>];
38253825
let Documentation = [Undocumented];
@@ -3941,7 +3941,7 @@ def LocksExcluded : InheritableAttr {
39413941
let TemplateDependent = 1;
39423942
let ParseArgumentsAsUnevaluated = 1;
39433943
let InheritEvenIfAlreadyPresent = 1;
3944-
let Subjects = SubjectList<[Function]>;
3944+
let Subjects = SubjectList<[Function, ParmVar]>;
39453945
let Documentation = [Undocumented];
39463946
}
39473947

clang/include/clang/Basic/BuiltinsHexagon.def

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
1818
#endif
1919

20+
#pragma push_macro("V75")
21+
#define V75 "v75"
2022
#pragma push_macro("V73")
21-
#define V73 "v73"
23+
#define V73 "v73|" V75
2224
#pragma push_macro("V71")
2325
#define V71 "v71|" V73
2426
#pragma push_macro("V69")
@@ -40,8 +42,10 @@
4042
#pragma push_macro("V5")
4143
#define V5 "v5|" V55
4244

45+
#pragma push_macro("HVXV75")
46+
#define HVXV75 "hvxv75"
4347
#pragma push_macro("HVXV73")
44-
#define HVXV73 "hvxv73"
48+
#define HVXV73 "hvxv73|" HVXV75
4549
#pragma push_macro("HVXV71")
4650
#define HVXV71 "hvxv71|" HVXV73
4751
#pragma push_macro("HVXV69")
@@ -143,6 +147,7 @@ TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_acc_128B,"V64iV64iV32iLLi","", "
143147
#pragma pop_macro("HVXV69")
144148
#pragma pop_macro("HVXV71")
145149
#pragma pop_macro("HVXV73")
150+
#pragma pop_macro("HVXV75")
146151

147152
#pragma pop_macro("V5")
148153
#pragma pop_macro("V55")
@@ -155,6 +160,7 @@ TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_acc_128B,"V64iV64iV32iLLi","", "
155160
#pragma pop_macro("V69")
156161
#pragma pop_macro("V71")
157162
#pragma pop_macro("V73")
163+
#pragma pop_macro("V75")
158164

159165
#undef BUILTIN
160166
#undef TARGET_BUILTIN

0 commit comments

Comments
 (0)