Skip to content

Integrate LLVM#7

Closed
WuXintong123 wants to merge 3354 commits into
mainfrom
wip/save-20260510-004023
Closed

Integrate LLVM#7
WuXintong123 wants to merge 3354 commits into
mainfrom
wip/save-20260510-004023

Conversation

@WuXintong123

Copy link
Copy Markdown
Collaborator

No description provided.

vrpT14s and others added 30 commits May 7, 2026 08:36
Update hanging reference of ParseBinaryExpression to
ParseRHSOfBinaryExpression

Fixes llvm#195747
The SPIR-V target support for UBSan Minimal Runtime is added to provide
basic undefined behavior detection capabilities for SPIR-V based
devices.

Currently, only the `spirv64` target is supported.
)

Reverts llvm#194304, as it caused failed asserts - see that
PR for reproducers.
These are suspected to have caused instability in CI testing
llvm#191372.

This reverts commits 4c22591 and
d7fac0f (llvm#179470 and llvm#177572).

The second change could technically stay in, but it was using the first
change to fix a bug in lldb-server. So I think it's better to revert
both so we don't mistakenly think the bug is still fixed.
This was only necessary for ASan container annotations for short
strings. Remove it now that we do not support ASan container annotations
on short strings to:
1. Not suppress Asan on other violations, e.g. std::string::size() on
dead object.
2. Make the code a bit more clean.

Short string annotations were removed in
llvm#194208.
)

shouldRunCompletion() checked the Expected<> from positionToOffset() via
operator!() but never consumed the error with takeError(). This caused
an assertion failure when a TriggerCharacter completion request had a
position beyond the document bounds.

LLM was used to generate the unit test.

Fixes: llvm#196072
These functions are only used inside assert statements, so mark them
[[maybe_unused]] to prevent -Wunused-function when they are used in a
non-asserts build.
…6278)

Added the Linux byteswap.h header providing bswap_16, bswap_32, and
bswap_64 as macros expanding to __builtin_bswap{16,32,64}. These are
always inlined by the compiler to single instructions.

Follows the existing endian.h / endian-macros.h pattern.

Assisted-by: Automated tooling, human reviewed.
…lvm#196101)

Summary:
This is currently rejected in two places, the toolchain creation and the
target itself. For the target we just permit it in the same way we alloe
things like 'amdhsa'. For the driver, the current handling just assumed
everything with 'vulkan' was HLSL. This shouldn't be true so we check
the source file type, and only push through actual HLSL files.

This is intended to more canonically support the 'CLSPV' target that
google has.
…vm#195150)

