<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/96403>96403</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
False positive "reference to stack memory associated with local variable" when double-dereferencing ("**itOpt") an optional iterator
</td>
</tr>
<tr>
<th>Labels</th>
<td>
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
smcpeak
</td>
</tr>
</table>
<pre>
For the following example:
```cpp
// test.cc
// Clang complains when accessing an optional iterator.
#include <cassert> // assert
#include <iostream> // std::cout
#include <optional> // std::optional
#include <vector> // std::vector
typedef std::vector<int> IVec;
IVec ivec;
int const &getVecElementRef()
{
// Get a valid iterator.
IVec::const_iterator it = ivec.cbegin();
assert(it != ivec.end());
// Wrap it in an optional.
std::optional<IVec::const_iterator> itOpt(it);
assert(itOpt);
#if 1
// Access the iterator via double dereference.
//
// Clang complains: warning: reference to stack memory associated with
// local variable 'itOpt' returned [-Wreturn-stack-address]
return **itOpt;
#else
// This works fine (with or without the `const &` part).
auto const &tmp = *itOpt;
return *tmp;
#endif
}
int main()
{
ivec.push_back(0);
// Get an element reference using operator[].
int const &v0 = ivec[0];
std::cout << "&v0: " << &v0 << "\n";
// Get an element reference using the function. The resulting address
// is the same.
int const &v1 = getVecElementRef();
std::cout << "&v1: " << &v1 << "\n";
// Returns 0.
return v1;
}
// EOF
```
Clang (v16, v18, and latest) erroneously complains:
```text
$ clang++ -o test.exe -std=c++17 -g -Wall test.cc
test.cc:27:12: warning: reference to stack memory associated with local variable 'itOpt' returned [-Wreturn-stack-address]
return **itOpt;
^~~~~
1 warning generated.
$ ./test.exe
&v0: 0x5633e9c95eb0
&v1: 0x5633e9c95eb0
```
GCC and MSVC accept this example without complaint (https://godbolt.org/z/f49P4s4fd).
The consensus on StackOverflow is this is a false positive: https://stackoverflow.com/questions/78656796/is-it-ok-to-double-dereference-itopt-an-optional-iterator
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy8Vk9v27gT_TT0ZSBDoizZOvhgO3HxO_zQRVu0x4KmRjY3FKklKSfZQz77gtQf24qDLXrYorAiajh8M_PeDJm14qgQ1yTbkuxhxlp30mZta94ge5oddPm63msD7oRQaSn1s1BHwBdWNxJJuiHxA4mH3zzu_vOm6VfontA9OLRuzvnN2k4ydQSu60YyoSw8n1AB4xyt9ScwBbpxQismQTg0zGkzvzmMpkJx2ZYIJN1xZi0aR9JH6P33C3dshbbOIKu98Z1__X7rSh9euuG6vetmgPeLbkbzO67OyJ02V-DHXf2Xq7jda4MlVu9M0p1QIf7_fUdO0m1n7V9AnK9Wul-hHHCtrANC8yO678gfJdao3BesCF0RWvTmy37fGNEndMDgzKQop5WB_vAubcq6n4MBCAckfQhQ5vyAR6H6U9LRf18xuvK2NBnNUZW97ZX5BNQPwxp_hlDXzBlgvS9CuvsIqU-hcJ-bDsiHCIPBFI6vagXJBNsmkDooaEzHWTAodXuQCCUarNCg4ji_3TnxM1EMSTfwzIwS6uj_HJ2A02Ad409QY63Nq0etuWAOS3gW7jTxKjVnEs7MCObRELrsg1uCQdcahSWQbBv96N6i4DpiZWnQWpI9DO66z0DohtBN5-JdclBanBz_7SQsPGvzZKESyp-_8iBBmwBWty4kzjeVga4kj6Fhvg7FmDDWOn0htKubwLZ3SK5hurq5IKQpqlJUA-cfplqp2UjYqSwCR5vWnn4eGH8idBXf4em1dhRgJ7WrmrWh6emm52DoxWNwN2I9x6OQSLaNfQUu0d00Ld9ZSLoDQmnY51lCKL0sd75Gm2yn_OMDhf0L9DAfWsW9vuYA304IBm0rXWjmPVtuPYpOE5bV-EGoSQj1g_b0a1End6JOfj3qL4EuFuL5hEDe8fYuXfqdj5_3k6l4bdRpmdDVOckJ3cE5WfkHUyVI5scloQWgMVqhbq18vZH93Znr8GUcUwvg3j-hW0K3EOluAOMLAkQhWQ-8-5YsITpC9INJeTukh5d0Q5ck3ST0d7vNf9Ffrqdu9vj29vbWrScDYjii8srCcnKFWMCc0P2QnWG110r8kuVpigUvMjzEl4_Jhx_vVfrTrivr_79-34X7TeM7mrDDHWpsc0OFPfVXJ-eaUOpApqMuD1q6uTZHQvd_E7qvFsUfC7uoyksT7H698LyAUNnWglbw1efz8xlNJfVzpzlh_ZNBxaRFaLQVTpz9ZQ5ujw2l0P3WOdc1ofu_WrRe45bQ_XKVZ_myyAndCxsJF-mnyOmom2vR1VyLhNONi5iKhgEcjeM2oJ6V67Qs0oLNcJ0skyJepVmaz05r5EURL0vkKx4nZVHQA6VskfHFgRa8SnEm1jSmizinNCkSmuTzalHGLF3kK55ghqucLGKsmZBzKc-1z-BMWNviusgXcTqT7IDSDpdfs_ZG0aE9WrKIpbDOXrY54SSu9zc58x3kd6Xgm1K49L7Ll-haQ-hgF7b7t-LuvXjWGrmeMEa4U3voa-ZD6B9RY_SfyF0omW3Rl7HLxHlN_wkAAP__xUaOxA">