LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 39183 - tuple comparison operators return true for tuples of different sizes
Summary: tuple comparison operators return true for tuples of different sizes
Status: RESOLVED FIXED
Alias: None
Product: libc++
Classification: Unclassified
Component: All Bugs (show other bugs)
Version: 7.0
Hardware: PC Linux
: P normal
Assignee: Marshall Clow (home)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-10-04 13:32 PDT by Tony E Lewis
Modified: 2019-02-10 04:33 PST (History)
3 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tony E Lewis 2018-10-04 13:32:35 PDT
The following compiles cleanly under `clang++ -stdlib=libc++ -S a.cpp` :


#include <tuple>

static_assert( std::tuple<int>{ 1 } == std::tuple<int, int>{ 1, 2 }, "" );
static_assert( std::tuple<int>{ 0 } != std::tuple<int, int>{ 1, 2 }, "" );
static_assert( std::tuple<int>{ 0 } <  std::tuple<int, int>{ 1, 2 }, "" );
static_assert( std::tuple<int>{ 2 } >= std::tuple<int, int>{ 1, 2 }, "" );


..demonstrating that these comparison operators are returning true for pairs of tuples of different sizes. This feels particularly problematic in the case of operator==().

Under "tuple.rel", the standard says that these operators require `sizeof...(TTypes) == sizeof...(UTypes)`, though I must confess I don't know whether the standard mandates detection and reporting of violations of requirements like these. Either way, I think it'd be very much better to do so in this case.

I can reproduce this on Godbolt with "clang version 8.0.0 (trunk 343649)" (and Clangs 6 and 7).

Thanks very much for all work on libc++.
Comment 1 Marshall Clow (home) 2018-10-04 16:13:59 PDT
"Require" is how we specify a precondition - something the caller must satisfy.
So, no, that's perfectly legal (though unhelpful) result.

I have a paper in flight (https://wg21.link/P0805) that relaxes the requirement that only equal-length tuples can be compared.
Comment 2 Marshall Clow (home) 2018-10-04 16:14:58 PDT
When P0805 is adopted, then your examples #2 and #4 will fail.
Comment 3 Marshall Clow (home) 2018-10-04 16:15:47 PDT
Wow - I can't read.
Only #1 will fail.
Comment 4 Eric Fiselier 2018-10-04 17:40:07 PDT
My personal preference is to fix this and force libc++ to diagnose it as ill-formed.

That being said, this looks like a conforming extension, since it should only be observable in programs that are otherwise ill-formed NDR.
Comment 5 Tony E Lewis 2018-10-05 02:20:47 PDT
Thanks for the responses. Understood re the meaning of "Require". P0805's suggestions seems like good ideas to me. Thanks for that (and for all the other vast amount of great work you do for LWG, and for WG21 in general).

Of my examples, #1 is the one that concerns me. I recently had tests that were erroneously passing under this scenario. It would have been great if libc++ had given me early indication that I was being an idiot.

My vote (FWIW) would be that if Clang 8.0 is likely to be released before libc++ is likely to be able to adopt a post-P0805 approach, it'd be really good if the equality operator could do something more helpful than at present: compile-time diagnosing, SFINAEing-away or at least returning false.

Thanks very much.
Comment 6 Marshall Clow (home) 2019-02-07 11:04:36 PST
As of revision revision 353450 libc++ now static_asserts if you try to compare tuples of different sizes.
Comment 7 Tony E Lewis 2019-02-10 04:33:54 PST
Yep - I'm able to see that fix on Godbolt.

Fantastic stuff - thanks very much.