Skip to content

Commit 844d68f

Browse files
authored
Merge branch 'main' into atomicrmw-vector-operand
2 parents a169d00 + df3f291 commit 844d68f

File tree

344 files changed

+19080
-17356
lines changed

Some content is hidden

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

344 files changed

+19080
-17356
lines changed

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

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ AST_MATCHER_P(DeducedTemplateSpecializationType, refsToTemplatedDecl,
2525
return false;
2626
}
2727

28+
AST_MATCHER_P(Type, asTagDecl, clang::ast_matchers::internal::Matcher<TagDecl>,
29+
DeclMatcher) {
30+
if (const TagDecl *ND = Node.getAsTagDecl())
31+
return DeclMatcher.matches(*ND, Finder, Builder);
32+
return false;
33+
}
34+
2835
} // namespace
2936

3037
// A function that helps to tell whether a TargetDecl in a UsingDecl will be
@@ -61,7 +68,8 @@ void UnusedUsingDeclsCheck::registerMatchers(MatchFinder *Finder) {
6168
Finder->addMatcher(userDefinedLiteral().bind("used"), this);
6269
Finder->addMatcher(
6370
loc(elaboratedType(unless(hasQualifier(nestedNameSpecifier())),
64-
hasUnqualifiedDesugaredType(type().bind("usedType")))),
71+
hasUnqualifiedDesugaredType(
72+
type(asTagDecl(tagDecl().bind("used")))))),
6573
this);
6674
// Cases where we can identify the UsingShadowDecl directly, rather than
6775
// just its target.
@@ -139,12 +147,6 @@ void UnusedUsingDeclsCheck::check(const MatchFinder::MatchResult &Result) {
139147
return;
140148
}
141149

