Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clang issue in CTAD #62925

Closed
walge-laine opened this issue May 24, 2023 · 3 comments · Fixed by #94752
Closed

Clang issue in CTAD #62925

walge-laine opened this issue May 24, 2023 · 3 comments · Fixed by #94752
Assignees
Labels
c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party

Comments

@walge-laine
Copy link

Clang fails to compile cppreference example code. See Compiler Explorer.

@EugeneZelenko EugeneZelenko added c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" and removed new issue labels May 24, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented May 24, 2023

@llvm/issue-subscribers-c-20

@llvmbot
Copy link
Collaborator

llvmbot commented May 24, 2023

@llvm/issue-subscribers-clang-frontend

@shafik
Copy link
Collaborator

shafik commented May 24, 2023

Code in question:

#include <map>

int main() {
   std::map m1 = {std::pair{"foo", 2}, {"bar", 3}}; // guide #2
   std::map m2(m1.begin(), m1.end()); // guide #1
}

Diagnostic:

<source>:4:13: error: no viable constructor or deduction guide for deduction of template arguments of 'map'
   std::map m1 = {std::pair{"foo", 2}, {"bar", 3}}; // guide #2
            ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_map.h:204:7: note: candidate template ignored: couldn't infer template argument '_Key'
      map(const _Compare& __comp,
      ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_map.h:283:2: note: candidate template ignored: couldn't infer template argument '_Key'
        map(_InputIterator __first, _InputIterator __last)
        ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_map.h:238:7: note: candidate template ignored: could not match 'initializer_list' against 'pair'
      map(initializer_list<value_type> __l,
      ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_map.h:250:7: note: candidate template ignored: could not match 'map' against 'pair'
      map(const map& __m, const __type_identity_t<allocator_type>& __a)
      ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_map.h:254:7: note: candidate template ignored: could not match 'map' against 'pair'
      map(map&& __m, const __type_identity_t<allocator_type>& __a)
      ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_map.h:260:7: note: candidate template ignored: could not match 'initializer_list' against 'pair'
      map(initializer_list<value_type> __l, const allocator_type& __a)
      ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_map.h:1472:5: note: candidate template ignored: substitution failure [with _InputIterator = std::pair<const char *, int>]: no member named 'value_type' in 'std::iterator_traits<std::pair<const char *, int>>'
    map(_InputIterator, _InputIterator,
    ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_map.h:1481:5: note: candidate template ignored: could not match 'initializer_list' against 'pair'
    map(initializer_list<pair<_Key, _Tp>>,
    ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_map.h:1494:5: note: candidate template ignored: could not match 'initializer_list' against 'pair'
    map(initializer_list<pair<_Key, _Tp>>, _Allocator)
    ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_map.h:217:7: note: candidate function template not viable: requires 1 argument, but 2 were provided
      map(const map&) = default;
      ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_map.h:225:7: note: candidate function template not viable: requires 1 argument, but 2 were provided
      map(map&&) = default;
      ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_map.h:246:7: note: candidate function template not viable: requires single argument '__a', but 2 arguments were provided
      map(const allocator_type& __a)
      ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_map.h:100:11: note: candidate function template not viable: requires 1 argument, but 2 were provided
    class map
          ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_map.h:266:2: note: candidate function template not viable: requires 3 arguments, but 2 were provided
        map(_InputIterator __first, _InputIterator __last,
        ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_map.h:1488:5: note: candidate function template not viable: requires 3 arguments, but 2 were provided
    map(_InputIterator, _InputIterator, _Allocator)
    ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_map.h:195:7: note: candidate function template not viable: requires 0 arguments, but 2 were provided
      map() = default;
      ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_map.h:300:2: note: candidate function template not viable: requires at least 3 arguments, but 2 were provided
        map(_InputIterator __first, _InputIterator __last,
        ^
1 error generated.
Compiler returned: 1

Note both gcc/MSVC accept: https://godbolt.org/z/6v4fvabb5

@shafik shafik added the confirmed Verified by a second party label May 24, 2023
@yuanfang-chen yuanfang-chen self-assigned this Jul 5, 2023
@spaits spaits closed this as completed in f80bd9b Jun 18, 2024
AlexisPerry pushed a commit to llvm-project-tlp/llvm-project that referenced this issue Jul 9, 2024
…on (llvm#94752)

Fixes llvm#62925.

The following code:
```cpp
#include <map>

int main() {
   std::map m1 = {std::pair{"foo", 2}, {"bar", 3}}; // guide llvm#2
   std::map m2(m1.begin(), m1.end()); // guide llvm#1
}
```
Is rejected by clang, but accepted by both gcc and msvc:
https://godbolt.org/z/6v4fvabb5 .

So basically CTAD with copy-list-initialization is rejected.

Note that this exact code is also used in a cppreference article:
https://en.cppreference.com/w/cpp/container/map/deduction_guides

I checked the C++11 and C++20 standard drafts to see whether suppressing
user conversion is the correct thing to do for user conversions. Based
on the standard I don't think that it is correct.

```
13.3.1.4 Copy-initialization of class by user-defined conversion [over.match.copy]
Under the conditions specified in 8.5, as part of a copy-initialization of an object of class type, a user-defined
conversion can be invoked to convert an initializer expression to the type of the object being initialized.
Overload resolution is used to select the user-defined conversion to be invoked
```
So we could use user defined conversions according to the standard.

```
If a narrowing conversion is required to initialize any of the elements, the
program is ill-formed.
```
We should not do narrowing.

```
In copy-list-initialization, if an explicit constructor is chosen, the initialization is ill-formed.
```
We should not use explicit constructors.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

5 participants