[Bug c++/92859] New: compiler treats enum type as an integer during overload resolution when a bit-field of this enum is considered

2019-12-08 Thread armagvvg at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92859

Bug ID: 92859
   Summary: compiler treats enum type as an integer during
overload resolution when a bit-field of this enum is
considered
   Product: gcc
   Version: 7.4.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: armagvvg at gmail dot com
  Target Milestone: ---

Created attachment 47440
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47440&action=edit
gzipped preprocessed file

Enumeration types are different from their underlying types when participating
in function overload resolution. But the compiler doesn't differentiate them
when a bit-field member is defined from the enumeration type. And an overloaded
stream operator is defined inside a class where that enum exists. The sample:


#include 

struct ES { 
enum E { v }; 

// 1
friend std::ostream& operator<<(std::ostream& os, E) { return os << "E"; }
};

// 2 - should be the same but...
// std::ostream& operator<<(std::ostream& os, ES::E) { return os << "E"; }

struct S {
ES::E e : 1; 
};

int main() {
S s{}; 
std::cout << s.e << std::endl;
return 0;
}


It's expected that an output should be 'E' thus calling the operator<<(..., E)
defined here. But 's.e' field is considered integer and '0' is printed.

What's more interesting, if the operator will be defined as marked by '2', all
it works as expected.

Compiled with: g++ -Wall -Wextra -std=c++11 --save-temps -o tst.gcc tst.cpp
No output during compilation.

> gcc -v:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu
7.4.0-1ubuntu1~18.04.1' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs
--enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr
--with-gcc-major-version-only --program-suffix=-7
--program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id
--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
--libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu
--enable-libstdcxx-debug --enable-libstdcxx-time=yes
--with-default-libstdcxx-abi=new --enable-gnu-unique-object
--disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie
--with-system-zlib --with-target-system-zlib --enable-objc-gc=auto
--enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64
--with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic
--enable-offload-targets=nvptx-none --without-cuda-driver
--enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu
--target=x86_64-linux-gnu
Thread model: posix
gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)

> uname -r
5.0.0-32-generic

I've repeated this bug also on my work with gcc 9.1.0. The same behaviour using
-std=c++14 and -std=c++17.

[Bug c++/113117] New: ambiguous call during operator overloading is not detected for templates

2023-12-22 Thread armagvvg at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113117

Bug ID: 113117
   Summary: ambiguous call during operator overloading is not
detected for templates
   Product: gcc
   Version: 13.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: armagvvg at gmail dot com
  Target Milestone: ---

In a nutshell: the next code snippet is compiled successfully, but shouldn't be
according to a language standard:

struct S {
template 
S& operator<<(T) { return *this; }
};

template 
T& operator<<(T& s, int) { return s; }

int main () {
S s;
s << 1;
}

Details:

Operator overloading for classes can be implemented with free functions and
with class member. When both exist, the C++ standard (I used C++17, part 16.5.2
- Overloaded Operators -> Binary operators) says that "If both forms of the
operator function have been declared, the rules in 16.3.1.2 determine which, if
any, interpretation is used.". The set of candidates contains both the member
and the free function then. The member is considered as a free function with
first implicit parameter (16.3.1 - Candidate functions and argument lists) - "a
member function is considered to have an extra parameter, called the implicit
object parameter, which represents the object for which the member function has
been called".

Thus we have two templates here:
1. template  T& operator<<(T&, int) - defined in the code
2. template  S& operator<<(S, T) - synthesized from the member
function

16.3.3 "Best viable function" mentions that "F1 and F2 are function template
specializations, and the function template for F1 is more specialized than the
template for F2 according to the partial ordering rules described in
17.5.6.2...". But no one template is more specialized for a call "operator<<(S,
int)". Thus we have two best viable functions and "If there is exactly one
viable function that is a better function than all other viable functions, then
it is the
one selected by overload resolution; otherwise the call is ill-formed".

This code snippet should be ill-formed. But it doesn't.

clang detects this as an error.

[Bug c++/113117] ambiguous call during operator overloading is not detected for templates

2023-12-22 Thread armagvvg at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113117

--- Comment #2 from Vyacheslav Grigoryev  ---
Looks so, checking on https://godbolt.org/z/vb6s6cY6Y. Hm... wasting a time on
filling the bug :(