142-
if (const auto *T = Result.Nodes.getNodeAs<Type>("usedType")) {
143-
if (const auto *ND = T->getAsTagDecl())
144-
RemoveNamedDecl(ND);
145-
return;
146-
}
147-
148150
if (const auto *UsedShadow =
149151
Result.Nodes.getNodeAs<UsingShadowDecl>("usedShadow")) {
150152
removeFromFoundDecls(UsedShadow->getTargetDecl());

clang-tools-extra/clangd/index/SymbolCollector.cpp

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "llvm/ADT/DenseMap.h"
4242
#include "llvm/ADT/SmallVector.h"
4343
#include "llvm/ADT/StringRef.h"
44+
#include "llvm/Support/Casting.h"
4445
#include "llvm/Support/ErrorHandling.h"
4546
#include "llvm/Support/FileSystem.h"
4647
#include "llvm/Support/Path.h"
@@ -75,18 +76,62 @@ bool isPrivateProtoDecl(const NamedDecl &ND) {
7576
if (ND.getIdentifier() == nullptr)
7677
return false;
7778
auto Name = ND.getIdentifier()->getName();
78-
if (!Name.contains('_'))
79-
return false;
80-
// Nested proto entities (e.g. Message::Nested) have top-level decls
81-
// that shouldn't be used (Message_Nested). Ignore them completely.
82-
// The nested entities are dangling type aliases, we may want to reconsider
83-
// including them in the future.
84-
// For enum constants, SOME_ENUM_CONSTANT is not private and should be
85-
// indexed. Outer_INNER is private. This heuristic relies on naming style, it
86-
// will include OUTER_INNER and exclude some_enum_constant.
87-
// FIXME: the heuristic relies on naming style (i.e. no underscore in
88-
// user-defined names) and can be improved.
89-
return (ND.getKind() != Decl::EnumConstant) || llvm::any_of(Name, islower);
79+
// There are some internal helpers like _internal_set_foo();
80+
if (Name.contains("_internal_"))
81+
return true;
82+
83+
// https://protobuf.dev/reference/cpp/cpp-generated/#nested-types
84+
// Nested entities (messages/enums) has two names, one at the top-level scope,
85+
// with a mangled name created by prepending all the outer types. These names
86+
// are almost never preferred by the developers, so exclude them from index.
87+
// e.g.
88+
// message Foo {
89+
// message Bar {}
90+
// enum E { A }
91+
// }
92+
//
93+
// yields:
94+
// class Foo_Bar {};
95+
// enum Foo_E { Foo_E_A };
96+
// class Foo {
97+
// using Bar = Foo_Bar;
98+
// static constexpr Foo_E A = Foo_E_A;
99+
// };
100+
101+
// We get rid of Foo_Bar and Foo_E by discarding any top-level entries with
102+
// `_` in the name. This relies on original message/enum not having `_` in the
103+
// name. Hence might go wrong in certain cases.
104+
if (ND.getDeclContext()->isNamespace()) {
105+
// Strip off some known public suffix helpers for enums, rest of the helpers
106+
// are generated inside record decls so we don't care.
107+
// https://protobuf.dev/reference/cpp/cpp-generated/#enum
108+
Name.consume_back("_descriptor");
109+
Name.consume_back("_IsValid");
110+
Name.consume_back("_Name");
111+
Name.consume_back("_Parse");
112+
Name.consume_back("_MIN");
113+
Name.consume_back("_MAX");
114+
Name.consume_back("_ARRAYSIZE");
115+
return Name.contains('_');
116+
}
117+
118+
// EnumConstantDecls need some special attention, despite being nested in a
119+
// TagDecl, they might still have mangled names. We filter those by checking
120+
// if it has parent's name as a prefix.
121+
// This might go wrong if a nested entity has a name that starts with parent's
122+
// name, e.g: enum Foo { Foo_X }.
123+
if (llvm::isa<EnumConstantDecl>(&ND)) {
124+
auto *DC = llvm::cast<EnumDecl>(ND.getDeclContext());
125+
if (!DC || !DC->getIdentifier())
126+
return false;
127+
auto CtxName = DC->getIdentifier()->getName();
128+
return !CtxName.empty() && Name.consume_front(CtxName) &&
129+
Name.consume_front("_");
130+
}
131+
132+
// Now we're only left with fields/methods without an `_internal_` in the
133+
// name, they're intended for public use.
134+
return false;
90135
}
91136

92137
// We only collect #include paths for symbols that are suitable for global code

clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -201,19 +201,63 @@ TEST_F(ShouldCollectSymbolTest, NoPrivateProtoSymbol) {
201201
build(
202202
R"(// Generated by the protocol buffer compiler. DO NOT EDIT!
203203
namespace nx {
204-
class Top_Level {};
205-
class TopLevel {};
206-
enum Kind {
207-
KIND_OK,
208-
Kind_Not_Ok,
204+
enum Outer_Enum : int {
205+
Outer_Enum_KIND1,
206+
Outer_Enum_Kind_2,
209207
};
208+
bool Outer_Enum_IsValid(int);
209+
210+
class Outer_Inner {};
211+
class Outer {
212+
using Inner = Outer_Inner;
213+
using Enum = Outer_Enum;
214+
static constexpr Enum KIND1 = Outer_Enum_KIND1;
215+
static constexpr Enum Kind_2 = Outer_Enum_Kind_2;
216+
static bool Enum_IsValid(int);
217+
int &x();
218+
void set_x();
219+
void _internal_set_x();
220+
221+
int &Outer_y();
222+
};
223+
enum Foo {
224+
FOO_VAL1,
225+
Foo_VAL2,
226+
};
227+
bool Foo_IsValid(int);
210228
})");
211-
EXPECT_TRUE(shouldCollect("nx::TopLevel"));
212-
EXPECT_TRUE(shouldCollect("nx::Kind::KIND_OK"));
213-
EXPECT_TRUE(shouldCollect("nx::Kind"));
214229

215-
EXPECT_FALSE(shouldCollect("nx::Top_Level"));
216-
EXPECT_FALSE(shouldCollect("nx::Kind::Kind_Not_Ok"));
230+
// Make sure all the mangled names for Outer::Enum is discarded.
231+
EXPECT_FALSE(shouldCollect("nx::Outer_Enum"));
232+
EXPECT_FALSE(shouldCollect("nx::Outer_Enum_KIND1"));
233+
EXPECT_FALSE(shouldCollect("nx::Outer_Enum_Kind_2"));
234+
EXPECT_FALSE(shouldCollect("nx::Outer_Enum_IsValid"));
235+
// But nested aliases are preserved.
236+
EXPECT_TRUE(shouldCollect("nx::Outer::Enum"));
237+
EXPECT_TRUE(shouldCollect("nx::Outer::KIND1"));
238+
EXPECT_TRUE(shouldCollect("nx::Outer::Kind_2"));
239+
EXPECT_TRUE(shouldCollect("nx::Outer::Enum_IsValid"));
240+
241+
// Check for Outer::Inner.
242+
EXPECT_FALSE(shouldCollect("nx::Outer_Inner"));
243+
EXPECT_TRUE(shouldCollect("nx::Outer"));
244+
EXPECT_TRUE(shouldCollect("nx::Outer::Inner"));
245+
246+
// Make sure field related information is preserved, unless it's explicitly
247+
// marked with `_internal_`.
248+
EXPECT_TRUE(shouldCollect("nx::Outer::x"));
249+
EXPECT_TRUE(shouldCollect("nx::Outer::set_x"));
250+
EXPECT_FALSE(shouldCollect("nx::Outer::_internal_set_x"));
251+
EXPECT_TRUE(shouldCollect("nx::Outer::Outer_y"));
252+
253+
// Handling of a top-level enum
254+
EXPECT_TRUE(shouldCollect("nx::Foo::FOO_VAL1"));
255+
EXPECT_TRUE(shouldCollect("nx::FOO_VAL1"));
256+
EXPECT_TRUE(shouldCollect("nx::Foo_IsValid"));
257+
// Our heuristic goes wrong here, if the user has a nested name that starts
258+
// with parent's name.
259+
EXPECT_FALSE(shouldCollect("nx::Foo::Foo_VAL2"));
260+
EXPECT_FALSE(shouldCollect("nx::Foo_VAL2"));
217261
}
218262

219263
TEST_F(ShouldCollectSymbolTest, DoubleCheckProtoHeaderComment) {

clang/docs/RealtimeSanitizer.rst

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,76 @@ non-zero exit code.
8484
#14 0x0001958960dc (<unknown module>)
8585
#15 0x2f557ffffffffffc (<unknown module>)
8686
87+
Run-time flags
88+
--------------
89+
90+
RealtimeSanitizer supports a number of run-time flags, which can be specified in the ``RTSAN_OPTIONS`` environment variable:
91+
92+
.. code-block:: console
93+
94+
% RTSAN_OPTIONS=option_1=true:path_option_2="/some/file.txt" ./a.out
95+
...
96+
97+
Or at compile-time by providing the symbol ``__rtsan_default_options``:
98+
99+
.. code-block:: c
100+
101+
__attribute__((__visibility__("default")))
102+
extern "C" const char *__rtsan_default_options() {
103+
return "symbolize=false:abort_on_error=0:log_to_syslog=0";
104+
}
105+
106+
You can see all sanitizer options (some of which are unsupported) by using the ``help`` flag:
107+
108+
.. code-block:: console
109+
110+
% RTSAN_OPTIONS=help=true ./a.out
111+
112+
A **partial** list of flags RealtimeSanitizer respects:
113+
114+
.. list-table:: Run-time Flags
115+
:widths: 20 10 10 70
116+
:header-rows: 1
117+
118+
* - Flag name
119+
- Default value
120+
- Type
121+
- Short description
122+
* - ``halt_on_error``
123+
- ``true``
124+
- boolean
125+
- Exit after first reported error. If false (continue after a detected error), deduplicates error stacks so errors appear only once.
126+
* - ``print_stats_on_exit``
127+
- ``false``
128+
- boolean
129+
- Print stats on exit. Includes total and unique errors.
130+
* - ``color``
131+
- ``"auto"``
132+
- string
133+
- Colorize reports: (always|never|auto).
134+
* - ``fast_unwind_on_fatal``
135+
- ``false``
136+
- boolean
137+
- If available, use the fast frame-pointer-based unwinder on detected errors. If true, ensure the code under test has been compiled with frame pointers with ``-fno-omit-frame-pointers`` or similar.
138+
* - ``abort_on_error``
139+
- OS dependent
140+
- boolean
141+
- If true, the tool calls abort() instead of _exit() after printing the error report. On some OSes (OSX, for exmple) this is beneficial because a better stack trace is emitted on crash.
142+
* - ``symbolize``
143+
- ``true``
144+
- boolean
145+
- If set, use the symbolizer to turn virtual addresses to file/line locations. If false, can greatly speed up the error reporting.
146+
147+
148+
Some issues with flags can be debugged using the ``verbosity=$NUM`` flag:
149+
150+
.. code-block:: console
151+
152+
% RTSAN_OPTIONS=verbosity=1:misspelled_flag=true ./a.out
153+
WARNING: found 1 unrecognized flag(s):
154+
misspelled_flag
155+
...
156+
87157
Disabling
88158
---------
89159

clang/docs/ReleaseNotes.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,13 @@ X86 Support
511511
* Supported MINMAX intrinsics of ``*_(mask(z)))_minmax(ne)_p[s|d|h|bh]`` and
512512
``*_(mask(z)))_minmax_s[s|d|h]``.
513513

514+
- The following bit manipulation intrinsics can now be used in constant expressions:
515+
all lzcnt intrinsics in lzcntintrin.h
516+
all bextr intrinsics in bmiintrin.h
517+
all tzcnt intrinsics in bmiintrin.h
518+
all bzhi intrinsics in bmi2intrin.h
519+
all intrinsics in tbmintrin.h
520+
514521
Arm and AArch64 Support
515522
^^^^^^^^^^^^^^^^^^^^^^^
516523

clang/include/clang/Basic/BuiltinsX86.def

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -551,16 +551,16 @@ TARGET_BUILTIN(__builtin_ia32_rdseed16_step, "UiUs*", "n", "rdseed")
551551
TARGET_BUILTIN(__builtin_ia32_rdseed32_step, "UiUi*", "n", "rdseed")
552552

553553
// LZCNT
554-
TARGET_BUILTIN(__builtin_ia32_lzcnt_u16, "UsUs", "nc", "lzcnt")
555-
TARGET_BUILTIN(__builtin_ia32_lzcnt_u32, "UiUi", "nc", "lzcnt")
554+
TARGET_BUILTIN(__builtin_ia32_lzcnt_u16, "UsUs", "ncE", "lzcnt")
555+
TARGET_BUILTIN(__builtin_ia32_lzcnt_u32, "UiUi", "ncE", "lzcnt")
556556

557557
// BMI
558558
TARGET_BUILTIN(__builtin_ia32_bextr_u32, "UiUiUi", "ncE", "bmi")
559-
TARGET_BUILTIN(__builtin_ia32_tzcnt_u16, "UsUs", "nc", "")
560-
TARGET_BUILTIN(__builtin_ia32_tzcnt_u32, "UiUi", "nc", "")
559+
TARGET_BUILTIN(__builtin_ia32_tzcnt_u16, "UsUs", "ncE", "")
560+
TARGET_BUILTIN(__builtin_ia32_tzcnt_u32, "UiUi", "ncE", "")
561561

562562
// BMI2
563-
TARGET_BUILTIN(__builtin_ia32_bzhi_si, "UiUiUi", "nc", "bmi2")
563+
TARGET_BUILTIN(__builtin_ia32_bzhi_si, "UiUiUi", "ncE", "bmi2")
564564
TARGET_BUILTIN(__builtin_ia32_pdep_si, "UiUiUi", "nc", "bmi2")
565565
TARGET_BUILTIN(__builtin_ia32_pext_si, "UiUiUi", "nc", "bmi2")
566566

clang/include/clang/Basic/BuiltinsX86_64.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,10 @@ TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcUOiUOiUOi*", "n", "")
7070
TARGET_BUILTIN(__builtin_ia32_subborrow_u64, "UcUcUOiUOiUOi*", "n", "")
7171
TARGET_BUILTIN(__builtin_ia32_rdrand64_step, "UiUOi*", "n", "rdrnd")
7272
TARGET_BUILTIN(__builtin_ia32_rdseed64_step, "UiUOi*", "n", "rdseed")
73-
TARGET_BUILTIN(__builtin_ia32_lzcnt_u64, "UOiUOi", "nc", "lzcnt")
73+
TARGET_BUILTIN(__builtin_ia32_lzcnt_u64, "UOiUOi", "ncE", "lzcnt")
7474
TARGET_BUILTIN(__builtin_ia32_bextr_u64, "UOiUOiUOi", "ncE", "bmi")
75-
TARGET_BUILTIN(__builtin_ia32_tzcnt_u64, "UOiUOi", "nc", "")
76-
TARGET_BUILTIN(__builtin_ia32_bzhi_di, "UOiUOiUOi", "nc", "bmi2")
75+
TARGET_BUILTIN(__builtin_ia32_tzcnt_u64, "UOiUOi", "ncE", "")
76+
TARGET_BUILTIN(__builtin_ia32_bzhi_di, "UOiUOiUOi", "ncE", "bmi2")
7777
TARGET_BUILTIN(__builtin_ia32_pdep_di, "UOiUOiUOi", "nc", "bmi2")
7878
TARGET_BUILTIN(__builtin_ia32_pext_di, "UOiUOiUOi", "nc", "bmi2")
7979
TARGET_BUILTIN(__builtin_ia32_bextri_u64, "UOiUOiIUOi", "ncE", "tbm")

clang/include/clang/Basic/arm_sme.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,4 +817,9 @@ multiclass ZAReadzArray<string vg_num>{
817817

818818
defm SVREADZ_VG2 : ZAReadzArray<"2">;
819819
defm SVREADZ_VG4 : ZAReadzArray<"4">;
820+
821+
let SMETargetGuard = "sme2,sme-lutv2" in {
822+
def SVLUTI4_ZT_X4 : SInst<"svluti4_zt_{d}_x4", "4i2.u", "cUc", MergeNone, "aarch64_sme_luti4_zt_x4", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>]>;
823+
}
824+
820825
} // let SVETargetGuard = InvalidMode

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "clang/AST/OSLog.h"
1515
#include "clang/AST/RecordLayout.h"
1616
#include "clang/Basic/Builtins.h"
17+
#include "clang/Basic/TargetBuiltins.h"
1718
#include "clang/Basic/TargetInfo.h"
1819
#include "llvm/Support/SipHash.h"
1920

