public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jason Merrill <jason@redhat.com>
To: Jakub Jelinek <jakub@redhat.com>, Jan Hubicka <jh@suse.cz>
Cc: Jonathan Wakely <jwakely@redhat.com>, gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] c++, symtab: Support &typeid(x) == &typeid(y) in constant evaluation [PR103600]
Date: Thu, 9 Dec 2021 18:09:12 -0500	[thread overview]
Message-ID: <53b915f2-8ac5-d6a8-9051-3518b3380ea2@redhat.com> (raw)
In-Reply-To: <20211209201523.GK2646553@tucnak>

On 12/9/21 15:15, Jakub Jelinek wrote:
> 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?

LGTM for fixing the specific typeid issue, if Honza has no objection.

For the more general comparison of decls like your a != b example above 
I think clang is in the right; in manifestly constant-evaluated context 
(folding_initializer) we should return that they are unequal and prevent 
a later alias declaration, like we do for comparison to 0 in 
maybe_nonzero_address.  It's possible that this gives a wrong answer 
based on something in another translation unit, but that's unlikely, and 
taking that chance seems better than rejecting code that needs a 
constant answer.

> 2021-12-09  Jakub Jelinek  <jakub@redhat.com>
> 
> 	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.
> 
> --- 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 <typeinfo>
> +
> +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, "");
> 
> 
> 	Jakub
> 


  parent reply	other threads:[~2021-12-09 23:09 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-08 10:35 [PATCH] c++: Support &typeid(x) == &typeid(y) and typeid(x) == typeid(y) " Jakub Jelinek
2021-12-08 13:53 ` Jason Merrill
2021-12-08 13:56   ` Jonathan Wakely
2021-12-09 20:15   ` [PATCH] c++, symtab: Support &typeid(x) == &typeid(y) " Jakub Jelinek
2021-12-09 20:41     ` Jan Hubicka
2021-12-09 23:09     ` Jason Merrill [this message]
2021-12-10 10:41       ` [PATCH] symtab: Fold &a == &b to 0 if folding_initializer [PR94716] Jakub Jelinek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=53b915f2-8ac5-d6a8-9051-3518b3380ea2@redhat.com \
    --to=jason@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jakub@redhat.com \
    --cc=jh@suse.cz \
    --cc=jwakely@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).