Bug 88434 - [DR1835] operator< should take precedence over template argument in basic.lookup.classref
Summary: [DR1835] operator< should take precedence over template argument in basic.loo...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 9.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
Depends on: P1787R6
Blocks: c++-lookup, c++-name-lookup
  Show dependency treegraph
 
Reported: 2018-12-10 20:40 UTC by Andrew Giese
Modified: 2022-12-02 20:27 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2018-12-11 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Giese 2018-12-10 20:40:26 UTC
Semi-related: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85570
Bug discovered here: https://stackoverflow.com/q/53712642/27678


The following code does not compile in gcc 9 (or earlier) or clang 8 (or earlier), but does in MSVC 19.00.23506.

compile with -std=c++11 Code follows:

#include <type_traits>

using namespace std;

struct A{ int rank; };

template<typename T>
bool comp_rank(const T &a, const T &b){
    return a.rank < b.rank;
}

int main()
{
    A a{42}, b{0};
    comp_rank(a, b);
}

gcc fails with 

prog.cc: In function 'bool comp_rank(const T&, const T&)':
prog.cc:9:23: error: type/value mismatch at argument 1 in template parameter list for 'template<class> struct std::rank'
    9 |     return a.rank < b.rank;
      |                       ^~~~
prog.cc:9:23: note:   expected a type, got 'b.rank'


This appears to violate [basic.lookup.classref] which states

In a class member access expression, if the . or -> token is immediately followed by an identifier followed by a <, the identifier must be looked up to determine whether the < is the beginning of a template argument list or a less-than operator. The identifier is first looked up in the class of the object expression. If the identifier is not found, it is then looked up in the context of the entire postfix-expression and shall name a class template.
Comment 1 Andrew Pinski 2018-12-11 00:04:26 UTC
>Semi-related: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85570

It might be related in the sense the namelookup of rank is happening a definition time rather instantation time.

Shorter testcase (without includes):

template <int> struct rank{};

struct A{ int rank; };

template<typename T>
bool comp_rank(const T &a, const T &b){
            return a.rank < b.rank;
}

int main()
{
            A a{42}, b{0};
                comp_rank(a, b);
}
Comment 2 Andrew Giese 2018-12-11 16:51:38 UTC
It appears there is a CWG issue for this: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1835
Comment 3 Marek Polacek 2018-12-11 18:44:10 UTC
Since the CWG issue is still "drafting", should we be making any changes at this time?
Comment 4 Andrew Pinski 2018-12-11 18:46:49 UTC
Suspecting until the Defect report is resolved.
Comment 5 Andrew Pinski 2022-12-02 20:26:15 UTC
> [Accepted at the November, 2020 meeting as part of paper P1787R6 and moved to DR at the February, 2021 meeting.]