Bug 111647 - g++ accepts different c++ on -fchecking= and checking=2
Summary: g++ accepts different c++ on -fchecking= and checking=2
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 14.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid
Depends on:
Blocks: 111642
  Show dependency treegraph
 
Reported: 2023-09-30 12:32 UTC by Sergei Trofimovich
Modified: 2024-08-09 14:27 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2023-10-02 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sergei Trofimovich 2023-09-30 12:32:42 UTC
Encountered when was reducing PR111642 where `make bootstrap4` fails. Reduced example:

// $ cat rtl-tests.cc.cc
struct poly_int {
  template <typename...> constexpr poly_int() : poly_int() {}
};
template <int> void run() { poly_int(); }

Here is the mismatch between -fchecking=0 and -fchecking=2:

$ /tmp/gb/./prev-gcc/xg++ -B/tmp/gb/./prev-gcc/ -c rtl-tests.cc.cc -o bug -fchecking=0
$ /tmp/gb/./prev-gcc/xg++ -B/tmp/gb/./prev-gcc/ -c rtl-tests.cc.cc -o bug -fchecking=2
rtl-tests.cc.cc: In instantiation of ‘constexpr poly_int::poly_int() [with <template-parameter-1-1> = {}]’:
rtl-tests.cc.cc:4:39:   required from here
rtl-tests.cc.cc:2:58: error: constructor delegates to itself
    2 |   template <typename...> constexpr poly_int() : poly_int() {}
      |          

I think it's an invalid code (clang rejects it as well), but I'm not sure. AFAIU all -fchecking= options should handle it identically.

gcc is from r14-4339-geaa41a6dc127d8

$ /tmp/gb/./prev-gcc/xg++ -B/tmp/gb/./prev-gcc/ -v
Reading specs from /tmp/gb/./prev-gcc/specs
COLLECT_GCC=/tmp/gb/./prev-gcc/xg++
COLLECT_LTO_WRAPPER=/tmp/gb/./prev-gcc/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /home/slyfox/dev/git/gcc/configure --disable-multilib --enable-languages=c,c++ CC='gcc -O1 -g0' CXX='g++ -O1 -g0'
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 14.0.0 20230929 (experimental) (GCC)
Comment 1 Sergei Trofimovich 2023-09-30 19:23:52 UTC
More realistic example extracted from gcc's poly_int:

// $ cat rtl-tests.cc
template<unsigned int N> struct poly_int {
  template<typename ...Cs> constexpr poly_int (const Cs &... cs)
  : coeffs { cs... } {}

  int coeffs[N];
};

#define TARGET_DEFINED_VALUE 1
// this works:
//#define TARGET_DEFINED_VALUE 2

// Is instantiated only for N == 2.
template<unsigned int N> struct const_poly_int_tests {
  static void run () {
    poly_int<TARGET_DEFINED_VALUE> (1, 1);
  }
};

$ g++ -c rtl-tests.cc -fchecking=1
# did not fail, BAD!

$ g++ -c rtl-tests.cc -fchecking=2
rtl-tests.cc: In instantiation of 'constexpr poly_int<N>::poly_int(const Cs& ...) [with Cs = {int, int}; unsigned int N = 1]':
rtl-tests.cc:15:42:   required from here
rtl-tests.cc:3:5: error: too many initializers for 'int [1]'
    3 |   : coeffs { cs... } {}
      |     ^~~~~~~~~~~~~~~~
# failed, GOOD

$ clang++ -c rtl-tests.cc
rtl-tests.cc:3:14: error: excess elements in array initializer
  : coeffs { cs... } {}
             ^~
rtl-tests.cc:15:5: note: in instantiation of function template specialization 'poly_int<1>::poly_int<int, int>' requested here
    poly_int<TARGET_DEFINED_VALUE> (1, 1);
    ^
1 error generated.
# failed, GOOD
Comment 2 Patrick Palka 2023-10-02 20:19:56 UTC
We probably want to diagnose this regardless of -fchecking.

Here's a similar IFNDR example that we don't diagnose even with -fchecking=2.

struct A { };

void g(A);

template<class T>
void f() {
  g(A(42));
}