From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 71A553858C24 for ; Fri, 5 Apr 2024 03:56:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 71A553858C24 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 71A553858C24 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1712289394; cv=none; b=Wqy1BYPC1iTM8yExvGtxzAekod+7JehgOd81Rob/1hXWJY59eEjOnhXT1b5lS2HahkaOHr8b5SvvKW8TW6XjF6MxU0JSyGoAdyYSeaK/tkQEOscQZFg+KSCkqJXfb5txhKS5ct2BhWZwfZTGrMeC58xqsYlR8QxKe5dHRr3/hl8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1712289394; c=relaxed/simple; bh=PWr/FO5tUE/cO9nG4m9dYZ09U4WNP8acFqf/CbrvigQ=; h=DKIM-Signature:Message-ID:Date:MIME-Version:Subject:To:From; b=JGiuQKeoyusPjIHii4XGZXG6wlgfJowLXp5BQKlaWyWlrmoJfd8lnm1PcA+MnODdulYi0pFhbWSQ4rrTZBKBTJxBAfvkaUR/4LLGyelF/HKKKV2aDoLIm/x9Hle6RlAgFtzf1hvYGMihOXqrKtBCvH4b9KMp1Y6km53037nX67k= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1712289392; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=novQ92jVjNDT6XBEl7HlMdFq7Xad67V43XwneY1myNc=; b=LgPgVe6JuZT/3mqYcxyhQpWpo5Z/9Tq1abcoubTlG28m75xLjWO/2/6iYz0KOI/kltZaAC Oxr9rxqDgjkjo8TBoJUvkoWgQkQHWf3ck4vhxfD68Rvcs5DZUU6i0sSEM9jXrHw/MOg6G/ 8Jm0FTIb/T67jmHo03POgW3NVO+bXcE= Received: from mail-ua1-f71.google.com (mail-ua1-f71.google.com [209.85.222.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-516-h2nrLTJeN-6qbg3KaV3pYg-1; Thu, 04 Apr 2024 23:56:30 -0400 X-MC-Unique: h2nrLTJeN-6qbg3KaV3pYg-1 Received: by mail-ua1-f71.google.com with SMTP id a1e0cc1a2514c-7e3bb7443fbso805734241.1 for ; Thu, 04 Apr 2024 20:56:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712289390; x=1712894190; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=novQ92jVjNDT6XBEl7HlMdFq7Xad67V43XwneY1myNc=; b=GV/MVonczXz6b9iybu1GVCSYHEaHa6r9IIHn+DWwFUZW/Tjbbhko5/vbI8a7JjJLNa e73SLW68kVFWRyDlptp/1x8bGyHLykRoZnvtUYvZzA0R9Jlopd1KovW7SE47VNLH1hvw YtBrAJUYLWPkQN0A+q5GFSUuvzQZfPiZ0GmRj7zUH+L9zj3nkcVoSzIA2IK1f20j3yVb O8ZNMO5I6GtSaZZFENvoIvn0mFX3ue1xcjwQbsOMupay1fJi1GIJMioq9wxeYBRw5zrN Xdkl2XNRFWLL0uGZqTFt9fwBK000WDs/etmImb1QRt372xLMCDzOWAvP5VrmorSG3blr 1/qg== X-Gm-Message-State: AOJu0YxKBDzSQibWh/57botA/2UJRTL1OHyHODhjwlYfWCKRWE+OYgKA anBZnbn4rH5WDmHhJoq1JKwJ9+IYRVN2J5NfWxd0ziNr4P4i8JLwTJILDIXeVe0TqTVmY7e4/WT 19iuPURbZHU92PX7yEqlUJs5vZcfdN+ZCXKEhHRYUOTlLFM18/bXeteI= X-Received: by 2002:a05:6102:3749:b0:479:d50d:85de with SMTP id u9-20020a056102374900b00479d50d85demr516296vst.19.1712289389867; Thu, 04 Apr 2024 20:56:29 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHKh6YC7lNDTNXj6z8R0xPpDm7L3rkTp2g/uubcgsQ5dubyUustJH3QjfciTEvof0IVhNp5yQ== X-Received: by 2002:a05:6102:3749:b0:479:d50d:85de with SMTP id u9-20020a056102374900b00479d50d85demr516283vst.19.1712289389471; Thu, 04 Apr 2024 20:56:29 -0700 (PDT) Received: from [192.168.9.172] ([38.125.9.91]) by smtp.gmail.com with ESMTPSA id ev11-20020a0561302e8b00b007e0f80aa61asm121787uab.14.2024.04.04.20.56.28 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 04 Apr 2024 20:56:28 -0700 (PDT) Message-ID: <37d7a173-92e2-4fdd-b3b1-14e867f568e1@redhat.com> Date: Thu, 4 Apr 2024 23:56:27 -0400 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v2] c++: constexpr error with fn redecl in local scope [PR111132] To: Marek Polacek Cc: GCC Patches , Jakub Jelinek References: <20240402175237.482119-1-polacek@redhat.com> <0a3fe0db-9466-478b-bd4f-2957863b585c@redhat.com> From: Jason Merrill In-Reply-To: X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 4/4/24 19:15, Marek Polacek wrote: > On Thu, Apr 04, 2024 at 05:28:22PM -0400, Jason Merrill wrote: >> On 4/4/24 14:43, Marek Polacek wrote: >>> On Wed, Apr 03, 2024 at 01:14:46PM -0400, Jason Merrill wrote: >>>> On 4/2/24 13:52, Marek Polacek wrote: >>>>> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/13? >>>>> >>>>> -- >8 -- >>>>> We evaluate constexpr functions on the original, pre-genericization bodies. >>>>> That means that the function body we're evaluating will not have gone >>>>> through cp_genericize_r's "Map block scope extern declarations to visible >>>>> declarations with the same name and type in outer scopes if any". Here: >>>>> >>>>> constexpr bool bar() { return true; } // #1 >>>>> constexpr bool foo() { >>>>> constexpr bool bar(void); // #2 >>>>> return bar(); >>>>> } >>>>> >>>>> it means that we: >>>>> 1) register_constexpr_fundef (#1) >>>>> 2) cp_genericize (#1) >>>>> nothing interesting happens >>>>> 3) register_constexpr_fundef (foo) >>>>> does copy_fn, so we have two copies of the BIND_EXPR >>>>> 4) cp_genericize (foo) >>>>> this remaps #2 to #1, but only on one copy of the BIND_EXPR >>>>> 5) retrieve_constexpr_fundef (foo) >>>>> we find it, no problem >>>>> 6) retrieve_constexpr_fundef (#2) >>>>> and here #2 isn't found in constexpr_fundef_table, because >>>>> we're working on the BIND_EXPR copy where #2 wasn't mapped to #1 >>>>> so we fail. We've only registered #1. >>>>> >>>>> It should work to use DECL_LOCAL_DECL_ALIAS (which used to be >>>>> extern_decl_map). We evaluate constexpr functions on pre-cp_fold >>>>> bodies to avoid diagnostic problems, but the remapping I'm proposing >>>>> should not interfere with diagnostics. >>>>> >>>>> This is not a problem for a global scope redeclaration; there we go >>>>> through duplicate_decls which keeps the DECL_UID: >>>>> DECL_UID (olddecl) = olddecl_uid; >>>>> and DECL_UID is what constexpr_fundef_hasher::hash uses. >>>>> >>>>> PR c++/111132 >>>>> >>>>> gcc/cp/ChangeLog: >>>>> >>>>> * constexpr.cc (get_function_named_in_call): If there's >>>>> a DECL_LOCAL_DECL_ALIAS, use it. >>>> >>>> Perhaps this function should use cp_get_fndecl_from_callee, and this change >>>> should be made there instead? >>> >>> It doesn't seem that get_function_named_in_call can use cp_get_fndecl_from_callee, >>> (or be replaced with cp_get_callee_fndecl_nofold). We can get e.g. a CALL_EXPR >>> whose CALL_EXPR_FN is a TEMPLATE_ID_EXPR, and get_function_named_in_call >>> returns the TEMPLATE_ID_EXPR whereas cp_get_fndecl_from_callee would return >>> null: >>> >>> if (TREE_CODE (fn) == FUNCTION_DECL) >>> return fn; >>> tree type = TREE_TYPE (fn); >>> if (type == NULL_TREE || !INDIRECT_TYPE_P (type)) >>> return NULL_TREE; >> >> Why couldn't this function use cp_get_fndecl_from_callee and return the >> original argument if that function returns null? > > It could. (The lambda below could have been a goto but either should be fine.) > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/13? OK. > -- >8 -- > We evaluate constexpr functions on the original, pre-genericization bodies. > That means that the function body we're evaluating will not have gone > through cp_genericize_r's "Map block scope extern declarations to visible > declarations with the same name and type in outer scopes if any". Here: > > constexpr bool bar() { return true; } // #1 > constexpr bool foo() { > constexpr bool bar(void); // #2 > return bar(); > } > > it means that we: > 1) register_constexpr_fundef (#1) > 2) cp_genericize (#1) > nothing interesting happens > 3) register_constexpr_fundef (foo) > does copy_fn, so we have two copies of the BIND_EXPR > 4) cp_genericize (foo) > this remaps #2 to #1, but only on one copy of the BIND_EXPR > 5) retrieve_constexpr_fundef (foo) > we find it, no problem > 6) retrieve_constexpr_fundef (#2) > and here #2 isn't found in constexpr_fundef_table, because > we're working on the BIND_EXPR copy where #2 wasn't mapped to #1 > so we fail. We've only registered #1. > > It should work to use DECL_LOCAL_DECL_ALIAS (which used to be > extern_decl_map). We evaluate constexpr functions on pre-cp_fold > bodies to avoid diagnostic problems, but the remapping I'm proposing > should not interfere with diagnostics. > > This is not a problem for a global scope redeclaration; there we go > through duplicate_decls which keeps the DECL_UID: > DECL_UID (olddecl) = olddecl_uid; > and DECL_UID is what constexpr_fundef_hasher::hash uses. > > PR c++/111132 > > gcc/cp/ChangeLog: > > * constexpr.cc (get_function_named_in_call): Use > cp_get_fndecl_from_callee. > * cvt.cc (cp_get_fndecl_from_callee): If there's a > DECL_LOCAL_DECL_ALIAS, use it. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp0x/constexpr-redeclaration3.C: New test. > * g++.dg/cpp0x/constexpr-redeclaration4.C: New test. > --- > gcc/cp/constexpr.cc | 10 ++++------ > gcc/cp/cvt.cc | 18 ++++++++++++++++-- > .../g++.dg/cpp0x/constexpr-redeclaration3.C | 13 +++++++++++++ > .../g++.dg/cpp0x/constexpr-redeclaration4.C | 14 ++++++++++++++ > 4 files changed, 47 insertions(+), 8 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-redeclaration3.C > create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-redeclaration4.C > > diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc > index fa346fe01c9..410ccdf597f 100644 > --- a/gcc/cp/constexpr.cc > +++ b/gcc/cp/constexpr.cc > @@ -702,16 +702,14 @@ build_constexpr_constructor_member_initializers (tree type, tree body) > > /* We have an expression tree T that represents a call, either CALL_EXPR > or AGGR_INIT_EXPR. If the call is lexically to a named function, > - retrun the _DECL for that function. */ > + return the _DECL for that function. */ > > static tree > get_function_named_in_call (tree t) > { > - tree fun = cp_get_callee (t); > - if (fun && TREE_CODE (fun) == ADDR_EXPR > - && TREE_CODE (TREE_OPERAND (fun, 0)) == FUNCTION_DECL) > - fun = TREE_OPERAND (fun, 0); > - return fun; > + tree callee = cp_get_callee (t); > + tree fun = cp_get_fndecl_from_callee (callee, /*fold*/false); > + return fun ? fun : callee; > } > > /* Subroutine of check_constexpr_fundef. BODY is the body of a function > diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc > index cbed847b343..db086c017e8 100644 > --- a/gcc/cp/cvt.cc > +++ b/gcc/cp/cvt.cc > @@ -1001,8 +1001,22 @@ cp_get_fndecl_from_callee (tree fn, bool fold /* = true */) > { > if (fn == NULL_TREE) > return fn; > + > + /* We evaluate constexpr functions on the original, pre-genericization > + bodies. So block-scope extern declarations have not been mapped to > + declarations in outer scopes. Use the namespace-scope declaration, > + if any, so that retrieve_constexpr_fundef can find it (PR111132). */ > + auto fn_or_local_alias = [] (tree f) > + { > + if (DECL_LOCAL_DECL_P (f)) > + if (tree alias = DECL_LOCAL_DECL_ALIAS (f)) > + if (alias != error_mark_node) > + return alias; > + return f; > + }; > + > if (TREE_CODE (fn) == FUNCTION_DECL) > - return fn; > + return fn_or_local_alias (fn); > tree type = TREE_TYPE (fn); > if (type == NULL_TREE || !INDIRECT_TYPE_P (type)) > return NULL_TREE; > @@ -1013,7 +1027,7 @@ cp_get_fndecl_from_callee (tree fn, bool fold /* = true */) > || TREE_CODE (fn) == FDESC_EXPR) > fn = TREE_OPERAND (fn, 0); > if (TREE_CODE (fn) == FUNCTION_DECL) > - return fn; > + return fn_or_local_alias (fn); > return NULL_TREE; > } > > diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-redeclaration3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-redeclaration3.C > new file mode 100644 > index 00000000000..2b41b456fc3 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-redeclaration3.C > @@ -0,0 +1,13 @@ > +// PR c++/111132 > +// { dg-do compile { target c++11 } } > + > +constexpr bool bar(void) { > + return true; > +} > + > +constexpr bool foo() { > + constexpr bool bar(void); > + return bar(); > +} > + > +static_assert(foo(), ""); > diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-redeclaration4.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-redeclaration4.C > new file mode 100644 > index 00000000000..c58247218c6 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-redeclaration4.C > @@ -0,0 +1,14 @@ > +// PR c++/111132 > +// { dg-do compile { target c++11 } } > + > +constexpr bool bar(void) { > + return true; > +} > + > +constexpr bool bar(void); > + > +constexpr bool foo() { > + return bar(); > +} > + > +static_assert(foo(), ""); > > base-commit: 27b6d081f68528435066be2234c7329e31e0e84f