https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115621

            Bug ID: 115621
           Summary: internal compiler error: Segmentation fault with
                    ambiguous operator
           Product: gcc
           Version: 14.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jan.zizka at nokia dot com
  Target Milestone: ---

Created attachment 58507
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58507&action=edit
Reproducer preprocessed source

When compiling below code with gcc 14.1.1 (in Fedora 40) an internal error is
thrown.
The same compiles with gcc 13.3.1 (in Fedora 39).

$ g++ -freport-bug reproduce.cpp -c -o reproduce.o
reproduce.cpp: In function ‘void test()’:
reproduce.cpp:68:38: internal compiler error: Segmentation fault
   68 |     log::print<int>() << "data: " << master_data;
      |                                      ^~~~~~~~~~~
Please submit a full bug report, with preprocessed source.
See <http://bugzilla.redhat.com/bugzilla> for instructions.
Preprocessed source stored into /tmp/ccCeduvz.out file, please attach this to
your bugreport.


#include <cstdlib>                                                              
#include <stddef.h>                                                             
#include <cstring>                                                              
#include <stddef.h>                                                             

class data_class                                                                
{                                                                               
public:                                                                         
    inline const int& operator*() const { return data; }                        
private:                                                                        
    int data;                                                                   
};                                                                              

class data_stream                                                               
{                                                                               
public:                                                                         
    data_stream& operator<<(char c) { return *this; }                           
};                                                                              

inline data_stream& operator<<(data_stream& out, const data_class& value) {
return out << *value; }   

class text_stream                                                               
{                                                                               
public:                                                                         
    template <typename T>                                                       
    text_stream& operator<<(T val) { return *this; }                            
};                                                                              

inline text_stream& operator<<(text_stream& out, const data_class& value) {
return out  << *value; }  

template <class Level, class Component>                                         
class log_stream_aa                                                             
{                                                                               
public:                                                                         
    template <typename T>                                                       
    log_stream_aa& operator<<(const T& t) { return *this; }                     
};                                                                              

template <class Level, class Component>                                         
struct log_config                                                               
{                                                                               
    typedef log_stream_aa<Level, Component> stream;                             
};                                                                              

template <class Component>                                                      
class basic_log                                                                 
{                                                                               
public:                                                                         
    template <class Level>                                                      
    class print : public log_config<Level, Component>::stream                   
    {                                                                           
    public:                                                                     
        print() : log_config<Level, Component>::stream() { }                    
    };                                                                          
};                                                                              

typedef basic_log<int> log;                                                     

typedef unsigned char data_type[8];                                             

const data_type master_data = {0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};         

template <typename Stream>                                                      
inline Stream& operator<<(Stream& stream, const data_type& value) { return
stream; }                  

void test()                                                                     
{                                                                               
    log::print<int>() << "data: " << master_data;                               
}                                                                               


The code was reduced from rather large code base. I assume the problem is
triggered while diagnostics tries to warn about ambiguous operator<<.
The legacy code is not proper but the compiler should not issue ICE.

When 


template <typename Stream>                                                      
inline Stream& operator<<(Stream& stream, const data_type& value) { return
stream; }  


is removed the code compiles without ICE.

When compiling with clang 18.1.1 following error is reported:


$ clang reproduce.cpp -c -o reproduce.o
reproduce.cpp:68:35: error: use of overloaded operator '<<' is ambiguous (with
operand types 'log_stream_aa<int, int>' and 'const data_type' (aka 'const
unsigned char[8]'))
   68 |     log::print<int>() << "data: " << master_data;
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^  ~~~~~~~~~~~
reproduce.cpp:36:20: note: candidate function [with T = unsigned char[8]]
   36 |     log_stream_aa& operator<<(const T& t) { return *this; }
      |                    ^
reproduce.cpp:64:16: note: candidate function [with Stream = log_stream_aa<int,
int>]
   64 | inline Stream& operator<<(Stream& stream, const data_type& value) {
return stream; }
      |                ^
1 error generated.


I believe that gcc is trying to report same problem during which it crashes.

Reply via email to