<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/95658>95658</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[static-analyzer] false positive in `unix.Errno`
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
tearfur
</td>
</tr>
</table>
<pre>
The static analyzer considers the case where `getcwd()` is sucessful but returns `nullptr`, which shouldn't be possible (if it is, how are we even supposed to check against that??).
Steps:
1. Configure the CMake project.
```
CC=clang CXX=clang++ cmake -B build -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_CLANG_TIDY=clang-tidy
```
2. Build the project.
```
cd build && cmake --build .
```
Using clang and clang-tidy from the llvm repo.
```console
$ clang --version
Ubuntu clang version 19.0.0 (++20240614073522+cc7a18c18011-1~exp1~20240614193539.212)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/lib/llvm-19/bin
$ clang-tidy --version
Ubuntu LLVM version 19.0.0
Optimized build.
```
<details>
<summary>Code for reproducing</summary>
```c++
// main.cpp
#include <climits>
#include <iostream>
#include <vector>
#include <unistd.h>
int main()
{
auto buf = std::vector<char>{};
buf.resize(PATH_MAX);
auto path = std::string_view{};
for (;;)
{
if (char const* const ret = getcwd(std::data(buf), std::size(buf)))
{
path = ret;
break;
}
if (errno == ERANGE)
{
buf.resize(std::size(buf) * 2U);
continue;
}
}
std::cout << path << '\n';
return 0;
}
```
```cmake
# CMakeLists.txt
cmake_minimum_required(VERSION 3.28)
project(test)
set(CMAKE_CXX_STANDARD 17)
add_executable(test main.cpp)
```
</details>
Output:
```
/root/main.cpp:20:13: warning: An undefined value may be read from 'errno' [clang-analyzer-unix.Errno]
20 | if (errno == ERANGE)
| ^
/usr/include/errno.h:38:16: note: expanded from macro 'errno'
38 | # define errno (*__errno_location ())
| ^~~~~~~~~~~~~~~~~~~~~~
/root/main.cpp:12:5: note: Loop condition is true. Entering loop body
12 | for (;;)
| ^
/root/main.cpp:14:37: note: Assuming that 'getcwd' is successful; 'errno' becomes undefined after the call
14 | if (char const* const ret = getcwd(std::data(buf), std::size(buf)))
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/root/main.cpp:14:31: note: Assuming 'ret' is null
14 | if (char const* const ret = getcwd(std::data(buf), std::size(buf)))
| ^~~
/root/main.cpp:14:9: note: Taking false branch
14 | if (char const* const ret = getcwd(std::data(buf), std::size(buf)))
| ^
/root/main.cpp:20:13: note: An undefined value may be read from 'errno'
20 | if (errno == ERANGE)
| ^
/usr/include/errno.h:38:16: note: expanded from macro 'errno'
38 | # define errno (*__errno_location ())
| ^~~~~~~~~~~~~~~~~~~~~~
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzUV91u2zoSfhrmZmBBoixLvvCFLNtni03bgzY9yLkyKGlscSuRWv44SS_67AvqL7bXyaJY4GBXMBSHM575Zjj8hsO05keBuCLRmkSbO2ZNJdXKIFMHq-5yWb6sHioEbZjhBTDB6pcfqKCQQvMSlQZTIRRMIzxVqBDIwj-iKZ5KQhNCl2ThA9egbYFaH2wNuTWg0FgltNMVtq5bo8jCJzSDp4oXFehK2roUhMYGcoRWas3zGoHQhB-AG-DaKVfyCZhCeELAEwrQtm2lxhKMhKLC4juwI-NCGzAVMyTcuQ9desTfED_t318NtpqEw3-BB5kUB360Cru4so_sO0Kr5D-wMBc_BHDoh0-_kmUk3BQ1E0fIHh_H74SuCV1D0ThLszXkltclzDbZx_Tv2_3624f7zf7hz9-3JNxsMLfHSZQ9Pu6z-_TTb_uHD5s_R3Mzw8uXtyBQD9adeYf9JuprzABFOUAidEHoYgQ66xe9t1z172-aiyP0MTNRwitEOCjZdDjq-tSAwlZeIJnMuUKSNQ6rdD5Ym81OqDSXYnCUW2HsIBskECw93_OhKzSXZOrTub8I5n4cRpQSui6KmAVJESR-EMyCn_jcBj9HpWAZRuHSowF1Vdo5eWDqiIaEKTwni_1iPmuLWc2FfZ4dhR1UKoWshEaWWDvFVmr-3Is-CG1YXWO54cqJCN1ZrQjd1Tx37_rUzIIlobuci6to-4zdDvn-_o-PVxGPe_K5NbzhP3DYQe8qsxfpDrMSDeO1JuF2WtK2aZh6IeE2kyXCQSq3UUqWtuDiSMKM0N2rzu3t61M_BrQjdAcN48Ir2nZcDLkoalsikDArat5wc4biQsqlNgpZ84b4hIWR6hrKhYoVXJvSq66UuDAdrIGUekm8nqobmDUScnsAEm5Am9JxQpiODrOiYp3feE3iDQnHH-b24CnU_AcSmvyePvxt_zF9dA7Ca9MtM9WlbW0UF8f9iePTtVmAbi8c2HDtPiNkJ7mA7R5-cJoOYcfKhtC0_-J4tvM5EfLkvGSGEZrk9uBs0-wMVh_MKFle-L7p3z1TeModoCk9Ctn3i7B6A5srJj0LA5US0llyxrZf0k-_bd9BcJH_2yGASwf9dr0p41NIYbiw-Cqc4L2BdXJTSOvSm5EwG-PvvhMakyhz7evCY9_0wJ8WX23fPLHTCXOEPJV635LuuTbaM8-mX-9U9g0XvLHNXuE_LVfo9vuP7ZevHz5_gtA7q_uhMRCaGHTVsjx3q9EJXjvQ14f00yb9soEgvtJkZbnHZyysYXmNg7XXsz8pv0FHhO7-jZG692drWmumnnzbCt0pKQ2hu8lfmFKfhGkQOu59Ykp0DJZCKsCKEg9cYAknVluEhr24e0XH5F2bIjTu6o7QGEi07jl5vOrMrODP3raTR6-lQX0gcQa_UL3n6l1tRRPJDZ1i4DFCd50hx2JpmLioFi4UIQ26v_jcMlHiAL5hhZLnIUwQw6Tz6aqmTwAM-FwxpPt999--lgUzrrkM3Hh52joD0fbnreedvQgoCdPoHPS9lK07bSXvnHENRln0ALbCoGNCqJ2Gu3BO_gM6Je1tPpwwvgdn7jIZn-NJtbaNc-suhy59I0nGw311uLCScH1RHzkWskF9VlTsYFAN1-C6fgU_v1EgfxFLv7drv7KLXdqCm2kjNHZc36fL3eL_twL_T1Etz4N6YN9dSAdWa4RcMVFU19H8VVGcZ-79mj6ju2lzfo3r_gsuu3nu_p9JbOwvd-UqLJfhkt3hKoiDZB5FSz--q1Zz6sdByJIwSXBJ88NiHheMzqMwpxhT_3DHV8NoEQU0CuaRFyVxHpXJcjn350mx8Mncx4bx2nOjgCfV8Y5rbXG1jBZRclezHGvdjeGUCnyCTkgodVO5WnXjQ26Pmsz9uuv-kxXDTd3N7_2MPjUuEm2GknZTiuEnBC7cHHfW0Bb-nVX1qjKmH4O7C_yRm8rmXiGbYW4Zx5fp5rDrwGlCdz3404r-KwAA___BNqL9">