llvm / llvm/llvm-project

[clang-tidy] AllowExplicitObjectParameters suppresses warnings for this auto&

Open
#221,750 1 comment 0 reactions 0 assignees View on GitHub
clang-tidy false-negative
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

`cat foo.cc`

```c++
#include
#include
#include

struct task {
struct promise_type {
task get_return_object() {
return {std::coroutine_handle::from_promise(*this)};
}
std::suspend_always initial_suspend() noexcept { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() { std::terminate(); }
};
std::coroutine_handle h;
~task() { h.destroy(); }
};

[[gnu::noinline]]
task make_task() {
auto f = [value = 42](this auto& self) -> task {
std::printf("%d\n", value);
co_return;
};
return f();
}

int main() {
auto t = make_task();
t.h.resume();
}
```

```console
❯ ./LLVM-CI-2cbdbc9ad7ff40457023c8f353161069df8eb57f-Linux-X64/bin/clang++ -std=c++23 -g -fsanitize=address foo.cc
❯ ./a.out
=================================================================
==85242==ERROR: AddressSanitizer: stack-use-after-return on address 0x7b956f6f0060 at pc 0x561f43753d1c bp 0x7fff50ae8350 sp 0x7fff50ae8348
READ of size 4 at 0x7b956f6f0060 thread T0
#0 0x561f43753d1b in _ZZ9make_taskvENH3$_0clIS_EE4taskRT_.resume /tmp/llvm-upstream-2cbdbc9ad7ff4/foo.cc:22:25
#1 0x561f437545b3 in std::__n4861::coroutine_handle::resume() const /usr/lib/gcc/x86_64-redhat-linux/16/../../../../include/c++/16/coroutine:247:29
#2 0x561f437538cf in main /tmp/llvm-upstream-2cbdbc9ad7ff4/foo.cc:30:7
#3 0x7f95718f3680 in __libc_start_call_main (/lib64/libc.so.6+0x3680) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6)
#4 0x7f95718f3797 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3797) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6)
#5 0x561f436616e4 in _start (/tmp/llvm-upstream-2cbdbc9ad7ff4/a.out+0x6e4)

Address 0x7b956f6f0060 is located in stack of thread T0 at offset 32 in frame
#0 0x561f4375329f in make_task() /tmp/llvm-upstream-2cbdbc9ad7ff4/foo.cc:20

This frame has 1 object(s):
[32, 36) 'f' (line 21) <== Memory access at offset 32 is inside this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-use-after-return /tmp/llvm-upstream-2cbdbc9ad7ff4/foo.cc:22:25 in _ZZ9make_taskvENH3$_0clIS_EE4taskRT_.resume
Shadow bytes around the buggy address:
0x7b956f6efd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7b956f6efe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7b956f6efe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7b956f6eff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7b956f6eff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x7b956f6f0000: f1 f1 f1 f1 00 f3 f3 f3 f5 f5 f5 f5[f5]f5 f5 f5
0x7b956f6f0080: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
0x7b956f6f0100: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
0x7b956f6f0180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7b956f6f0200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7b956f6f0280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==85242==ABORTING
Aborted (core dumped) ./a.out
❯ cat .clang-tidy
Checks: '-*,cppcoreguidelines-avoid-capturing-lambda-coroutines'
CheckOptions:
cppcoreguidelines-avoid-capturing-lambda-coroutines.AllowExplicitObjectParameters: true
❯ ./LLVM-CI-2cbdbc9ad7ff40457023c8f353161069df8eb57f-Linux-X64/bin/clang-tidy foo.cc -- -std=c++23
❯ echo $?
0
❯ ./LLVM-CI-2cbdbc9ad7ff40457023c8f353161069df8eb57f-Linux-X64/bin/clang -v
clang version 24.0.0git (https://github.com/llvm/llvm-project 2cbdbc9ad7ff40457023c8f353161069df8eb57f)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /tmp/llvm-upstream-2cbdbc9ad7ff4/LLVM-CI-2cbdbc9ad7ff40457023c8f353161069df8eb57f-Linux-X64/bin
Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/16
Selected GCC installation: /usr/lib/gcc/x86_64-redhat-linux/16
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Selected multilib: .;@m64
```

Expected behavior:

The check should warn for capturing coroutine lambdas with reference explicit object parameters (`this auto&` or `this auto&&`), even when `AllowExplicitObjectParameters` is `true`. Only by-value explicit object parameters (`this auto`) should be exempted, since reference parameters do not copy the closure into the coroutine frame.

Contributor guide

Open the contributing guide

Research direction

Start with the foo.cc reproducer and its .clang-tidy configuration, then run clang-tidy with the cppcoreguidelines-avoid-capturing-lambda-coroutines check. Trace how AllowExplicitObjectParameters handles the explicit object parameter. Done means reference parameters such as this auto& and this auto&& produce warnings, while this auto remains exempt.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.