<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">