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

libc++ makes some tuple_size specializations complete types, breaking decomposition declarations #30861

Closed
llvmbot opened this issue Jan 3, 2017 · 8 comments
Labels
bugzilla Issues migrated from bugzilla libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

Comments

@llvmbot
Copy link
Collaborator

llvmbot commented Jan 3, 2017

Bugzilla Link 31513
Resolution FIXED
Resolved on Jan 04, 2017 16:40
Version unspecified
OS Linux
Reporter LLVM Bugzilla Contributor
CC @mclow,@zygoloid

Extended Description

(reported on behalf of Bjorn Fahller; he cannot get a new account created).

The following (believed to be correct) code fails to compile with svn rev 290809 with -std=c++1z -stdlib=libc++ :

--
#include
struct S { int s; };

int main()
{
S const s{99};
auto& [p] = s;
return p;
}

Quoting Bjorn:

"The above program fails on a home built clang+libc++ at svn rev 290809 when compiled with '-std=c++1z -stdlib=libc++'
To make it compile, comment out the '#include' line.
I believe the bug is in libstdc++ rather than in clang++ itself.
It's very similar to, but not identical with, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78939
Strictly speaking, neither const nor & capture is needed to expose the problem, but since it does make a difference in the gcc libstdc++-case, I choose to include it."

Bjorn emailed a while back asking for a login to report it himself.

@llvmbot
Copy link
Collaborator Author

llvmbot commented Jan 3, 2017

Hi Matt, Thanks for the report! (Big fan of godbolt.org)

Note that this reproducer doesn't compile with any combination of Clang, GCC, libstdc++, and libc++. I suspect the bug is in the compiler side of the structured binding implementations.

Strictly speaking, neither const nor & capture is needed to expose the problem

In the case of libc++ it does, because libc++ currently incorrectly rejects the non-const case even though it should be accepted. That's the real libc++ bug here, and that bug is caused by providing an empty definition of the "tuple_size" primary template. I'll fix that bug shortly.

@zygoloid
Copy link
Mannequin

zygoloid mannequin commented Jan 3, 2017

Note that this reproducer doesn't compile with any combination of Clang,
GCC, libstdc++, and libc++. I suspect the bug is in the compiler side of the
structured binding implementations.

I don't think so. Rather, I suspect neither libc++ nor libstdc++ have implemented http://cplusplus.github.io/LWG/lwg-defects.html#2770 yet.

@llvmbot
Copy link
Collaborator Author

llvmbot commented Jan 3, 2017

Note that this reproducer doesn't compile with any combination of Clang,
GCC, libstdc++, and libc++. I suspect the bug is in the compiler side of the
structured binding implementations.

I don't think so. Rather, I suspect neither libc++ nor libstdc++ have
implemented http://cplusplus.github.io/LWG/lwg-defects.html#2770 yet.

Libc++ (just) now implements LWG 2770, but this still appears to be a Clang bug. It appears that Clang is checking of tuple_size is incomplete, not if tuple_size<Tp>::value is well formed. So even with LWG 2770 Clang appears incorrect.

Example:

#include
#include

struct S { int x; };

int main() {
S const s{99};
auto [p1] = s; // OK. looks at tuple_size and sees it is incomplete.
auto& [p2] = s; // error {{tuple_size::value is not an integral constant expression}}
}

@llvmbot
Copy link
Collaborator Author

llvmbot commented Jan 3, 2017

Re-binning as Clang and re-titling to be more appropriate for Clang.

@​Richard please send this back to libc++ if I'm incorrect.

@zygoloid
Copy link
Mannequin

zygoloid mannequin commented Jan 3, 2017

See wg21.link/p0490r0, GB 20 -- Clang is correct to test for tuple_size being complete. Sending back to libc++ =)

@zygoloid
Copy link
Mannequin

zygoloid mannequin commented Jan 3, 2017

Hmm. Looks like it's actually a bug in the standard. For some reason, LWG 2770 only constrains tuple_size to have no member 'value' if tuple_size::value is not available, rather than making it an incomplete type, as CWG assumed LWG was going to do :(

On the core side, the idea is that if someone tries to specialize tuple_size but gets it wrong (for instance, if ::value is not usable in a constant expression), we want to give a hard error.

@llvmbot
Copy link
Collaborator Author

llvmbot commented Jan 3, 2017

@​Richard I implemented a version of LWG 2770 which makes tuple_size incomplete in most situations.

It is up for review as D28222 (https://reviews.llvm.org/D28222).

@llvmbot
Copy link
Collaborator Author

llvmbot commented Jan 5, 2017

Fixed in r291019 (v4.0). Unfortunately the fix is entirely non-standard, but the standard is clearly incorrect here. I'll submit a new resolution for LWG 2770 which mirrors what libc++ actually implements shortly.

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 10, 2021
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

No branches or pull requests

1 participant