Bug 101486 - Rejects valid qualification conversion involving array of unknown bound in function template argument [P0388]
Summary: Rejects valid qualification conversion involving array of unknown bound in fu...
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 12.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2021-07-17 12:58 UTC by Lénárd Szolnoki
Modified: 2021-07-24 03:12 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Lénárd Szolnoki 2021-07-17 12:58:19 UTC
Version:

g++ (Compiler-Explorer-Build-gcc-48e8a7a677b8356df946cd12fbb215538828e747-binutils-2.36.1) 12.0.0 20210707 (experimental)

Flags: -std=c++20 -pedantic-errors

Observed behavior:

Rejects the following code:

```
template <typename T>
void f1(const T(*)[10]);

template <typename T>
void f2(T(*)[]);

void bar(int (*ptr)[10]) {
    f1(ptr); // accepts
    f2(ptr); // rejects
}
```

Expected behavior:

Accept both function calls. Qualification conversions are allowed when deducing template arguments in a pointer function parameter (https://timsong-cpp.github.io/cppwp/n4868/temp.deduct#call-4.2). As of C++20 (P0388) converting `int (*)[10]` to `int (*)[]` is a valid qualification conversion.

Exhibits:

https://godbolt.org/z/rcbMhEf45
Comment 1 Andrew Pinski 2021-07-24 03:11:09 UTC
clang and ICC reject this.
clang error message:
<source>:9:5: error: no matching function for call to 'f2'
    f2(ptr); // rejects
    ^~
<source>:5:6: note: candidate template ignored: could not match 'type-parameter-0-0 []' against 'int [10]'
void f2(T(*)[]);
     ^
Comment 2 Andrew Pinski 2021-07-24 03:12:25 UTC
Note GCC accepts the following while both clang and ICC don't:
template <typename T>
void f1(const T(*)[10]);

template <typename T>
void f2(T(*)[]);

void bar(int (*ptr)[10]) {
    f1<int>(ptr);
    f2<int>(ptr);
}
So GCC at least is doing the conversion correctly.