https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116442

            Bug ID: 116442
           Summary: ICE when calling immediate function in NSDMI with
                    aggregate initialization
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mital at mitalashok dot co.uk
  Target Milestone: ---

<https://eel.is/c++draft/expr.const#example-9> has:

    consteval int id(int i) { return i; }

    struct A {
      int x;
      int y = id(x);
    };

    template<class T>
    constexpr int k(int) {          // k<int> is not an immediate function
because A(42) is a
      return A(42).y;               // constant expression and thus not
immediate-escalating
    }

Which is justified by <http://eel.is/c++draft/expr.const#16.sentence-3>:

> An aggregate initialization is an immediate invocation if it evaluates a 
> default member initializer that has a subexpression that is an 
> immediate-escalating expression.

So since k<int> isn't an immediate function, we should be able to take it's
address: <https://godbolt.org/z/r9eWf96sW>

    int(*p)(int) = &k<int>;

<source>:13:16: error: taking address of an immediate function 'constexpr int
k(int) [with T = int]'
   13 | int(*p)(int) = &k<int>;
      |                ^~~~~~~
<source>:10:10: note: 'constexpr int k(int) [with T = int]' was promoted to an
immediate function because its body contains an immediate-escalating expression
'id((&*this)->A::x)'
   10 |   return A(42).y;               // constant expression and thus not
immediate-escalating
      |          ^~~~~


A similar test when not put in a `constexpr` function (so that it can't be
marked immediate-escalating): <https://godbolt.org/z/Ts47hnaqK>

    consteval int id(int i) { return i; }

    struct A {
      int x;
      int y = id(x);
    };

    int main() {
      return A{42}.y;
    }

Leads to an ICE:

test.cpp: In function ‘int main()’:
test.cpp:9:14: error: call to consteval function ‘id((&*this)->A::x)’ is not a
constant expression
    9 |   return A{42}.y;
      |              ^
test.cpp:9:14: internal compiler error: in cxx_eval_constant_expression, at
cp/constexpr.cc:8413
0x2792a05 internal_error(char const*, ...)
        ../../gcc/gcc/diagnostic-global-context.cc:491
0xa712e8 fancy_abort(char const*, int, char const*)
        ../../gcc/gcc/diagnostic.cc:1772
0x78a5b7 cxx_eval_constant_expression
        ../../gcc/gcc/cp/constexpr.cc:8413
0xad6ba5 cxx_eval_indirect_ref
        ../../gcc/gcc/cp/constexpr.cc:5964
0xad6ba5 cxx_eval_constant_expression
        ../../gcc/gcc/cp/constexpr.cc:7842
0xad863c cxx_eval_component_reference
        ../../gcc/gcc/cp/constexpr.cc:4567
0xad863c cxx_eval_constant_expression
        ../../gcc/gcc/cp/constexpr.cc:8015
0xad3232 cxx_bind_parameters_in_call
        ../../gcc/gcc/cp/constexpr.cc:1885
0xad3232 cxx_eval_call_expression
        ../../gcc/gcc/cp/constexpr.cc:3040
0xad6c23 cxx_eval_constant_expression
        ../../gcc/gcc/cp/constexpr.cc:7559
0xae2df6 cxx_eval_outermost_constant_expr
        ../../gcc/gcc/cp/constexpr.cc:8845
0xae3a13 cxx_constant_value(tree_node*, tree_node*, int)
        ../../gcc/gcc/cp/constexpr.cc:9001
0xb0f891 cxx_constant_value(tree_node*, int)
        ../../gcc/gcc/cp/cp-tree.h:8704
0xb0f891 cp_fold_immediate_r
        ../../gcc/gcc/cp/cp-gimplify.cc:1282
0xb142ff cp_fold_r
        ../../gcc/gcc/cp/cp-gimplify.cc:1372
0x173a9ac walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*,
tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*))
        ../../gcc/gcc/tree.cc:11479
0x173ae06 walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*,
tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*))
        ../../gcc/gcc/tree.cc:11567
0xb14397 cp_fold_r
        ../../gcc/gcc/cp/cp-gimplify.cc:1476
0x173a9ac walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*,
tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*))
        ../../gcc/gcc/tree.cc:11479
0x173abc2 walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*,
tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*))
        ../../gcc/gcc/tree.cc:11713
Please submit a full bug report, with preprocessed source (by using
-freport-bug).
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.

Clang and MSVC also do not accept this properly, but they just reject it
instead of crashing. See related discussion for Clang:
https://github.com/llvm/llvm-project/issues/104908
  • [Bug c++/116442] New: ICE when ... mital at mitalashok dot co.uk via Gcc-bugs

Reply via email to