Bug 105398 - [11 Regression][ICE] enum in array in lambda
Summary: [11 Regression][ICE] enum in array in lambda
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 12.0
: P2 normal
Target Milestone: 11.4
Assignee: Marek Polacek
URL:
Keywords: c++-lambda, ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2022-04-26 18:41 UTC by Egor Pugin
Modified: 2022-11-02 04:10 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work: 10.3.0
Known to fail: 11.1.0
Last reconfirmed: 2022-04-26 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Egor Pugin 2022-04-26 18:41:45 UTC
Works in 10.3, broken in 11.1 till trunk.
https://godbolt.org/z/x3z6WYroE
Comment 1 Egor Pugin 2022-04-26 18:43:11 UTC
auto f = [](auto &&m) {
    enum { _,e3,e2,e1,C4,C3,C2,C1 };
    static constexpr int x_coeffs[3][4] = {
        {e1,C2,C3,C4},
        {e2,C1,C3,C4},
        {e3,C1,C2,C4},
    };
};

int main() {
    f(0);
}



<source>: In instantiation of '<lambda(auto:1&&)> [with auto:1 = int]':
<source>:11:6:   required from here
<source>:4:10: internal compiler error: in tsubst_copy, at cp/pt.cc:16910
    4 |         {e1,C2,C3,C4},
      |          ^~
Comment 2 Marek Polacek 2022-04-26 19:01:17 UTC
Confirmed.  Started with r11-7993-g9f4c41147a41d0
Comment 3 Patrick Palka 2022-04-26 19:33:09 UTC
Looking into it..
Comment 4 Marek Polacek 2022-04-26 19:33:32 UTC
The patch above changed

-      if (TREE_CODE (template_type) == ENUMERAL_TYPE && !is_dependent_type
+      if (TREE_CODE (template_type) == ENUMERAL_TYPE
+         && !uses_template_parms (current_nonlambda_scope ())
          && !DECL_ALIAS_TEMPLATE_P (gen_tmpl))

but here current_nonlambda_scope () is ::, a NAMESPACE_DECL, which doesn't have a type, so is considered type-dependent.  So we don't call tsubst_enum.  That doesn't look right.
Comment 5 Patrick Palka 2022-04-26 19:43:27 UTC
(In reply to Marek Polacek from comment #4)
> The patch above changed
> 
> -      if (TREE_CODE (template_type) == ENUMERAL_TYPE && !is_dependent_type
> +      if (TREE_CODE (template_type) == ENUMERAL_TYPE
> +         && !uses_template_parms (current_nonlambda_scope ())
>           && !DECL_ALIAS_TEMPLATE_P (gen_tmpl))
> 
> but here current_nonlambda_scope () is ::, a NAMESPACE_DECL, which doesn't
> have a type, so is considered type-dependent.  So we don't call tsubst_enum.
> That doesn't look right.

Whoops, sorry Marek, didn't know you were already looking into this.  Your analysis makes sense to me :)
Comment 6 Marek Polacek 2022-04-26 19:55:03 UTC
Testing a fix.
Comment 7 GCC Commits 2022-04-27 17:09:22 UTC
The trunk branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>:

https://gcc.gnu.org/g:409edcca331296b53842c50d3b789e1b1ccc05e5

commit r12-8290-g409edcca331296b53842c50d3b789e1b1ccc05e5
Author: Marek Polacek <polacek@redhat.com>
Date:   Tue Apr 26 16:12:58 2022 -0400

    c++: enum in generic lambda at global scope [PR105398]
    
    We crash compiling this test since r11-7993 which changed
    lookup_template_class_1 so that we only call tsubst_enum when
    
      !uses_template_parms (current_nonlambda_scope ())
    
    But here current_nonlambda_scope () is the global NAMESPACE_DECL ::, which
    doesn't have a type, therefore is considered type-dependent.  So we don't
    call tsubst_enum, and crash in tsubst_copy/CONST_DECL because we didn't
    find the e1 enumerator.
    
    I don't think any namespace can depend on any template parameter, so
    this patch tweaks uses_template_parms.
    
            PR c++/105398
    
    gcc/cp/ChangeLog:
    
            * pt.cc (uses_template_parms): Return false for any NAMESPACE_DECL.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp1y/lambda-generic-enum2.C: New test.
Comment 8 Marek Polacek 2022-04-27 17:11:12 UTC
Fixed on trunk so far, will backport to 11.4.
Comment 9 GCC Commits 2022-04-27 17:14:17 UTC
The releases/gcc-11 branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>:

https://gcc.gnu.org/g:3a1358e5f38864bf5688a7b6db1fda482321a77a

commit r11-9941-g3a1358e5f38864bf5688a7b6db1fda482321a77a
Author: Marek Polacek <polacek@redhat.com>
Date:   Tue Apr 26 16:12:58 2022 -0400

    c++: enum in generic lambda at global scope [PR105398]
    
    We crash compiling this test since r11-7993 which changed
    lookup_template_class_1 so that we only call tsubst_enum when
    
      !uses_template_parms (current_nonlambda_scope ())
    
    But here current_nonlambda_scope () is the global NAMESPACE_DECL ::, which
    doesn't have a type, therefore is considered type-dependent.  So we don't
    call tsubst_enum, and crash in tsubst_copy/CONST_DECL because we didn't
    find the e1 enumerator.
    
    I don't think any namespace can depend on any template parameter, so
    this patch tweaks uses_template_parms.
    
            PR c++/105398
    
    gcc/cp/ChangeLog:
    
            * pt.c (uses_template_parms): Return false for any NAMESPACE_DECL.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp1y/lambda-generic-enum2.C: New test.
    
    (cherry picked from commit 409edcca331296b53842c50d3b789e1b1ccc05e5)
Comment 10 Marek Polacek 2022-04-27 17:14:29 UTC
Fixed.