Both trunk and 8.2.1 segfault on this valid snippet $ cat bug_4.cpp template <class T, class U> concept bool Concept2 = requires (T t, U u) { { t += u } -> T&; }; template <class T> concept bool Concept = Concept2 <T, T>; struct S { template <Concept T> constexpr S& operator += (T o); }; constexpr S operator * (S a, S b) { return a += b; } $ g++-9 -std=c++2a -fconcepts -c bug_4.cpp g++-9: internal compiler error: Segmentation fault signal terminated program cc1plus Please submit a full bug report, with preprocessed source if appropriate. See <https://gcc.gnu.org/bugs/> for instructions. $ g++-9 -v Using built-in specs. COLLECT_GCC=g++-9 COLLECT_LTO_WRAPPER=/home/manu/system/opt/gcc-9/libexec/gcc/x86_64-pc-linux-gnu/9.0.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc-9/configure --prefix=/home/manu/system/opt/gcc-9 --program-suffix=-9 Thread model: posix gcc version 9.0.0 20181204 (experimental) (GCC)
(In reply to Emmanuel Le Trong from comment #0) > Both trunk and 8.2.1 segfault on this valid snippet > > $ cat bug_4.cpp > template <class T, class U> > concept bool Concept2 = requires (T t, U u) > { > { t += u } -> T&; > }; > > template <class T> > concept bool Concept = Concept2 <T, T>; > > struct S > { > template <Concept T> > constexpr S& operator += (T o); > }; > constexpr S operator * (S a, S b) > { > return a += b; > } > > > > $ g++-9 -std=c++2a -fconcepts -c bug_4.cpp > g++-9: internal compiler error: Segmentation fault signal terminated program > cc1plus > Please submit a full bug report, > with preprocessed source if appropriate. > See <https://gcc.gnu.org/bugs/> for instructions. > > $ g++-9 -v > Using built-in specs. > COLLECT_GCC=g++-9 > COLLECT_LTO_WRAPPER=/home/manu/system/opt/gcc-9/libexec/gcc/x86_64-pc-linux- > gnu/9.0.0/lto-wrapper > Target: x86_64-pc-linux-gnu > Configured with: ../gcc-9/configure --prefix=/home/manu/system/opt/gcc-9 > --program-suffix=-9 > Thread model: posix > gcc version 9.0.0 20181204 (experimental) (GCC) First off that's just a valid snippet without a class definition so I was unable to build it against gcc itself to even check this is a bug. Further more can you check this is still happening and if so just report back with the exact code that builds but is giving you a segfault on the trunk branch.
(In reply to Nicholas Krause from comment #1) > First off that's just a valid snippet without a class definition so I was > unable to build it against gcc itself to even check this is a bug. Further > more can you check this is still happening and if so just report back with > the exact code that builds but is giving you a segfault on the trunk branch. I'm sorry I don't understand your requests. The compilation of this small piece of code causes the compiler (trunk 20181213) to crash, without further information.
(In reply to Emmanuel Le Trong from comment #2) > (In reply to Nicholas Krause from comment #1) > > First off that's just a valid snippet without a class definition so I was > > unable to build it against gcc itself to even check this is a bug. Further > > more can you check this is still happening and if so just report back with > > the exact code that builds but is giving you a segfault on the trunk branch. > > I'm sorry I don't understand your requests. The compilation of this small > piece of code causes the compiler (trunk 20181213) to crash, without further > information. test.cpp:2:5: error: ‘concept’ does not name a type; did you mean ‘constexpr’? concept bool Concept2 = requires (T t, U u) ^~~~~~~ constexpr test.cpp:2:5: note: ‘concept’ only available with -fconcepts test.cpp:8:5: error: ‘concept’ does not name a type; did you mean ‘constexpr’? concept bool Concept = Concept2 <T, T>; ^~~~~~~ constexpr test.cpp:8:5: note: ‘concept’ only available with -fconcepts test.cpp:12:19: error: ‘Concept’ has not been declared template <Concept T> ^~~~~~~ test.cpp:13:35: error: ‘T’ was not declared in this scope constexpr S& operator += (T o); ^ test.cpp:13:38: error: declaration of ‘operator+=’ as non-function constexpr S& operator += (T o); ^ test.cpp: In function ‘constexpr S operator*(S, S)’: test.cpp:17:18: error: no match for ‘operator+=’ (operand types are ‘S’ and ‘S’) return a += b; Is what I am getting because I don't have the class definition. I would like all of the code so that it builds properly and can check against a compiling working program.
(In reply to Nicholas Krause from comment #3) > Is what I am getting because I don't have the class definition. I would like > all of the code so that it builds properly and can check against a compiling > working program. No, it's what you're getting because you didn't use the -fconcepts flag which is necessary to enable the language feature. The example is fine, it's not missing anything, so I'm confirming the bug.
(In reply to Emmanuel Le Trong from comment #0) > Both trunk and 8.2.1 segfault on this valid snippet And 7.4.1 too. The flag -std=c++2a isn't relevant, only -fconcepts is needed.
Created attachment 45242 [details] Proposed Bug Fix
(In reply to Nicholas Krause from comment #6) > Created attachment 45242 [details] > Proposed Bug Fix This is my proposed fix after tracing it and reading it carefully seems that passing the NULL_TREE in rather than the correct decl tree of concepts is causing the bug. If this is correct I will just run the gcc test suite and post to the list.
Created attachment 46334 [details] Proposed Proper Bug Fix
(In reply to Nicholas Krause from comment #8) > Created attachment 46334 [details] > Proposed Proper Bug Fix This is the proper bug fix after tracing it seems and looking at other callers in that file. I tried pinging on the list twice but didn't get any reply so I'm attaching it here for people to merge if it's correct.
I don't think this is a valid testcase: operator+= requires Concept, but checking Concept depends on operator+=. It would be good for the compiler to detect this recursive dependency rather than recursing infinitely, of course.
(In reply to Jason Merrill from comment #10) > I don't think this is a valid testcase: operator+= requires Concept, but > checking Concept depends on operator+=. It would be good for the compiler > to detect this recursive dependency rather than recursing infinitely, of > course. I agree however I was going to test on clang but seems clang does not support concepts yet so didn't know if it would crash on that too. Still a nullptr on concepts expansion isn't good. Perhaps a better idea would be to warn about the infinite expansion than my PARM_CONSTR patch posted previously.
Author: asutton Date: Wed Nov 27 15:09:22 2019 New Revision: 278773 URL: https://gcc.gnu.org/viewcvs?rev=278773&root=gcc&view=rev Log: 2019-11-27 Andrew Sutton <asutton@lock3software.com> PR c++/88395 Prevent recursive satisfaction by adding requests to the instantiation stack. gcc/cp/ * constraint.cc (satisfy_declaration_constraints): Push tinst levels around satisfaction. gcc/testsuite/ * g++.dg/cpp2a/concepts-pr88395.C: New. * g++.dg/cpp2a/concepts-recursive-sat1.C: New. * g++.dg/cpp2a/concepts-recursive-sat2.C: New. * g++.dg/cpp2a/concepts-recursive-sat3.C: New. Added: trunk/gcc/testsuite/g++.dg/cpp2a/concepts-pr88395.C trunk/gcc/testsuite/g++.dg/cpp2a/concepts-recursive-sat1.C trunk/gcc/testsuite/g++.dg/cpp2a/concepts-recursive-sat2.C trunk/gcc/testsuite/g++.dg/cpp2a/concepts-recursive-sat3.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/constraint.cc trunk/gcc/testsuite/ChangeLog
*** Bug 92778 has been marked as a duplicate of this bug. ***
The releases/gcc-9 branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:e50627ff8cd54c3983614b34727323b333b9374d commit r9-8351-ge50627ff8cd54c3983614b34727323b333b9374d Author: Jason Merrill <jason@redhat.com> Date: Thu Mar 5 13:45:38 2020 -0500 c++: Avoid ICE on infinite recursion with concepts. This was simple enough to backport even though it's concepts. gcc/cp/ChangeLog 2020-03-05 Jason Merrill <jason@redhat.com> PR c++/88395 PR c++/93551 * constraint.cc (constraints_satisfied_p): Use push_tinst_level.
Fixed for 9.3/10.