@@ -1152,6 +1153,33 @@ static bool interp__builtin_is_aligned_up_down(InterpState &S, CodePtr OpPC,
11521153
return false;
11531154
}
11541155

1156+
static bool interp__builtin_ia32_bextr(InterpState &S, CodePtr OpPC,
1157+
const InterpFrame *Frame,
1158+
const Function *Func,
1159+
const CallExpr *Call) {
1160+
PrimType ValT = *S.Ctx.classify(Call->getArg(0));
1161+
PrimType IndexT = *S.Ctx.classify(Call->getArg(1));
1162+
APSInt Val = peekToAPSInt(S.Stk, ValT,
1163+
align(primSize(ValT)) + align(primSize(IndexT)));
1164+
APSInt Index = peekToAPSInt(S.Stk, IndexT);
1165+
1166+
unsigned BitWidth = Val.getBitWidth();
1167+
uint64_t Shift = Index.extractBitsAsZExtValue(8, 0);
1168+
uint64_t Length = Index.extractBitsAsZExtValue(8, 8);
1169+
Length = Length > BitWidth ? BitWidth : Length;
1170+
1171+
// Handle out of bounds cases.
1172+
if (Length == 0 || Shift >= BitWidth) {
1173+
pushInteger(S, 0, Call->getType());
1174+
return true;
1175+
}
1176+
1177+
uint64_t Result = Val.getZExtValue() >> Shift;
1178+
Result &= llvm::maskTrailingOnes<uint64_t>(Length);
1179+
pushInteger(S, Result, Call->getType());
1180+
return true;
1181+
}
1182+
11551183
static bool interp__builtin_os_log_format_buffer_size(InterpState &S,
11561184
CodePtr OpPC,
11571185
const InterpFrame *Frame,
@@ -1737,6 +1765,14 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
17371765
return false;
17381766
break;
17391767

1768+
case clang::X86::BI__builtin_ia32_bextr_u32:
1769+
case clang::X86::BI__builtin_ia32_bextr_u64:
1770+
case clang::X86::BI__builtin_ia32_bextri_u32:
1771+
case clang::X86::BI__builtin_ia32_bextri_u64:
1772+
if (!interp__builtin_ia32_bextr(S, OpPC, Frame, F, Call))
1773+
return false;
1774+
break;
1775+
17401776
case Builtin::BI__builtin_os_log_format_buffer_size:
17411777
if (!interp__builtin_os_log_format_buffer_size(S, OpPC, Frame, F, Call))
17421778
return false;

0 commit comments

Comments
 (0)