https://llvm.org/bugs/show_bug.cgi?id=26504
Bug ID: 26504 Summary: Overload resolution is strange with constexpr Product: clang Version: trunk Hardware: PC OS: All Status: NEW Severity: normal Priority: P Component: C++11 Assignee: unassignedclangb...@nondot.org Reporter: nicolaswe...@gmx.de CC: dgre...@apple.com, llvm-bugs@lists.llvm.org Classification: Unclassified Consider this: Nicos-MBP:llvm-build thakis$ cat test.cc template<class T> const T& min(const T& a, const T& b) { return a < b ? a : b; } struct A { A(); operator int() const; operator unsigned() const; A foo() const { return min(*this, A()); } }; inline bool operator<(const A &a, const A &b) { return true; } Nicos-MBP:llvm-build thakis$ bin/clang -c test.cc -std=c++11 This builds fine. Now make max() constexpr: Nicos-MBP:llvm-build thakis$ bin/clang -c test.cc -std=c++11 test.cc:2:12: error: use of overloaded operator '<' is ambiguous (with operand types 'const A' and 'const A') return a < b ? a : b; ~ ^ ~ test.cc:10:12: note: in instantiation of function template specialization 'min<A>' requested here return min(*this, A()); ^ test.cc:2:12: note: because of ambiguity in conversion of 'const A' to 'float' return a < b ? a : b; ^ test.cc:6:3: note: candidate function operator int() const; ^ test.cc:7:3: note: candidate function operator unsigned() const; ^ test.cc:2:12: note: because of ambiguity in conversion of 'const A' to 'float' return a < b ? a : b; ^ test.cc:6:3: note: candidate function operator int() const; ^ test.cc:7:3: note: candidate function operator unsigned() const; ^ test.cc:2:12: note: built-in candidate operator<(float, float) return a < b ? a : b; ^ test.cc:2:12: note: built-in candidate operator<(float, double) test.cc:2:12: note: built-in candidate operator<(float, long double) test.cc:2:12: note: built-in candidate operator<(float, int) test.cc:2:12: note: built-in candidate operator<(float, long) test.cc:2:12: note: built-in candidate operator<(float, long long) test.cc:2:12: note: built-in candidate operator<(float, __int128) test.cc:2:12: note: built-in candidate operator<(float, unsigned int) test.cc:2:12: note: built-in candidate operator<(float, unsigned long) test.cc:2:12: note: built-in candidate operator<(float, unsigned long long) test.cc:2:12: note: built-in candidate operator<(float, unsigned __int128) test.cc:2:12: note: built-in candidate operator<(double, float) test.cc:2:12: note: built-in candidate operator<(double, double) test.cc:2:12: note: built-in candidate operator<(double, long double) test.cc:2:12: note: built-in candidate operator<(double, int) test.cc:2:12: note: built-in candidate operator<(double, long) test.cc:2:12: note: built-in candidate operator<(double, long long) test.cc:2:12: note: built-in candidate operator<(double, __int128) test.cc:2:12: note: built-in candidate operator<(double, unsigned int) test.cc:2:12: note: built-in candidate operator<(double, unsigned long) test.cc:2:12: note: built-in candidate operator<(double, unsigned long long) test.cc:2:12: note: built-in candidate operator<(double, unsigned __int128) test.cc:2:12: note: built-in candidate operator<(long double, float) test.cc:2:12: note: built-in candidate operator<(long double, double) test.cc:2:12: note: built-in candidate operator<(long double, long double) test.cc:2:12: note: built-in candidate operator<(long double, int) test.cc:2:12: note: built-in candidate operator<(long double, long) test.cc:2:12: note: built-in candidate operator<(long double, long long) test.cc:2:12: note: built-in candidate operator<(long double, __int128) test.cc:2:12: note: built-in candidate operator<(long double, unsigned int) test.cc:2:12: note: built-in candidate operator<(long double, unsigned long) test.cc:2:12: note: built-in candidate operator<(long double, unsigned long long) test.cc:2:12: note: built-in candidate operator<(long double, unsigned __int128) test.cc:2:12: note: built-in candidate operator<(int, float) test.cc:2:12: note: built-in candidate operator<(int, double) test.cc:2:12: note: built-in candidate operator<(int, long double) test.cc:2:12: note: built-in candidate operator<(int, int) test.cc:2:12: note: built-in candidate operator<(int, long) test.cc:2:12: note: built-in candidate operator<(int, long long) test.cc:2:12: note: built-in candidate operator<(int, __int128) test.cc:2:12: note: built-in candidate operator<(int, unsigned int) test.cc:2:12: note: built-in candidate operator<(int, unsigned long) test.cc:2:12: note: built-in candidate operator<(int, unsigned long long) test.cc:2:12: note: built-in candidate operator<(int, unsigned __int128) test.cc:2:12: note: built-in candidate operator<(long, float) test.cc:2:12: note: built-in candidate operator<(long, double) test.cc:2:12: note: built-in candidate operator<(long, long double) test.cc:2:12: note: built-in candidate operator<(long, int) test.cc:2:12: note: built-in candidate operator<(long, long) test.cc:2:12: note: built-in candidate operator<(long, long long) test.cc:2:12: note: built-in candidate operator<(long, __int128) test.cc:2:12: note: built-in candidate operator<(long, unsigned int) test.cc:2:12: note: built-in candidate operator<(long, unsigned long) test.cc:2:12: note: built-in candidate operator<(long, unsigned long long) test.cc:2:12: note: built-in candidate operator<(long, unsigned __int128) test.cc:2:12: note: built-in candidate operator<(long long, float) test.cc:2:12: note: built-in candidate operator<(long long, double) test.cc:2:12: note: built-in candidate operator<(long long, long double) test.cc:2:12: note: built-in candidate operator<(long long, int) test.cc:2:12: note: built-in candidate operator<(long long, long) test.cc:2:12: note: built-in candidate operator<(long long, long long) test.cc:2:12: note: built-in candidate operator<(long long, __int128) test.cc:2:12: note: built-in candidate operator<(long long, unsigned int) test.cc:2:12: note: built-in candidate operator<(long long, unsigned long) test.cc:2:12: note: built-in candidate operator<(long long, unsigned long long) test.cc:2:12: note: built-in candidate operator<(long long, unsigned __int128) test.cc:2:12: note: built-in candidate operator<(__int128, float) test.cc:2:12: note: built-in candidate operator<(__int128, double) test.cc:2:12: note: built-in candidate operator<(__int128, long double) test.cc:2:12: note: built-in candidate operator<(__int128, int) test.cc:2:12: note: built-in candidate operator<(__int128, long) test.cc:2:12: note: built-in candidate operator<(__int128, long long) test.cc:2:12: note: built-in candidate operator<(__int128, __int128) test.cc:2:12: note: built-in candidate operator<(__int128, unsigned int) test.cc:2:12: note: built-in candidate operator<(__int128, unsigned long) test.cc:2:12: note: built-in candidate operator<(__int128, unsigned long long) test.cc:2:12: note: built-in candidate operator<(__int128, unsigned __int128) test.cc:2:12: note: built-in candidate operator<(unsigned int, float) test.cc:2:12: note: built-in candidate operator<(unsigned int, double) test.cc:2:12: note: built-in candidate operator<(unsigned int, long double) test.cc:2:12: note: built-in candidate operator<(unsigned int, int) test.cc:2:12: note: built-in candidate operator<(unsigned int, long) test.cc:2:12: note: built-in candidate operator<(unsigned int, long long) test.cc:2:12: note: built-in candidate operator<(unsigned int, __int128) test.cc:2:12: note: built-in candidate operator<(unsigned int, unsigned int) test.cc:2:12: note: built-in candidate operator<(unsigned int, unsigned long) test.cc:2:12: note: built-in candidate operator<(unsigned int, unsigned long long) test.cc:2:12: note: built-in candidate operator<(unsigned int, unsigned __int128) test.cc:2:12: note: built-in candidate operator<(unsigned long, float) test.cc:2:12: note: built-in candidate operator<(unsigned long, double) test.cc:2:12: note: built-in candidate operator<(unsigned long, long double) test.cc:2:12: note: built-in candidate operator<(unsigned long, int) test.cc:2:12: note: built-in candidate operator<(unsigned long, long) test.cc:2:12: note: built-in candidate operator<(unsigned long, long long) test.cc:2:12: note: built-in candidate operator<(unsigned long, __int128) test.cc:2:12: note: built-in candidate operator<(unsigned long, unsigned int) test.cc:2:12: note: built-in candidate operator<(unsigned long, unsigned long) test.cc:2:12: note: built-in candidate operator<(unsigned long, unsigned long long) test.cc:2:12: note: built-in candidate operator<(unsigned long, unsigned __int128) test.cc:2:12: note: built-in candidate operator<(unsigned long long, float) test.cc:2:12: note: built-in candidate operator<(unsigned long long, double) test.cc:2:12: note: built-in candidate operator<(unsigned long long, long double) test.cc:2:12: note: built-in candidate operator<(unsigned long long, int) test.cc:2:12: note: built-in candidate operator<(unsigned long long, long) test.cc:2:12: note: built-in candidate operator<(unsigned long long, long long) test.cc:2:12: note: built-in candidate operator<(unsigned long long, __int128) test.cc:2:12: note: built-in candidate operator<(unsigned long long, unsigned int) test.cc:2:12: note: built-in candidate operator<(unsigned long long, unsigned long) test.cc:2:12: note: built-in candidate operator<(unsigned long long, unsigned long long) test.cc:2:12: note: built-in candidate operator<(unsigned long long, unsigned __int128) test.cc:2:12: note: built-in candidate operator<(unsigned __int128, float) test.cc:2:12: note: built-in candidate operator<(unsigned __int128, double) test.cc:2:12: note: built-in candidate operator<(unsigned __int128, long double) test.cc:2:12: note: built-in candidate operator<(unsigned __int128, int) test.cc:2:12: note: built-in candidate operator<(unsigned __int128, long) test.cc:2:12: note: built-in candidate operator<(unsigned __int128, long long) test.cc:2:12: note: built-in candidate operator<(unsigned __int128, __int128) test.cc:2:12: note: built-in candidate operator<(unsigned __int128, unsigned int) test.cc:2:12: note: built-in candidate operator<(unsigned __int128, unsigned long) test.cc:2:12: note: built-in candidate operator<(unsigned __int128, unsigned long long) test.cc:2:12: note: built-in candidate operator<(unsigned __int128, unsigned __int128) 1 error generated. cl.exe builds this fine, and that's how it implements std::min(). a) Who is right? b) If it's clang, we need to figure out what cl.exe does and accept that as an extension. (Also, the diagnostic is not very good.) -- You are receiving this mail because: You are on the CC list for the bug.
_______________________________________________ llvm-bugs mailing list llvm-bugs@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs