From patchwork Thu Dec 9 20:15:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 48723 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B4DE73858016 for ; Thu, 9 Dec 2021 20:16:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B4DE73858016 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1639080996; bh=dom/3CrJs/f9cEDFDi3mhsq3py9b9i7/0S1+DvAI6Uw=; h=Date:To:Subject:References:In-Reply-To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=yZoCaJHNkyGs7o3IcGbyJ7nCkz+0Tm/ZJsav+rZLxROHEHrdD+A/5T4mVLMWMPy0E 4G7UnHwNTU7PyXf5Jds/uhvmbKH79B5OmI2g2n8Mut+iocQb1Wt26JNtCqVQsQaxdr jXuYYjm7fX4r5D26+WUc1nAdyATwZlQSaMQnTjFg= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 4C44A3858C27 for ; Thu, 9 Dec 2021 20:16:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 4C44A3858C27 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-37-mRmeo5UvPkiEozrTFquuoA-1; Thu, 09 Dec 2021 15:16:01 -0500 X-MC-Unique: mRmeo5UvPkiEozrTFquuoA-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id B372A19253C5; Thu, 9 Dec 2021 20:16:00 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.194.188]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 604C97DE57; Thu, 9 Dec 2021 20:15:27 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.16.1/8.16.1) with ESMTPS id 1B9KFOd51569801 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 9 Dec 2021 21:15:25 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.16.1/8.16.1/Submit) id 1B9KFNVF1569800; Thu, 9 Dec 2021 21:15:23 +0100 Date: Thu, 9 Dec 2021 21:15:23 +0100 To: Jason Merrill , Jan Hubicka Subject: [PATCH] c++, symtab: Support &typeid(x) == &typeid(y) in constant evaluation [PR103600] Message-ID: <20211209201523.GK2646553@tucnak> References: <20211208103528.GE2646553@tucnak> MIME-Version: 1.0 In-Reply-To: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-5.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jakub Jelinek via Gcc-patches From: Jakub Jelinek Reply-To: Jakub Jelinek Cc: Jonathan Wakely , gcc-patches@gcc.gnu.org Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" On Wed, Dec 08, 2021 at 08:53:03AM -0500, Jason Merrill wrote: > > As mentioned in the PR, the varpool/middle-end code is trying to be > > conservative with address comparisons of different vars if those vars > > don't bind locally, because of possible aliases in other TUs etc. > > Would it make sense to assume that DECL_ARTIFICIAL variables can't be > aliases? If not, could we have some way of marking a variable as > non-aliasing, perhaps an attribute? I think DECL_ARTIFICIAL vars generally can overlap. The following patch adds a GCC internal attribute "non overlapping" and uses it in symtab_node::equal_address_to. Not sure what plans has Honza in that area and whether it would be useful to make the attribute public and let users assert that some variable will never overlap with other variables, won't have aliases etc. > During constant evaluation, the operator== could compare the type_info > address instead of the __name address, reducing this to the previous > problem. Ah, indeed, good idea. FYI, clang++ seems to constant fold &typeid(x) != &typeid(y) already, so Jonathan could use it even for clang++ in the constexpr operator==. But it folds even extern int &a, &b; constexpr bool c = &a != &b; regardless of whether some other TU has int a; int b __attribute__((alias (a)); or not. Here is an updated patch, ok for trunk if it passes bootstrap/regtest? 2021-12-09 Jakub Jelinek PR c++/103600 gcc/ * symtab.c (symtab_node::equal_address_to): Return 0 if one of VAR_DECLs has "non overlapping" attribute and rs1 != rs2. gcc/c-family/ * c-attribs.c (handle_non_overlapping_attribute): New function. (c_common_attribute_table): Add "non overlapping" attribute. gcc/cp/ * rtti.c (get_tinfo_decl_direct): Add "non overlapping" attribute to DECL_TINFO_P VAR_DECLs. gcc/testsuite/ * g++.dg/cpp0x/constexpr-typeid2.C: New test. Jakub --- gcc/symtab.c.jj 2021-11-19 09:58:37.268716406 +0100 +++ gcc/symtab.c 2021-12-09 20:41:30.085566768 +0100 @@ -2276,6 +2276,14 @@ symtab_node::equal_address_to (symtab_no return 0; } + /* If the FE tells us at least one of the decls will never be aliased nor + overlapping with other vars in some other way, return 0. */ + if (VAR_P (decl) + && rs1 != rs2 + && (lookup_attribute ("non overlapping", DECL_ATTRIBUTES (decl)) + || lookup_attribute ("non overlapping", DECL_ATTRIBUTES (s2->decl)))) + return 0; + /* TODO: Alias oracle basically assume that addresses of global variables are different unless they are declared as alias of one to another while the code folding comparisons doesn't. --- gcc/c-family/c-attribs.c.jj 2021-09-11 09:33:37.734334126 +0200 +++ gcc/c-family/c-attribs.c 2021-12-09 20:44:42.593810421 +0100 @@ -159,6 +159,7 @@ static tree handle_omp_declare_variant_a static tree handle_simd_attribute (tree *, tree, tree, int, bool *); static tree handle_omp_declare_target_attribute (tree *, tree, tree, int, bool *); +static tree handle_non_overlapping_attribute (tree *, tree, tree, int, bool *); static tree handle_designated_init_attribute (tree *, tree, tree, int, bool *); static tree handle_patchable_function_entry_attribute (tree *, tree, tree, int, bool *); @@ -512,6 +513,8 @@ const struct attribute_spec c_common_att handle_omp_declare_target_attribute, NULL }, { "omp declare target block", 0, 0, true, false, false, false, handle_omp_declare_target_attribute, NULL }, + { "non overlapping", 0, 0, true, false, false, false, + handle_non_overlapping_attribute, NULL }, { "alloc_align", 1, 1, false, true, true, false, handle_alloc_align_attribute, attr_alloc_exclusions }, @@ -3764,6 +3767,15 @@ handle_omp_declare_target_attribute (tre { return NULL_TREE; } + +/* Handle an "non overlapping" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_non_overlapping_attribute (tree *, tree, tree, int, bool *) +{ + return NULL_TREE; +} /* Handle a "returns_twice" attribute; arguments as in struct attribute_spec.handler. */ --- gcc/cp/rtti.c.jj 2021-12-09 15:37:05.330625874 +0100 +++ gcc/cp/rtti.c 2021-12-09 21:02:13.090738268 +0100 @@ -475,6 +475,15 @@ get_tinfo_decl_direct (tree type, tree n DECL_IGNORED_P (d) = 1; TREE_READONLY (d) = 1; TREE_STATIC (d) = 1; + /* Tell equal_address_to that different tinfo decls never + overlap. */ + if (vec_safe_is_empty (unemitted_tinfo_decls)) + DECL_ATTRIBUTES (d) + = build_tree_list (get_identifier ("non overlapping"), + NULL_TREE); + else + DECL_ATTRIBUTES (d) + = DECL_ATTRIBUTES ((*unemitted_tinfo_decls)[0]); /* Mark the variable as undefined -- but remember that we can define it later if we need to do so. */ --- gcc/testsuite/g++.dg/cpp0x/constexpr-typeid2.C.jj 2021-12-09 20:28:47.083369305 +0100 +++ gcc/testsuite/g++.dg/cpp0x/constexpr-typeid2.C 2021-12-09 20:28:47.083369305 +0100 @@ -0,0 +1,14 @@ +// PR c++/103600 +// { dg-do compile { target c++11 } } + +#include + +struct S { int i; }; +namespace { + struct T { int i; }; +}; +constexpr bool a = &typeid (int) == &typeid (int); +constexpr bool b = &typeid (int) == &typeid (long); +constexpr bool c = &typeid (double) != &typeid (int); +constexpr bool d = &typeid (S) != &typeid (T); +static_assert (a && !b && c && d, "");