Bug 88395 - ICE: Segmentation fault signal terminated program cc1plus, with -std=c++2a -fconcepts
Summary: ICE: Segmentation fault signal terminated program cc1plus, with -std=c++2a -f...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 9.0
: P3 normal
Target Milestone: 9.3
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-invalid-code
: 92778 (view as bug list)
Depends on:
Blocks: concepts
  Show dependency treegraph
 
Reported: 2018-12-06 16:38 UTC by Emmanuel Le Trong
Modified: 2020-03-05 19:19 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2018-12-13 00:00:00


Attachments
Proposed Bug Fix (626 bytes, application/mbox)
2018-12-15 03:37 UTC, Nicholas Krause
Details
Proposed Proper Bug Fix (636 bytes, application/mbox)
2019-05-09 22:31 UTC, Nicholas Krause
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Emmanuel Le Trong 2018-12-06 16:38:26 UTC
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)
Comment 1 Nicholas Krause 2018-12-13 00:12:24 UTC
(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.
Comment 2 Emmanuel Le Trong 2018-12-13 10:31:14 UTC
(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.
Comment 3 Nicholas Krause 2018-12-13 10:35:57 UTC
(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.
Comment 4 Jonathan Wakely 2018-12-13 11:25:47 UTC
(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.
Comment 5 Jonathan Wakely 2018-12-13 11:32:49 UTC
(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.
Comment 6 Nicholas Krause 2018-12-15 03:37:54 UTC
Created attachment 45242 [details]
Proposed Bug Fix
Comment 7 Nicholas Krause 2018-12-15 03:39:11 UTC
(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.
Comment 8 Nicholas Krause 2019-05-09 22:31:20 UTC
Created attachment 46334 [details]
Proposed Proper Bug Fix
Comment 9 Nicholas Krause 2019-05-09 22:32:26 UTC
(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.
Comment 10 Jason Merrill 2019-06-12 21:16:04 UTC
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.
Comment 11 Nicholas Krause 2019-06-13 01:54:23 UTC
(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.
Comment 12 asutton 2019-11-27 15:09:54 UTC
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
Comment 13 Jason Merrill 2020-03-05 18:47:48 UTC
*** Bug 92778 has been marked as a duplicate of this bug. ***
Comment 14 GCC Commits 2020-03-05 19:14:09 UTC
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.
Comment 15 Jason Merrill 2020-03-05 19:19:01 UTC
Fixed for 9.3/10.