narrowing conversion in list initialization is not flagged when using conversion function to convert to reference
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
```cpp
#include
#include
struct Big
{
operator uint64_t()
{
return a;
}
uint64_t a;
};
struct Small
{
uint32_t a;
using param_t = const uint32_t&; // compiles
// using param_t = const uint32_t; but if its non ref doesnt compile
explicit Small(param_t a) : a(a) {};
};
void foo()
{
int a;
std::cin >> a;
Big big(a);
Small small{big};
// Small small2{a}; does not compile even with uint32_t&
}
```
clang does not issue a diagnostic on narrowing conversion when during a conversion sequence with a conversion function the parameter is reference type
in the code above, if the ref qualifier is removed then narrowing conversion is flagged
gcc on the other hand issues a diagnostic (warning) in all cases
https://godbolt.org/z/b79T5jo8K
i think this is the relevant quote from the standard https://eel.is/c++draft/dcl.init.list#3.7
> Otherwise, if T is a class type, constructors are considered ... If a narrowing conversion (see below) is required to convert any of the arguments, the program is ill-formed
Contributor guide
Research direction
Start with the reduced C++ reproducer in the issue and compare Clang's behavior with the cited [dcl.init.list]#3.7 wording and GCC. Trace list-initialization overload and conversion handling when a conversion function feeds a reference parameter, then add a regression test covering both parameter forms. Done means Clang diagnoses the narrowing conversion consistently.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100