https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117322
Bug ID: 117322 Summary: Another spurios "may be used uninitialized" warning when using alloca. Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: akryuk at gmail dot com Target Milestone: --- The following code produces a "may be used uninitialized warning", though there is no visible path that would leave the `arr` pointer uninitialized (https://godbolt.org/z/6dbEafEGb). This happens when using GCC versions starting with 14.1. It does not seem to happen with prior versions. I ran into it when building on Ubuntu 24.04 with "-O2 -Wall" flags. If I use alloca or heap allocation unconditionally, the warning goes away. If I do an early return (`if(len == 0) return;`), the warning goes away. If I actually skip heap memory allocation the `else` clause ( /* heapBuff.reset(new Storage[len]);*/ ), the warning goes away. If I drop optimization to "-O1", the warning goes away. //********************************************************* #include <memory> #include <alloca.h> #include <type_traits> using T = long long; //---------------------------------------------------------- void f(T const* data, size_t len); //---------------------------------------------------------- void h(int const* data, size_t len) { using Storage = typename std::aligned_storage<sizeof(T), alignof(T)>::type; T* arr; std::unique_ptr<Storage[]> heapBuff; auto nbytes = len * sizeof(T); if (nbytes <= 256*1024) { arr = reinterpret_cast<T*>(alloca(nbytes)); } else { heapBuff.reset(new Storage[len]); arr = reinterpret_cast<T*>(heapBuff.get()); } // for(size_t i = 0; i != len; ++i) // arr[i] = data[i]; std::uninitialized_copy(data, data + len, arr); f(arr, len); } //********************************************************* <source>: In function 'void h(const int*, size_t)': <source>:29:4: warning: 'arr' may be used uninitialized [-Wmaybe-uninitialized] 29 | f(arr, len); | ~^~~~~~~~~~ <source>:7:6: note: by argument 1 of type 'const T*' {aka 'const long long int*'} to 'void f(const T*, size_t)' declared here 7 | void f(T const* data, size_t len); | ^