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

Reply via email to