[llvm-bugs] [Bug 44484] New: Clang mishandles span CTAD with a constrained constructor

via llvm-bugs llvm-bugs at lists.llvm.org
Tue Jan 7 15:58:24 PST 2020


            Bug ID: 44484
           Summary: Clang mishandles span CTAD with a constrained
           Product: clang
           Version: trunk
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: normal
          Priority: P
         Component: C++2a
          Assignee: unassignedclangbugs at nondot.org
          Reporter: sfinae at hotmail.com
                CC: blitzrakete at gmail.com, erik.pilkington at gmail.com,
                    llvm-bugs at lists.llvm.org, richard-llvm at metafoo.co.uk

Consider the following code, reduced from std::span's Standardese in N4842:

C:\Temp>type clang_span_ctad.cpp
#include <stddef.h>
#include <type_traits>

inline constexpr size_t dynamic_extent = static_cast<size_t>(-1);

template <typename T, size_t Extent = dynamic_extent>
struct span {
    template <size_t Size>
    requires (Extent == dynamic_extent || Extent == Size)
    span(T (&)[Size]) {}

template <typename T, size_t Extent>
span(T (&)[Extent]) -> span<T, Extent>;

int main() {
    int arr[] = {1,2,3};
    span s{arr};
    static_assert(std::is_same_v<decltype(s), span<int, dynamic_extent>>,
        "CTAD should deduce span<int, dynamic_extent> here (surprisingly!).");

C:\Temp>cl /EHsc /nologo /W4 /std:c++latest clang_span_ctad.cpp

C:\Temp>clang-cl -m32 /EHsc /nologo /W4 /std:c++latest clang_span_ctad.cpp
clang_span_ctad.cpp(19,5): error: static_assert failed due to requirement
'std::is_same_v<span<int, 3>, span<int,
      4294967295> >' "CTAD should deduce span<int, dynamic_extent> here
    static_assert(std::is_same_v<decltype(s), span<int, dynamic_extent>>,
    ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

The current development version of MSVC accepts this. On Wandbox, gcc HEAD
10.0.0 20200106 also accepts this. Clang 9.0.0 (depicted above) and clang HEAD
10.0.0 on Wandbox reject this, emitting the static_assert.

I believe that this is a Clang bug. My current understanding of what should
happen is that the templated and constrained constructor (generating an
implicit deduction guide) and the templated non-constrained explicit deduction
guide should compete during CTAD. During overload resolution,
[over.match.best]/2.5 should tiebreak due to "more specialized" (selecting the
implicit deduction guide generated by the constrained constructor because of
partial ordering by constraints, [temp.constr.order]), which is considered
before the tiebreaker that favors explicit deduction guides

(Separately, the Standardese for std::span didn't anticipate this interaction
between a constrained constructor and non-constrained guide, so I'm going to
file an LWG issue to change it. As a result, this is a low priority for the

You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200107/0b79f8d6/attachment.html>

More information about the llvm-bugs mailing list