Bug 98043 - [8/9 Regression] ICE ‘verify_gimple’ failed since r5-3726-g083e891e69429f93b958f6c18e2d52f515bae572
Summary: [8/9 Regression] ICE ‘verify_gimple’ failed since r5-3726-g083e891e69429f93b9...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 11.0
: P2 normal
Target Milestone: 8.5
Assignee: Marek Polacek
URL:
Keywords: ice-checking
: 97634 (view as bug list)
Depends on:
Blocks:
 
Reported: 2020-11-28 13:54 UTC by Ben Wiederhake
Modified: 2021-12-25 00:56 UTC (History)
6 users (show)

See Also:
Host:
Target: x86_64-*-*
Build:
Known to work: 9.3.0
Known to fail: 10.2.0, 11.0
Last reconfirmed: 2020-11-30 00:00:00


Attachments
Preprocessed source code (212 bytes, text/plain)
2020-11-28 13:54 UTC, Ben Wiederhake
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ben Wiederhake 2020-11-28 13:54:45 UTC
Created attachment 49640 [details]
Preprocessed source code

Compiling the following code crashes g++-10 and g++-11, but not g++-9:

    // g++ -std=c++2a -o /tmp/example.cpp.o -c example.cpp
    enum class MyEnumClass { A };
    struct MyClass {
        MyEnumClass foobar : 8 { MyEnumClass::A };
    };
    bool some_function(MyClass x)
    {
        switch (x.foobar) {
        case MyEnumClass::A:
            return false;
        }
    }

See at the bottom the exact invocation, error messages, and g++ versions.

The enum-class, bit-packing, the seemingly incomplete switch-case, non-constant
switch-argument, all seem to be necessary to trigger the bug.

This bug seems very similar to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97634 , but it's a different platform. Feel free to merge if it's the same bug.

* What was the outcome of this action?

Compiler crash (error message see below)

* What outcome did you expect instead?

Either a successful compilation, or a compilation error; but not a compiler
crash.


Full error message and versions:

$ /usr/bin/g++-9 --version
g++-9 (Debian 9.3.0-18) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ /usr/bin/g++-9 -std=c++2a -o /tmp/example.cpp.o -c example.cpp
example.cpp: In function ‘bool some_function(MyClass)’:
example.cpp:12:1: warning: control reaches end of non-void function [-Wreturn-
type]
   12 | }
      | ^

$ /usr/bin/g++-10 --version
g++-10 (Debian 10.2.0-16) 10.2.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ /usr/bin/g++-10 -std=c++2a -o /tmp/example.cpp.o -c example.cpp
example.cpp: In function ‘bool some_function(MyClass)’:
example.cpp:6:6: error: type precision mismatch in switch statement
    6 | bool some_function(MyClass x)
      |      ^~~~~~~~~~~~~
switch (_1) <default: <D.2095>, case 0: <D.2092>>
example.cpp:6:6: internal compiler error: ‘verify_gimple’ failed
0x128422d verify_gimple_in_seq(gimple*)
        ../../src/gcc/tree-cfg.c:5144
0xf85436 gimplify_body(tree_node*, bool)
        ../../src/gcc/gimplify.c:14888
0xf856a3 gimplify_function_tree(tree_node*)
        ../../src/gcc/gimplify.c:14978
0xdbbe27 cgraph_node::analyze()
        ../../src/gcc/cgraphunit.c:670
0xdbee27 analyze_functions
        ../../src/gcc/cgraphunit.c:1227
0xdbf9f2 symbol_table::finalize_compilation_unit()
        ../../src/gcc/cgraphunit.c:2986
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-10/README.Bugs> for instructions.

$ /usr/lib/gcc-snapshot/bin/g++ --version
g++ (Debian 20201127-1) 11.0.0 20201127 (experimental) [master revision 3493b0c3281:5c47353bc97:5e9f814d754be790aec5b69a95699a8af2654058]
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ /usr/lib/gcc-snapshot/bin/g++ -std=c++2a -o /tmp/example.cpp.o -c example.cpp
example.cpp: In function 'bool some_function(MyClass)':
example.cpp:6:6: error: type precision mismatch in switch statement
    6 | bool some_function(MyClass x)
      |      ^~~~~~~~~~~~~
