https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100288
Bug ID: 100288 Summary: g++-11 internal error and fails to precompile a concept Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: f.b.brokken at rug dot nl Target Milestone: --- Created attachment 50687 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=50687&action=edit The compiler generated a-bug.ii file This bug report is using: g++ (Debian 11-20210424-1) 11.0.1 20210424 (prerelease) [gcc-11 revision 7a7fc01b9d2:ab3797fc424:5b2ac9b40c325e9209c0bd55955db84aad4a0cc5] On a Debian Linux system, running bullseye (testing) where the latest g++ compiler is the one mentioned above. The following input was processed by the compiler. The source file (named 'bug.h') shown between the ----- lines is precompiled using the command: g++ --std=c++2a -Wall -O2 -fdiagnostics-color=never -x c++-header bug.h The precompilation fails in some cases when using the concept OstreamInsertable. Specific comment and notes are added beyond the following 'bug.h' source file. If you need any additional information, please contact me. The bug.h source file: ---------------------------------------------------------------------------- #ifndef INCLUDED_CSVTABINS_ #define INCLUDED_CSVTABINS_ // #include <ostream> instead of iosfwd makes no difference #include <iosfwd> template <typename Type> concept OstreamInsertable = requires(std::ostream &out, Type value) { out << value; }; // when using typename instead of the above concept : no error (1) // e.g., by activating the following #define //#define OstreamInsertable typename struct FMT { enum Align {}; typedef FMT (*FMTFun)(unsigned, unsigned); typedef FMT (*FMTHline)(unsigned); }; class CSVTabIns { template <OstreamInsertable Type> friend void operator<<(CSVTabIns &tab, Type const &value); // when omitted: results in bugreport1 (2) friend CSVTabIns &operator<<(CSVTabIns &tab, FMT const &fmt); friend void operator<<(CSVTabIns &tab, FMT::FMTHline); }; // when defined here: precompilation error (3) // template <OstreamInsertable Type> inline void operator<<(CSVTabIns &&tab, Type const &value) {} inline void operator<<(CSVTabIns &tab, FMT::FMTHline hline) { // when the insertion is omitted: no precompilation error tab << (*hline)(1); // insert hline in the next column } // when defined here: no precompilation error (4) //template <OstreamInsertable Type> //inline void operator<<(CSVTabIns &&tab, Type const &value) //{} #endif ----------------------------------------------------------------------- At (1): when using 'typename' instead of the 'OstreamInsertable' the precompilation completes flawlessly. In that case (2) may either be kept or commented out, (3) is used, (4) is commented out In the following cases the '#define OstreamInsertable typename' was commented out, resulting in: At (2): the friend declaration was kept: (3) was commented out, (4) was activated: precompilation completed flawlessly (3) was kept, (4) was commented out: results in a precompilation error, but the error message is (at least for me) not very helpful: bug.h:11:13: required by substitution of ‘template<class Type> requires OstreamInsertable<Type> void operator<<(CSVTabIns&, const Type&) [with Type = FMT]’ bug.h:46:22: required from here bug.h:8:9: required for the satisfaction of ‘OstreamInsertable<Type>’ [with Type = FMT] bug.h:9:5: in requirements with ‘std::ostream& out’, ‘Type value’ [with Type = FMT] bug.h:9:5: error: satisfaction of atomic constraint ‘requires(std::ostream& out, Type value) {out << value;} [with Type = Type]’ depends on itself 9 | requires(std::ostream &out, Type value) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 10 | { | ~ 11 | out << value; | ~~~~~~~~~~~~~ 12 | }; | ~ At (2): when the friend declaration is commented out: (3) was commented out, (4) was activated: results in a precompilation error: bug.h: In function ‘void operator<<(CSVTabIns&, FMT::FMTHline)’: bug.h:46:9: error: no match for ‘operator<<’ (operand types are ‘CSVTabIns’ and ‘FMT’) 46 | tab << (*hline)(1); // insert hline in the next column | ~~~ ^~ ~~~~~~~~~~~ | | | | CSVTabIns FMT bug.h:30:17: note: candidate: ‘template<class Type> requires OstreamInsertable<Type> void operator<<(CSVTabIns&, const Type&)’ 30 | friend void operator<<(CSVTabIns &tab, Type const &value); | ^~~~~~~~ bug.h:30:17: note: template argument deduction/substitution failed: bug.h:30:17: note: constraints not satisfied bug.h: In substitution of ‘template<class Type> requires OstreamInsertable<Type> void operator<<(CSVTabIns&, const Type&) [with Type = FMT]’: bug.h:46:22: required from here bug.h:8:9: required for the satisfaction of ‘OstreamInsertable<Type>’ [with Type = FMT] bug.h:9:5: in requirements with ‘std::ostream& out’, ‘Type value’ [with Type = FMT] bug.h:11:13: note: the required expression ‘(out << value)’ is invalid 11 | out << value; | ~~~~^~~~~~~~ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more detail bug.h:43:13: note: candidate: ‘void operator<<(CSVTabIns&, FMT::FMTHline)’ 43 | inline void operator<<(CSVTabIns &tab, FMT::FMTHline hline) | ^~~~~~~~ bug.h:43:54: note: no known conversion for argument 2 from ‘FMT’ to ‘FMT::FMTHline’ {aka ‘FMT (*)(unsigned int)’} 43 | inline void operator<<(CSVTabIns &tab, FMT::FMTHline hline) | ~~~~~~~~~~~~~~^~~~~ (3) was kept, (4) was commented out: results in a compiler bugreport requesting me to submit the bug-report. The bugreport is: bug.h: In substitution of ‘template<class Type> requires OstreamInsertable<Type> void operator<<(CSVTabIns&&, const Type&) [with Type = FMT]’: bug.h:11:13: required by substitution of ‘template<class Type> requires OstreamInsertable<Type> void operator<<(CSVTabIns&, const Type&) [with Type = FMT]’ bug.h:46:22: required from here bug.h:8:9: required for the satisfaction of ‘OstreamInsertable<Type>’ [with Type = FMT] bug.h:9:5: in requirements with ‘std::ostream& out’, ‘Type value’ [with Type = FMT] bug.h:9:5: error: satisfaction of atomic constraint ‘requires(std::ostream& out, Type value) {out << value;} [with Type = Type]’ depends on itself 9 | requires(std::ostream &out, Type value) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 10 | { | ~ 11 | out << value; | ~~~~~~~~~~~~~ 12 | }; | ~ bug.h: In function ‘void operator<<(CSVTabIns&, FMT::FMTHline)’: bug.h:46:9: error: no match for ‘operator<<’ (operand types are ‘CSVTabIns’ and ‘FMT’) 46 | tab << (*hline)(1); // insert hline in the next column | ~~~ ^~ ~~~~~~~~~~~ | | | | CSVTabIns FMT bug.h:40:13: note: candidate: ‘template<class Type> requires OstreamInsertable<Type> void operator<<(CSVTabIns&&, const Type&)’ 40 | inline void operator<<(CSVTabIns &&tab, Type const &value) | ^~~~~~~~ bug.h:40:13: note: template argument deduction/substitution failed: bug.h:40:13: note: constraints not satisfied bug.h: In substitution of ‘template<class Type> requires OstreamInsertable<Type> void operator<<(CSVTabIns&&, const Type&) [with Type = FMT]’: bug.h:11:13: required by substitution of ‘template<class Type> requires OstreamInsertable<Type> void operator<<(CSVTabIns&&, const Type&) [with Type = FMT]’ bug.h:46:22: required from here bug.h:8:9: required for the satisfaction of ‘OstreamInsertable<Type>’ [with Type = FMT] bug.h:9:5: in requirements with ‘std::ostream& out’, ‘Type value’ [with Type = FMT] bug.h:11:13: internal compiler error: in get, at cp/constraint.cc:2666 11 | out << value; | ~~~~^~~~~~~~ 0xc73b0f satisfaction_cache::get() ../../src/gcc/cp/constraint.cc:2666 0xc79264 satisfy_atom ../../src/gcc/cp/constraint.cc:2942 0xc79264 satisfy_constraint_r ../../src/gcc/cp/constraint.cc:3047 0xc797aa satisfy_normalized_constraints ../../src/gcc/cp/constraint.cc:3072 0xc79a24 satisfy_declaration_constraints ../../src/gcc/cp/constraint.cc:3280 0xc79a24 constraint_satisfaction_value ../../src/gcc/cp/constraint.cc:3300 0x9f6743 constraints_satisfied_p(tree_node*, tree_node*) ../../src/gcc/cp/constraint.cc:3337 0x9f6743 constraints_satisfied_p(tree_node*, tree_node*) ../../src/gcc/cp/constraint.cc:3331 0x9f6743 fn_type_unification(tree_node*, tree_node*, tree_node*, tree_node* const*, unsigned int, tree_node*, unification_kind_t, int, conversion**, bool, bool) ../../src/gcc/cp/pt.c:21686 0x16e0aa9 add_template_candidate_real(z_candidate**, tree_node*, tree_node*, tree_node*, tree_node*, vec<tree_node*, va_gc, vl_embed> const*, tree_node*, tree_node*, tree_node*, int, tree_node*, unification_kind_t, int) [clone .isra.0] ../../src/gcc/cp/call.c:3456 0x14bd4d6 add_template_candidate ../../src/gcc/cp/call.c:3541 0x14bd4d6 add_candidates ../../src/gcc/cp/call.c:6031 0x15dee95 add_operator_candidates ../../src/gcc/cp/call.c:6153 0x14bddbc build_new_op_1 ../../src/gcc/cp/call.c:6376 0x14bc9d3 build_new_op(op_location_t const&, tree_code, int, tree_node*, tree_node*, tree_node*, tree_node**, int) ../../src/gcc/cp/call.c:6764 0x14bc9d3 build_x_binary_op(op_location_t const&, tree_code, tree_node*, tree_code, tree_node*, tree_code, tree_node**, int) ../../src/gcc/cp/typeck.c:4323 0x154d551 tsubst_copy_and_build(tree_node*, tree_node*, int, tree_node*, bool, bool) ../../src/gcc/cp/pt.c:19919 0x15d5be7 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool) ../../src/gcc/cp/pt.c:19198 0x1325a15 tsubst_valid_expression_requirement(tree_node*, tree_node*, sat_info) [clone .isra.0] ../../src/gcc/cp/constraint.cc:1959 0xc7829a tsubst_simple_requirement ../../src/gcc/cp/constraint.cc:1993 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <file:///usr/share/doc/gcc-11/README.Bugs> for instructions.