`isDefinedAsZero` was vulnerable to a classic "passing an unchecked
`Operation *` to `TypeSwitch`".
…bank-select. (llvm#194778)

This removes the fconstant_to_constant post-legalizer lowering combine,
moving it to where it belongs in reg bank select. The result should be
mostly be no change in generated code.
Summary:
Adds a macro like for `__LINUX__` or `__WIN32`. The intention here is to
let code differentiate between vulkan variants or not.
…mpoundLiteralExpr`s (llvm#195675)

Like the current interpreter does.
…vm#195857)

Currently PointerMayBeCaptured/FindEarliestEscape accept a
ReturnCaptures argument to determine whether returning the pointer
should be considered a capture. If you want to do a capture check for
both cases, you have to invoke the capture tracking API twice.

This PR instead changes the low level APIs to return a pair of capture
components, one where returns are considered non-capturing, and one
where they are considered capturing.

This is for use by llvm#193939,
where AA wants both our usual captures-before (ignoring returns)
reasoning, and captures-anywhere (including returns). This will allow us
to do this in one (cached) query.
…vm#196301)

`LD64B` and `ST64B` are defined as follows[1]:
```
  LD64B <Xt>, [<Xn|SP> {,#0}]
```

but they're missing the form that allows a zero immediate offset,
for example:
```
  ld64b x2, [x13, #0]
  st64b x16, [x13, #0]
```

Add support for zero immediate offsets for these instructions.

[1] https://developer.arm.com/documentation/ddi0602/2022-09/Base-Instructions/LD64B--Single-copy-Atomic-64-byte-Load-
This was phabricator specific which has not been around for a while now.
…vm#182501)

The LLVM build documentation says that setting CMAKE_OSX_SYSROOT should
be sufficient to correctly configure the sysroot, however this flag was
not forwarded to the build of runtimes: leading to failures in flang-rt
tests. https://llvm.org/docs/CMake.html#apple-osx

It is not safe to forward this flag in general because the runtime might
be cross-compiled. In this case I have tried to do this only for native
builds. My intention here is not to make the build more complex than
currently documented.
…#194991)

Reduce the cost of i8 vector insert and extract elements to avoid
scalarization in VectorCombine.

It is impossible to know during VectorCombine if an extract element will
require additional instructions or be free. There is a lot of additional context
needed to make that assessment. For example, what instructions are using
the extract elements or what other extract element index values occur. This
patch chooses some cases that likely do not require instructions, which
reduces the overall cost and avoids scalarization. Because of this chance, there
are SLP vectorization opportunities that are missed. In general, those missed
SLP vectorization cases require scalarization during code generation, and the
compiler ends up generating the same code with and without SLP vectorization.
EmitCMP folds `c CMP rhs` into `rhs CMP' c+1` for four condition codes.
The `c+1` must wrap modulo the i16 operand width, but the current code
does `DAG.getConstant(C->getSExtValue() + 1, dl, MVT::i16)`:
sign-extending to `int64_t`, adding there, then handing the result to
the unsigned
`getConstant(uint64_t, ..., MVT::i16)` overload. 

For constants with bit 15 set the negative `int64_t` is reinterpreted as
a huge `uint64_t`, which
trips the `isUIntN(16, val)` assertion in the APInt constructor under
`LLVM_ENABLE_ASSERTIONS` and yields an APInt with non-zero bits past its
declared width otherwise.

Switching to `DAG.getSignedConstant(C->getSExtValue() + 1, ...)` routes
through the signed `APInt` constructor, which checks `isIntN(16, val)`
and accepts the negative `c+1` produced when the high bit is set. The
four EmitCMP fold branches (SETUGE, SETULT, SETGE, SETLT) are updated
identically.
)

Summary:
libclc needs to normalize triples, mostly on account of the fact that
things like spv and clspv aren't real triples but are used anyway. That
is, we convert the user-value to whatever is passed to `--target=`. The
problem is that we were not using the normal triple for the installation
directory, so something like `spirv64-mesa32-unknown` would be installed
in `spirv64--`.

This *might* have the side effect of putting these in
`spirv64-unknown-unknown`. I actually do not know if that's a problem
with the clang handling, I'll double check.
…m#196345)

\llvm#192120 marked this as RequiredPassInfoMixin, deviating from previous
behavior. This is probably fine for Function/Module analyses, but
doesn't work well for loop analyses in the case that we have a loop in
an optnone function that is not in LCSSA. The LCSSA pass will not run
because it is optional, the analysis will get computed, and then we
assert because the loop is out of LCSSA at the end of the LPM.

Restore the old behavior of just not marking the pass as required as it
seems reasonable enough.
Resolves llvm#128152.

The old algorithm runs a backward DFS from `I` and marks `E` as
ephemeral iff every user of `E` has already been visited. This fails
when `E` has a user that the backward walk never reaches. Switch to a
forward DFS from `E` so that ephemeral values are identified when the
condition has other uses off the assume chain.
RiverDave and others added 21 commits May 9, 2026 02:41
…lvm#195382)

Related: llvm#179278,
llvm#175871

More target attributes like: NoInline on kernels, CUDALaunchBoundsAttr,
CUDAGridConstantAttr param attrs, nvvm.annotations for surface/texture
VarDecls to be deferred for later patches.
…perands (llvm#196214)

`SoftPromoteHalfOperand` had no case for `ISD::BR_CC`, causing a crash
when a half-typed `fcmp` result fed directly into a conditional branch.
All other comparison-related nodes (`SETCC, SELECT_CC`) were already
handled. Add `SoftPromoteHalfOp_BR_CC` following the same pattern as
`SoftPromoteHalfOp_SELECT_CC`.

Fixes llvm#195562

---------

Co-authored-by: Tony Varghese <tony.varghese@ibm.com>
…lvm#196676)

GISel isn't canonicalizing the shift pair to an AND the same way
SelectionDAG does so the patterns weren't firing. Add more directed
tests that use an And explicitly.
…vm#196140)

Fixes llvm#196078

An extra colon in `-mcpu` (e.g. `gfx900::xnack+`) produced an empty
feature component and triggered an assertion in `StringRef::back()`.

Return `std::nullopt` for malformed target IDs instead.
…lvm#196081)

This enabled bf16 promotion for the following operations in GISel,
promoting them to f32 and truncating the result back:
G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FMA, G_FSQRT, G_FMAXNUM, G_FMINNUM,
G_FMAXIMUM, G_FMINIMUM, G_FCEIL, G_FFLOOR, G_FRINT, G_FNEARBYINT,
G_INTRINSIC_TRUNC, G_INTRINSIC_ROUND, G_INTRINSIC_ROUNDEVEN
I’ve removed the TRI member and its initialization, leaving only MRI and
TII as the stored pointers.

---------

Co-authored-by: Benjamin Maxwell <benjamin.maxwell@arm.com>
…lvm#196019)

Move BBAddrMapEntry and PGOAnalysisMapEntry out of namespace ELFYAML
into a new format-agnostic namespace BBAddrMapYAML so that COFF
YAML support can reuse the same schema and MappingTraits.
Updates from 2026-05-08 CWG telecon.
llvm#196661)

Do not suggest adding `[[nodiscard]]` to functions returning a class
template specialization whose primary template is already marked
`[[nodiscard]]`.

Class template specializations do not carry the `[[nodiscard]]`
attribute on their own declarations, so `modernize-use-nodiscard`
previously missed this case and emitted redundant diagnostics for return
types such as:
```cpp
template <class T>
struct [[nodiscard]] Result;

Result<int> f() const;
```
Fixes llvm#163425.
`TidyFastChecks.inc` is generated and its contents should not be checked
by clang-format CI workflow. Add a local `.clang-format-ignore` entry so
the PR formatting check does not report diffs for this file.

Related run:
llvm#194516 (comment)
This adds bf16 legalization for floating point compares.
Renames `RISCVInstrInfoZvvmm.td` to `RISCVInstrInfoZvvm.td` so `Zvvmm`
and `Zvvfmm` share the same IME instruction file according to the spec.
And all future instructions from the `Zvvm family` will be placed here
too.

This PR is required for reviewing llvm#196486 in order to make GitHub show
the diff correcrly.
…opsrun test (#4)

Fix three issues found on RISC-V:

1. Fix use-after-free in block walk (Visitors.h)

When walking blocks with ReverseDominanceIterator, the Traversal object
returned by Iterator::makeIterable(region) was passed as a temporary
directly to llvm::make_early_inc_range(). The temporary was destroyed at
the end of the full expression while iterators from make_early_inc_range
still referenced it. Store the result in a local variable with auto&& to
extend the lifetime of the temporary and bind lvalue references for
ForwardIterator.

2. Fix Shape dialect CstrBroadcastableOp fold and cast canonicalization

Extend getShapeVec to look through tensor.cast operations so that folds
can resolve shapes behind casts inserted by earlier canonicalization
passes (e.g., ShapeOfOpToConstShapeOp). Add a new fold check in
CstrBroadcastableOp::fold that recognizes broadcasting is trivially
valid when at most one operand is non-scalar (resolved via getShapeVec).
Rewrite CanonicalizeCastExtentTensorOperandsPattern to use
modifyOpInPlace instead of replaceOpWithNewOp to avoid issues with
op builder template instantiation.

3. Fix opsrun.py test invocation pattern for multithreaded_tests.py

Convert direct test_foo() calls to run(test_foo) so that
copy_and_update in multithreaded_tests.py properly strips them during
import, preventing JIT execution at module load time which crashes on
RISC-V due to R_RISCV_HI20 relocation range limits.
@WuXintong123
WuXintong123 deleted the wip/save-20260510-004023 branch May 10, 2026 06:56
WuXintong123 pushed a commit that referenced this pull request Jun 7, 2026
I recently noticed LLDB crash during execution of `script
print(lldb.SBDebugger().GetBroadcaster().GetName())` command:
```
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: /home/sergei/llvm-project/build/bin/lldb-dap
 #0 0x000062735c3403d2 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/sergei/llvm-project/build/bin/lldb-dap+0x7c3d2)
 #1 0x000062735c33d7ec llvm::sys::RunSignalHandlers() (/home/sergei/llvm-project/build/bin/lldb-dap+0x797ec)
 #2 0x000062735c33d94c SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #3 0x00007eaa6aa45330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
 #4 0x00007eaa6bb0c092 lldb::SBBroadcaster::GetName() const (/home/sergei/llvm-project/build/bin/../lib/liblldb.so.23.0git+0x90c092)
 #5 0x00007eaa6bcb9a5d _wrap_SBBroadcaster_GetName LLDBWrapPython.cpp:0:0
 #6 0x00007eaa6a1df5f5 (/lib/x86_64-linux-gnu/libpython3.12.so.1.0+0x1df5f5)
 #7 0x00007eaa6a182b2c PyObject_Vectorcall (/lib/x86_64-linux-gnu/libpython3.12.so.1.0+0x182b2c)
 #8 0x00007eaa6a11d5ee _PyEval_EvalFrameDefault (/lib/x86_64-linux-gnu/libpython3.12.so.1.0+0x11d5ee)
 #9 0x00007eaa6a2a091f PyEval_EvalCode (/lib/x86_64-linux-gnu/libpython3.12.so.1.0+0x2a091f)
#10 0x00007eaa6a29c8b0 (/lib/x86_64-linux-gnu/libpython3.12.so.1.0+0x29c8b0)
#11 0x00007eaa6a11fbd3 _PyEval_EvalFrameDefault (/lib/x86_64-linux-gnu/libpython3.12.so.1.0+0x11fbd3)
#12 0x00007eaa6c4891b7 lldb_private::ScriptInterpreterPythonImpl::ExecuteOneLine(llvm::StringRef, lldb_private::CommandReturnObject*, lldb_private::ExecuteScriptOptions const&) (/home/sergei/llvm-project/build/bin/../lib/liblldb.so.23.0git+0x12891b7)
#13 0x00007eaa70326ff5 CommandObjectScriptingRun::DoExecute(llvm::StringRef, lldb_private::CommandReturnObject&) (/home/sergei/llvm-project/build/bin/../lib/liblldb.so.23.0git+0x5126ff5)
#14 0x00007eaa6bee3739 lldb_private::CommandObjectRaw::Execute(char const*, lldb_private::CommandReturnObject&) (/home/sergei/llvm-project/build/bin/../lib/liblldb.so.23.0git+0xce3739)
#15 0x00007eaa6bede09a lldb_private::CommandInterpreter::HandleCommand(char const*, lldb_private::LazyBool, lldb_private::CommandReturnObject&, bool) (/home/sergei/llvm-project/build/bin/../lib/liblldb.so.23.0git+0xcde09a)
#16 0x00007eaa6bb0f0f8 lldb::SBCommandInterpreter::HandleCommand(char const*, lldb::SBExecutionContext&, lldb::SBCommandReturnObject&, bool) (/home/sergei/llvm-project/build/bin/../lib/liblldb.so.23.0git+0x90f0f8)
#17 0x00007eaa6bb0f265 lldb::SBCommandInterpreter::HandleCommand(char const*, lldb::SBCommandReturnObject&, bool) (/home/sergei/llvm-project/build/bin/../lib/liblldb.so.23.0git+0x90f265)
#18 0x000062735c3707f3 lldb_dap::RunLLDBCommands[abi:cxx11](lldb::SBDebugger&, lldb::SBMutex, llvm::StringRef, llvm::ArrayRef<lldb_dap::protocol::String> const&, bool&, bool, bool) (/home/sergei/llvm-project/build/bin/lldb-dap+0xac7f3)
#19 0x000062735c3a8019 lldb_dap::EvaluateRequestHandler::Run(lldb_dap::protocol::EvaluateArguments const&) const (/home/sergei/llvm-project/build/bin/lldb-dap+0xe4019)
#20 0x000062735c3aba78 lldb_dap::RequestHandler<lldb_dap::protocol::EvaluateArguments, llvm::Expected<lldb_dap::protocol::EvaluateResponseBody>>::operator()(lldb_dap::protocol::Request const&) const (/home/sergei/llvm-project/build/bin/lldb-dap+0xe7a78)
#21 0x000062735c3ce1bf lldb_dap::BaseRequestHandler::Run(lldb_dap::protocol::Request const&) (/home/sergei/llvm-project/build/bin/lldb-dap+0x10a1bf)
#22 0x000062735c3577e7 lldb_dap::DAP::HandleObject(std::variant<lldb_dap::protocol::Request, lldb_dap::protocol::Response, lldb_dap::protocol::Event> const&) (/home/sergei/llvm-project/build/bin/lldb-dap+0x937e7)
llvm#23 0x000062735c358705 lldb_dap::DAP::Loop() (/home/sergei/llvm-project/build/bin/lldb-dap+0x94705)
llvm#24 0x000062735c2ed0c7 main (/home/sergei/llvm-project/build/bin/lldb-dap+0x290c7)
llvm#25 0x00007eaa6aa2a1ca __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
```
As far as I understand default constuctors should be covered by fuzzing
tests, so I don't know how to write test for that patch.
WuXintong123 pushed a commit that referenced this pull request Jul 1, 2026
…lvm#191275)" (llvm#206816)

This reverts commit 0f51760.

A test fails with the commit
(llvm#191275 (comment)):

```
Traceback (most recent call last):
  File "/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 596, in test_python_source_frames
    self.assertNotIn("0xffffffffffffffff", output.lower())
AssertionError: '0xffffffffffffffff' unexpectedly found in "* thread #2, name = 'a.out', stop reason = breakpoint 1.1\n  * frame #0: compute_fibonacci at python_helper.py:7 [synthetic]\n    frame #1: process_data at python_helper.py:16 [synthetic]\n    frame #2: main at python_helper.py:27 [synthetic]\n    frame #3: 0x0000badc2de81358 a.out`thread_func(thread_num=0) at main.cpp:44:13\n    frame #4: 0x0000badc2de81f9c a.out`void std::__invoke_impl<void, void (*)(int), int>((null)=__invoke_other @ 0x0000f1555ebae74f, __f=0x0000badc66845ec0, __args=0x0000badc66845eb8) at invoke.h:61:14\n    frame #5: 0x0000badc2de81f18 a.out`std::__invoke_result<void (*)(int), int>::type std::__invoke<void (*)(int), int>(__fn=0x0000badc66845ec0, __args=0x0000badc66845eb8) at invoke.h:96:14\n    frame #6: 0x0000badc2de81ee4 a.out`void std::thread::_invoker<std::tuple<void (*)(int), int>>::_m_invoke<0ul, 1ul>(this=0x0000badc66845eb8, (null)=_index_tuple<0ul, 1ul> @ 0x0000f1555ebae7af) at std_thread.h:259:13\n    frame #7: 0x0000badc2de81e98 a.out`std::thread::_invoker<std::tuple<void (*)(int), int>>::operator()(this=0x0000badc66845eb8) at std_thread.h:266:11\n    frame #8: 0x0000badc2de81d70 a.out`std::thread::_state_impl<std::thread::_invoker<std::tuple<void (*)(int), int>>>::_m_run(this=0xffffffffffffffff) at std_thread.h:211:13\n    frame #9: 0x0000f1555ef029cc libstdc++.so.6`___lldb_unnamed_symbol_d29b0 + 28\n    frame #10: 0x0000f1555ec30398 libc.so.6`___lldb_unnamed_symbol_800c0 + 728\n    frame #11: 0x0000f1555ec99e9c libc.so.6`___lldb_unnamed_symbol_e9e90 + 12\n"
```

I don't know why this test fails with the PR, but I don't have time to
fix it now, so revert it to unblock CI.

The backtrace was
```
    frame #0: compute_fibonacci at python_helper.py:7 [synthetic]
    frame #1: process_data at python_helper.py:16 [synthetic]
    frame #2: main at python_helper.py:27 [synthetic]
    frame #3: 0x0000badc2de81358 a.out`thread_func(thread_num=0) at main.cpp:44:13
    frame #4: 0x0000badc2de81f9c a.out`void std::__invoke_impl<void, void (*)(int), int>((null)=__invoke_other @ 0x0000f1555ebae74f, __f=0x0000badc66845ec0, __args=0x0000badc66845eb8) at invoke.h:61:14
    frame #5: 0x0000badc2de81f18 a.out`std::__invoke_result<void (*)(int), int>::type std::__invoke<void (*)(int), int>(__fn=0x0000badc66845ec0, __args=0x0000badc66845eb8) at invoke.h:96:14
    frame #6: 0x0000badc2de81ee4 a.out`void std::thread::_invoker<std::tuple<void (*)(int), int>>::_m_invoke<0ul, 1ul>(this=0x0000badc66845eb8, (null)=_index_tuple<0ul, 1ul> @ 0x0000f1555ebae7af) at std_thread.h:259:13
    frame #7: 0x0000badc2de81e98 a.out`std::thread::_invoker<std::tuple<void (*)(int), int>>::operator()(this=0x0000badc66845eb8) at std_thread.h:266:11
    frame #8: 0x0000badc2de81d70 a.out`std::thread::_state_impl<std::thread::_invoker<std::tuple<void (*)(int), int>>>::_m_run(this=0xffffffffffffffff) at std_thread.h:211:13
    frame #9: 0x0000f1555ef029cc libstdc++.so.6`___lldb_unnamed_symbol_d29b0 + 28
    frame #10: 0x0000f1555ec30398 libc.so.6`___lldb_unnamed_symbol_800c0 + 728
    frame #11: 0x0000f1555ec99e9c libc.so.6`___lldb_unnamed_symbol_e9e90 + 12
```

This contains 0xffffffffffffffff in frame 8.
WuXintong123 pushed a commit that referenced this pull request Jul 6, 2026
A `breakpoint set -P <class>` with an invalid-UTF-8 class name crashes
lldb with `EXC_BAD_ACCESS`.  The class name is passed through
unmodified, so the byte sequence `\xd0p` (an incomplete two-byte UTF-8
sequence) reaches the Python layer:

```
 ./bin/lldb -b -o $'breakpoint set -P \xd0p -f main.cpp' ./bin/lldb
...
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/
Stack dump:
 #4 PythonDictionary::GetItem(PythonObject const&) const
 #6 PythonDictionary::GetItemForKey(PythonObject const&) const
 #7 PythonObject::ResolveNameWithDictionary(StringRef, PythonDictionary const&)
 #9 ScriptedPythonInterface::CreatePluginObject<...>(...)
```

`ResolveNameWithDictionary` builds a `PythonString` from the class name
and looks it up in the module dictionary.  When the name is not valid
UTF-8, `PyUnicode_FromStringAndSize` returns `NULL`, so the
`PythonString` is left with `m_py_obj == NULL`. `GetItemForKey` forwards
that object to `GetItem`, which passed the `NULL` `PyObject *` straight
to `PyDict_GetItemWithError`.

Debugging the crashing lldb under lldb shows the `NULL` key arriving in
`GetItem`:

```
(lldb) break set -n lldb_private::python::PythonDictionary::GetItem
(lldb) run --no-use-colors -b -s /tmp/bp_cmds.txt
* stop reason = breakpoint 1.1
(lldb) up
(lldb) frame variable key.m_py_obj
(PyObject *) key.m_py_obj = nullptr
```

Continuing lands on the dereference of that `NULL` inside CPython:

```
(lldb) continue
* stop reason = EXC_BAD_ACCESS (code=1, address=0x8)
    frame #0: PyDict_GetItemWithError + 40
->  ldr    x8, [x1, #0x8]
```

`x1` holds the key argument, which is `NULL`, so reading the type field
at offset `0x8` faults at address `0x8`.

`GetItem` already guards against an invalid dictionary (`!IsValid()`);
extend that guard to reject an invalid key as well and return
`nullDeref()`.  `GetItemForKey` consumes the error and returns an empty
`PythonObject`, so existing callers such as `ResolveNameWithDictionary`
keep working and the breakpoint command now fails cleanly instead of
crashing.

This was found by `lldb-commandinterpreter-fuzzer`.

Adds `PythonDataObjectsTest.TestPythonDictionaryGetItemWithInvalidKey`,
which feeds an invalid-UTF-8 key to `GetItem`.  Without the fix the test
dereferences the `NULL` key and crashes (`SIGSEGV`).
WuXintong123 pushed a commit that referenced this pull request Jul 8, 2026
…long encodings (llvm#205907)

When a (signed or unsigned) LEB128 value is encoded with extra trailing
bytes that only carry zero- or sign-extension, the decode loop could
keep
running with the shift amount at 64 or beyond and then evaluate
`Slice << Shift`, which is undefined behavior for a 64-bit type.

The DWARF expression parser feeds attacker-controlled LEB128 operands
(such as `DW_OP_bregN` / `DW_OP_constu`) through
`DataExtractor::getULEB128` / `getSLEB128`, so the
`lldb-dwarf-expression-fuzzer` reaches this under UBSan.  The unsigned
case:

```
LEB128.h:152:20: runtime error: shift exponent 70 is too large for
64-bit type 'uint64_t' (aka 'unsigned long long')
    #0 llvm::decodeULEB128(...) LEB128.h:152
    #1 getLEB128<unsigned long long>(...) DataExtractor.cpp:227
    #2 llvm::DataExtractor::getULEB128(...) DataExtractor.cpp:241
    #3 llvm::DWARFExpression::Operation::extract(...) DWARFExpression.cpp:218
    #7 lldb_private::DWARFExpression::Evaluate(...) DWARFExpression.cpp:1333
    #9 LLVMFuzzerTestOneInput lldb-dwarf-expression-fuzzer.cpp:83
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior LEB128.h:152:20
```

and the signed case, reached the same way:

```
LEB128.h:190:20: runtime error: shift exponent 70 is too large for
64-bit type 'uint64_t' (aka 'unsigned long long')
    #0 llvm::decodeSLEB128(...) LEB128.h:190
    #1 getLEB128<long long>(...) DataExtractor.cpp:227
    #2 llvm::DataExtractor::getSLEB128(...) DataExtractor.cpp:245
    #3 llvm::DWARFExpression::Operation::extract(...) DWARFExpression.cpp:216
    #7 lldb_private::DWARFExpression::Evaluate(...) DWARFExpression.cpp:1333
```

The existing range checks already guarantee that once `Shift` reaches 64
the remaining bytes are pure extension and contribute nothing to the
result, so skip the accumulating shift in that case.  Decoded values are
unchanged for all well-formed inputs.

Adds overlong-encoding regression cases to `LEB128Test`. Without the fix
the signed case is the UBSan diagnostic above in a sanitizer build, and
in a normal build the unsigned case also decodes to the wrong value (the
overlong `1` decodes as `11`).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.