switch (_1) <default: <D.2107>, case 0: <D.2104>>
example.cpp:6:6: internal compiler error: 'verify_gimple' failed
0x12f35bd verify_gimple_in_seq(gimple*)
	../../src/gcc/tree-cfg.c:5119
0x1006b66 gimplify_body(tree_node*, bool)
	../../src/gcc/gimplify.c:15329
0x1006ced gimplify_function_tree(tree_node*)
	../../src/gcc/gimplify.c:15400
0xe37367 cgraph_node::analyze()
	../../src/gcc/cgraphunit.c:670
0xe39e27 analyze_functions
	../../src/gcc/cgraphunit.c:1235
0xe3aa1d symbol_table::finalize_compilation_unit()
	../../src/gcc/cgraphunit.c:2513
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-snapshot/README.Bugs> for instructions.

Downstream ticket:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=976024

Your bugs page says you also want a preprocessed source – I don't see how it's useful, but sure: Please find attached the preprocessed file "example.ii".

Cheers,
Ben
Comment 1 Martin Liška 2020-11-30 08:16:57 UTC
Started with Jakub's revision.
Comment 2 Jakub Jelinek 2020-11-30 13:16:54 UTC
The ICE is much older is you remove the for the ICE unnecessary C++20 initializer of the bitfield.

enum class B { A };
struct C { B c : 8; };

bool
foo (C x)
{
  switch (x.c)
    {
    case B::A:
      return false;
    default:
      return true;
    }
}
Comment 3 Marek Polacek 2020-11-30 14:22:24 UTC
Mine then.
Comment 4 Marek Polacek 2020-12-01 23:44:29 UTC
Candidate fix:

--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -3711,6 +3711,10 @@ pop_switch (void)
     SWITCH_STMT_ALL_CASES_P (cs->switch_stmt) = 1;
   if (!cs->break_stmt_seen_p)
     SWITCH_STMT_NO_BREAK_P (cs->switch_stmt) = 1;
+  if (SWITCH_STMT_TYPE (cs->switch_stmt)
+      && SCOPED_ENUM_P (SWITCH_STMT_TYPE (cs->switch_stmt)))
+    SWITCH_STMT_TYPE (cs->switch_stmt)
+      = TREE_TYPE (SWITCH_STMT_COND (cs->switch_stmt));
   gcc_assert (!cs->in_loop_body_p);
   splay_tree_delete (cs->cases);
   switch_stack = switch_stack->next;
Comment 5 GCC Commits 2020-12-07 17:38:38 UTC
The master branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>:

https://gcc.gnu.org/g:7482d5a3acb7a8a5564f5cddc4f9d2ebbaea75e4

commit r11-5829-g7482d5a3acb7a8a5564f5cddc4f9d2ebbaea75e4
Author: Marek Polacek <polacek@redhat.com>
Date:   Wed Dec 2 10:47:49 2020 -0500

    c++: ICE with switch and scoped enum bit-fields [PR98043]
    
    In this testcase we are crashing trying to gimplify a switch, because
    the types of the switch condition and case constants have different
    TYPE_PRECISIONs.
    
    This started with my r5-3726 fix: SWITCH_STMT_TYPE is supposed to be the
    original type of the switch condition before any conversions, so in the
    C++ FE we need to use unlowered_expr_type to get the unlowered type of
    enum bit-fields.
    
    Normally, the switch type is subject to integral promotions, but here
    we have a scoped enum type and those don't promote:
    
      enum class B { A };
      struct C { B c : 8; };
    
      switch (x.c) // type B
        case B::A: // type int, will be converted to B
    
    Here TREE_TYPE is "signed char" but SWITCH_STMT_TYPE is "B".  When
    gimplifying this in gimplify_switch_expr, the index type is "B" and
    we convert all the case values to "B" in preprocess_case_label_vec,
    but SWITCH_COND is of type "signed char": gimple_switch_index should
    be the (possibly promoted) type, not the original type, so we gimplify
    the "x.c" SWITCH_COND to a SSA_NAME of type "signed char".  And then
    we crash because the precision of the index type doesn't match the
    precision of the case value type.
    
    I think it makes sense to do the following; at the end of pop_switch
    we've already issued the switch warnings, and since scoped enums don't
    promote, it should be okay to use the type of SWITCH_STMT_COND.  The
    r5-3726 change was about giving warnings for enum bit-fields anyway.
    
    gcc/cp/ChangeLog:
    
            PR c++/98043
            * decl.c (pop_switch): If SWITCH_STMT_TYPE is a scoped enum type,
            set it to the type of SWITCH_STMT_COND.
    
    gcc/testsuite/ChangeLog:
    
            PR c++/98043
            * g++.dg/cpp0x/enum41.C: New test.
