https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114983

            Bug ID: 114983
           Summary: The -Wsizeof-array-div warning suppression using extra
                    parenthesis (which is even suggested when in the
                    warning itself) doesn't work inside templated code.
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: patryk.ludwikowski.7 at gmail dot com
                CC: polacek at redhat dot com
  Target Milestone: ---

The -Wsizeof-array-div warning suppression using extra parenthesis (which is
even suggested when in the warning itself) doesn't work inside templated code,
or: the note in the warning is invalid for use in templated code. 

Code snippet to reproduce the problem:

```c++
#include <cstdint>

uint16_t samplesBuffer[40];

template <typename T>
constexpr inline auto getNumberOfSamples()
{
    // No matter how much parentheses are added, warnings still persists
    return ((sizeof(samplesBuffer)) / (sizeof(T))); 
}

int main()
{
    // return sizeof(samplesBuffer) / (sizeof(uint8_t)); // Works fine, no
warning
    return getNumberOfSamples<uint8_t>(); // Results in warning, how to silence
it?
}
```

Tried on Godbolt https://godbolt.org/z/63YK5dW5o with x86-64 gcc trunk. Other
GCC versions (older and other architectures) also seem affected. By the way,
CLANG compiles fine without warning. For the compiler options, the
-Wsizeof-array-div alone is enough to trigger the bug.

I tried it out on my system as well (sorry for Windows and older GCC version),
the same warning:

```
PS D:\Test> gcc -v
Using built-in specs.
COLLECT_GCC=F:\msys64\mingw64\bin\gcc.exe
COLLECT_LTO_WRAPPER=F:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../gcc-13.2.0/configure --prefix=/mingw64
--with-local-prefix=/mingw64/local --build=x86_64-w64-mingw32
--host=x86_64-w64-mingw32 --target=x86_64-w64-mingw32
--with-native-system-header-dir=/mingw64/include --libexecdir=/mingw64/lib
--enable-bootstrap --enable-checking=release --with-arch=nocona
--with-tune=generic --enable-languages=c,lto,c++,fortran,ada,objc,obj-c++,jit
--enable-shared --enable-static --enable-libatomic --enable-threads=posix
--enable-graphite --enable-fully-dynamic-string
--enable-libstdcxx-filesystem-ts --enable-libstdcxx-time
--disable-libstdcxx-pch --enable-lto --enable-libgomp --disable-libssp
--disable-multilib --disable-rpath --disable-win32-registry --disable-nls
--disable-werror --disable-symvers --with-libiconv --with-system-zlib
--with-gmp=/mingw64 --with-mpfr=/mingw64 --with-mpc=/mingw64
--with-isl=/mingw64 --with-pkgversion='Rev6, Built by MSYS2 project'
--with-bugurl=https://github.com/msys2/MINGW-packages/issues --with-gnu-as
--with-gnu-ld --disable-libstdcxx-debug --enable-plugin
--with-boot-ldflags=-static-libstdc++ --with-stage1-ldflags=-static-libstdc++
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.2.0 (Rev6, Built by MSYS2 project)
PS D:\Test> gcc test.cpp -Wsizeof-array-div
test.cpp: In instantiation of 'constexpr auto getNumberOfSamples() [with T =
unsigned char]':
test.cpp:15:36:   required from here
test.cpp:9:41: warning: expression does not compute the number of elements in
this array; element type is 'uint16_t' {aka 'short unsigned int'}, not
'unsigned char' [-Wsizeof-array-div]
    9 |         return ((sizeof(samplesBuffer)) / (sizeof(T)));
      |                ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~
test.cpp:9:44: note: add parentheses around 'sizeof (unsigned char)' to silence
this warning
    9 |         return ((sizeof(samplesBuffer)) / (sizeof(T)));
      |                                           ~^~~~~~~~~~
      |                                           (          )
test.cpp:3:10: note: array 'samplesBuffer' declared here
    3 | uint16_t samplesBuffer[40];
      |          ^~~~~~~~~~~~~
```

Please note that the warning is correct, because T is not guaranteed to be the
array element type. IMO it would be nice if the warning was not thrown in this
case, or if there was other way of silencing it. Either way the note about
adding parentheses is wrong in this case for sure. 

I added CC to pola...@redhat.com because they seem to be the person who
implemented it (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91741 / mail
thread https://gcc.gnu.org/pipermail/gcc-patches/2020-September/553888.html),
no intention of blaming or anything, just they might be interested, idk. 

Workaround by diagnostic macros can be used for GCC:
```c++
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsizeof-array-div"
        return sizeof(samplesBuffer) / (sizeof(T));
#pragma GCC diagnostic pop
```

Let me know if something more is needed, it's my frist bug report here.

Reply via email to