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);
      |      ^

Reply via email to