Hi! Seems I've missed one thing, as the first hunk in https://github.com/cplusplus/draft/commit/c8e68ed202b4a9260616bcee8a9768b5dca4bbca changes the wording so that only potentially-evaluated id-expressions that denote immediate functions must appear only in the specified contexts. That IMO means that in unevaluated contexts there aren't such restrictions anymore, so I think in unevaluated contexts one should be able to take the address of an immediate function.
The following patch implements it, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2020-02-28 Jakub Jelinek <ja...@redhat.com> P1937R2 - Fixing inconsistencies between const{expr,eval} functions * typeck.c (cp_build_addr_expr_1): Allow taking address of immediate functions in unevaluated contexts. * g++.dg/cpp2a/consteval3.C: Change dg-error about taking address of immediate function in unevaluated contexts into dg-bogus. * g++.dg/cpp2a/consteval16.C: New test. --- gcc/cp/typeck.c.jj 2020-02-27 09:28:46.328957157 +0100 +++ gcc/cp/typeck.c 2020-02-27 12:51:35.798841665 +0100 @@ -6325,6 +6325,7 @@ cp_build_addr_expr_1 (tree arg, bool str tree stripped_arg = tree_strip_any_location_wrapper (arg); if (TREE_CODE (stripped_arg) == FUNCTION_DECL && DECL_IMMEDIATE_FUNCTION_P (stripped_arg) + && cp_unevaluated_operand == 0 && (current_function_decl == NULL_TREE || !DECL_IMMEDIATE_FUNCTION_P (current_function_decl))) { --- gcc/testsuite/g++.dg/cpp2a/consteval3.C.jj 2020-02-24 15:24:33.792751698 +0100 +++ gcc/testsuite/g++.dg/cpp2a/consteval3.C 2020-02-27 12:55:19.271507525 +0100 @@ -31,8 +31,8 @@ consteval consteval int f11 () { return struct U { consteval ~U () {} }; // { dg-error "a destructor cannot be 'consteval'" } struct V { consteval int v = 5; }; // { dg-error "non-static data member 'v' declared 'consteval'" } struct W { consteval static int w; }; // { dg-error "static data member 'w' declared 'consteval'" } -int i = sizeof (&f6); // { dg-error "taking address of an immediate function 'consteval int f6\\(int\\)'" } -using j = decltype (&f6); // { dg-error "taking address of an immediate function 'consteval int f6\\(int\\)'" } +int i = sizeof (&f6); // { dg-bogus "taking address of an immediate function 'consteval int f6\\(int\\)'" } +using j = decltype (&f6); // { dg-bogus "taking address of an immediate function 'consteval int f6\\(int\\)'" } int k = sizeof (f6 (d)); // { dg-bogus "the value of 'd' is not usable in a constant expression" } using l = decltype (f6 (d)); // { dg-bogus "the value of 'd' is not usable in a constant expression" } bool m = noexcept (f6 (d)); // { dg-bogus "the value of 'd' is not usable in a constant expression" } --- gcc/testsuite/g++.dg/cpp2a/consteval16.C.jj 2020-02-27 12:55:25.414415871 +0100 +++ gcc/testsuite/g++.dg/cpp2a/consteval16.C 2020-02-27 12:56:55.891065989 +0100 @@ -0,0 +1,7 @@ +// { dg-do compile } +// { dg-options "-std=c++2a" } + +consteval int foo () { return 0; } +int bar (int (*) ()); +auto sz = sizeof (bar (foo)); // { dg-bogus "taking address of an immediate function" } +decltype (bar (foo)) baz; // { dg-bogus "taking address of an immediate function" } Jakub