Comment 6 Marek Polacek 2020-12-07 17:51:56 UTC
Fixed on trunk thus far.
Comment 7 Ben Wiederhake 2020-12-07 21:03:31 UTC
A testcase got added in PR 98043. Yay!

The testcase contains a `default:` in the switch-case statement. Wasn't it the case that the bug got triggered by a *lack* of `default:` case?
Comment 8 Marek Polacek 2020-12-07 21:08:53 UTC
(In reply to Ben Wiederhake from comment #7)
> A testcase got added in PR 98043. Yay!
> 
> The testcase contains a `default:` in the switch-case statement. Wasn't it
> the case that the bug got triggered by a *lack* of `default:` case?

No, it was about a type mismatch between the type of the controlling expression, and the type of the case value.

Thanks for reporting this issue.
Comment 9 Ben Wiederhake 2020-12-08 22:07:48 UTC
I totally forgot to say it:

Thanks for fixing it so quickly! :D

When I saw https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97634 I was afraid it would suffer a slow death – but nope, fixed within a few days. Awesome! Now I only have to wait for the next release, and my OS's package maintainers. :)
Comment 10 Marek Polacek 2020-12-08 22:25:31 UTC
*** Bug 97634 has been marked as a duplicate of this bug. ***
Comment 11 GCC Commits 2021-01-05 21:30:35 UTC
The releases/gcc-10 branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>:

https://gcc.gnu.org/g:48aa64322e824d674b955459ea3816f3047629a3

commit r10-9206-g48aa64322e824d674b955459ea3816f3047629a3
Author: Marek Polacek <polacek@redhat.com>
Date:   Wed Dec 2 10:47:49 2020 -0500

    c++: ICE with switch and scoped enum bit-fields [PR98043]
    
    In this testcase we are crashing trying to gimplify a switch, because
    the types of the switch condition and case constants have different
    TYPE_PRECISIONs.
    
    This started with my r5-3726 fix: SWITCH_STMT_TYPE is supposed to be the
    original type of the switch condition before any conversions, so in the
    C++ FE we need to use unlowered_expr_type to get the unlowered type of
    enum bit-fields.
    
    Normally, the switch type is subject to integral promotions, but here
    we have a scoped enum type and those don't promote:
    
      enum class B { A };
      struct C { B c : 8; };
    
      switch (x.c) // type B
        case B::A: // type int, will be converted to B
    
    Here TREE_TYPE is "signed char" but SWITCH_STMT_TYPE is "B".  When
    gimplifying this in gimplify_switch_expr, the index type is "B" and
    we convert all the case values to "B" in preprocess_case_label_vec,
    but SWITCH_COND is of type "signed char": gimple_switch_index should
    be the (possibly promoted) type, not the original type, so we gimplify
    the "x.c" SWITCH_COND to a SSA_NAME of type "signed char".  And then
    we crash because the precision of the index type doesn't match the
    precision of the case value type.
    
    I think it makes sense to do the following; at the end of pop_switch
    we've already issued the switch warnings, and since scoped enums don't
    promote, it should be okay to use the type of SWITCH_STMT_COND.  The
    r5-3726 change was about giving warnings for enum bit-fields anyway.
    
    gcc/cp/ChangeLog:
    
            PR c++/98043
            * decl.c (pop_switch): If SWITCH_STMT_TYPE is a scoped enum type,
            set it to the type of SWITCH_STMT_COND.
    
    gcc/testsuite/ChangeLog:
    
            PR c++/98043
            * g++.dg/cpp0x/enum41.C: New test.
    
    (cherry picked from commit 7482d5a3acb7a8a5564f5cddc4f9d2ebbaea75e4)
Comment 12 Marek Polacek 2021-01-05 21:35:55 UTC
Fixed in GCC 10 too.