Skip to content

clang-cl emits bogus error: cannot decompose this type; 'std::tuple_size<const S>::value' is not a valid integral constant expression #32583

@StephanTLavavej

Description

@StephanTLavavej
Bugzilla Link 33236
Resolution FIXED
Resolved on Aug 20, 2019 03:01
Version 4.0
OS Windows NT
Blocks #41819
Attachments Self-contained test case
CC @zmodem,@JVApen,@mclow,@zygoloid,@rnk

Extended Description

Note: This is using my implementation of LWG 2770 tuple_size SFINAE, which will ship in VS 2017's first toolset update (aka "15.3").

C:\Temp>type meow.cpp
#include <assert.h>
#include

struct S {
int x;
};

int main() {
S s{99};
auto [m1] = s;
auto& [r1] = s;
assert(m1 == 99);
assert(&r1 == &s.x);

const S cs{1729};
auto [m2] = cs;
auto& [r2] = cs;
assert(m2 == 1729);
assert(&r2 == &cs.x);

}

C:\Temp>cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25326 for x64
Copyright (C) Microsoft Corporation. All rights reserved.

usage: cl [ option... ] filename... [ /link linkoption... ]

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

C:\Temp>clang-cl -v
clang version 4.0.0 (tags/RELEASE_400/final)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: S:\WCFB01\vctools\NonShip\ClangLLVM\bin

C:\Temp>clang-cl /EHsc /nologo /W4 /std:c++latest meow.cpp && meow
meow.cpp(17,11): error: cannot decompose this type; 'std::tuple_size::value' is not a valid integral constant expression
auto& [r2] = cs;
^
1 error generated.

I believe that this is the same issue as what I reported to the reflectors on April 3, 2017. C1XX has implemented my preferred resolution.

--
Subject: [isocpp-lib] New issue - Core and Library disagree on tuple_size SFINAE (LWG 2770)

LWG 2770's resolution taught tuple_size to SFINAE. However, Core's wording for structured bindings disagrees with what the Library provides.

N4659 23.5.3.6 [tuple.helper]/4: "template class tuple_size; template class tuple_size; template class tuple_size; Let TS denote tuple_size of the cv-unqualified type T. If the expression TS::value is well-formed when treated as an unevaluated operand, then each of the three templates shall meet the UnaryTypeTrait requirements (23.15.1) with a base characteristic of integral_constant<size_t, TS::value> Otherwise, they shall have no member value."

When the Library provides SFINAE, Meow is complete, it's just that Meow::value or Meow::type is non-existent. This is the long-standing practice followed by invoke_result, etc.

However, Core expects different behavior:

11.5 [dcl.struct.bind]/3: "Otherwise, if the qualified-id std::tuple_size names a complete type, the expression std::tuple_size::value shall be a well-formed integral constant expression and"

This wording was introduced in Issaquah as the resolution of GB 20 (thanks to Casey for the programmer-archaeology). He found no discussion, just "ready for vote on Friday".

I encountered this because I implemented tuple_size SFINAE with the traditional approach (it is a complete class with no members), yet libc++ had a test expecting tuple_size to be an incomplete class. I argue that the Core wording should change - it should not inspect the completeness of tuple_size, but should instead inspect the well-formedness of tuple_size::value, which is what the Library is already doing when implementing tuple_size.

Thanks,
STL

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugzillaIssues migrated from bugzillaclangClang issues not falling into any other category

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions