Bug 258079 - clang-11 fails: candidate template ignored: substitution failure [with U = float]: variable length array cannot be formed during template argument deduction
Summary: clang-11 fails: candidate template ignored: substitution failure [with U = fl...
Status: Closed Works As Intended
Alias: None
Product: Base System
Classification: Unclassified
Component: misc (show other bugs)
Version: 13.0-STABLE
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-toolchain (Nobody)
URL: https://bugs.llvm.org/show_bug.cgi?id...
Keywords:
Depends on:
Blocks:
 
Reported: 2021-08-27 09:34 UTC by Yuri Victorovich
Modified: 2021-08-27 10:12 UTC (History)
2 users (show)

See Also:


Attachments
c++test.cpp (319 bytes, text/plain)
2021-08-27 09:34 UTC, Yuri Victorovich
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Yuri Victorovich freebsd_committer freebsd_triage 2021-08-27 09:34:22 UTC
Created attachment 227468 [details]
c++test.cpp

clang-11 fails on the attached testcase, bug g++10 succeeds.

c++test.cpp:16:12: error: no matching member function for call to 'mmm'
        return ph.mmm(data, 10);
               ~~~^~~
c++test.cpp:10:14: note: candidate template ignored: substitution failure [with U = float]: variable length array cannot be formed during template argument deduction
    inline U mmm(U data[(1U<<IntBits)+1], unsigned int mask) const {
             ^         ~
c++test.cpp:10:28: warning: shift count >= width of type [-Wshift-count-overflow]
    inline U mmm(U data[(1U<<IntBits)+1], unsigned int mask) const {
                           ^ ~~~~~~~
1 warning and 1 error generated.
[yuri@yv /disk-samsung/freebsd-ports/audio/calf-lv2]$ c++ -std=c++11 -c c++test.cpp 
c++test.cpp:16:12: error: no matching member function for call to 'mmm'
        return ph.mmm(data, 10);
               ~~~^~~
c++test.cpp:10:14: note: candidate template ignored: substitution failure [with U = float]: variable length array cannot be formed during template argument deduction
    inline U mmm(U data[(1U<<IntBits)+1], unsigned int mask) const {
             ^         ~
c++test.cpp:10:28: warning: shift count >= width of type [-Wshift-count-overflow]
    inline U mmm(U data[(1U<<IntBits)+1], unsigned int mask) const {
                           ^ ~~~~~~~
1 warning and 1 error generated.


audio/calf-lv2 had USE_GCC=yes because of this.
Comment 1 Yuri Victorovich freebsd_committer freebsd_triage 2021-08-27 09:35:39 UTC
* audio/calf-lv2 has USE_GCC=yes because of this.
Comment 2 Dimitry Andric freebsd_committer freebsd_triage 2021-08-27 10:02:08 UTC
Is it possible to compile this source with -std=gnu++98 or -std=gnu++03 ? Because appparently this VLA restriction is very old, but somehow only triggered for C++11 and higher.
Comment 3 Yuri Victorovich freebsd_committer freebsd_triage 2021-08-27 10:09:29 UTC
(In reply to Dimitry Andric from comment #2)

It succeeds with -std=gnu++98 and -std=gnu++03.
Comment 4 David Chisnall freebsd_committer freebsd_triage 2021-08-27 10:12:09 UTC
The code in the test case contains undefined behaviour.  `IntBits` is 64 - 20, whcih is 44.  `1U` is an `unsigned int`, which is 32 bits.  `1U<<44` is a shift of greater than the width od the type, which is undefined behaviour.

This is *probably* benign here, because array sizes in arguments in C/C++ are ignored and so this probably won't propagate into the generated IR (though if it does, both clang and GCC will take advantage of the UB and probably reduce this to something that traps.

The correct fix is to change `1U` to `1ULL`.  Rejecting code that contains undefined behaviour is both allowed by the standard and generally considered more user-friendly behaviour than accepting it and generating broken code.