symtab: Fold &a == &b to 0 if folding_initializer [PR94716]
On Thu, Dec 09, 2021 at 06:09:12PM -0500, Jason Merrill wrote: > 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. I agree. This is an incremental patch to do that. 2022-01-03 Jakub Jelinek <jakub@redhat.com> PR c++/94716 gcc/ * symtab.c: Include fold-const.h. (symtab_node::equal_address_to): If folding_initializer is true, handle it like memory_accessed. Simplify. gcc/testsuite/ * gcc.dg/init-compare-1.c: New test. * g++.dg/cpp0x/constexpr-compare1.C: New test. * g++.dg/cpp1y/constexpr-94716.C: New test. * g++.dg/cpp1z/constexpr-compare1.C: New test.
This commit is contained in:
parent
814c221c9e
commit
91031bffa4
14
gcc/symtab.c
14
gcc/symtab.c
@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
#include "stringpool.h"
|
#include "stringpool.h"
|
||||||
#include "attribs.h"
|
#include "attribs.h"
|
||||||
#include "builtins.h"
|
#include "builtins.h"
|
||||||
|
#include "fold-const.h"
|
||||||
|
|
||||||
static const char *ipa_ref_use_name[] = {"read","write","addr","alias"};
|
static const char *ipa_ref_use_name[] = {"read","write","addr","alias"};
|
||||||
|
|
||||||
@ -2276,10 +2277,12 @@ symtab_node::equal_address_to (symtab_node *s2, bool memory_accessed)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rs1 == rs2)
|
||||||
|
return -1;
|
||||||
|
|
||||||
/* If the FE tells us at least one of the decls will never be aliased nor
|
/* 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. */
|
overlapping with other vars in some other way, return 0. */
|
||||||
if (VAR_P (decl)
|
if (VAR_P (decl)
|
||||||
&& rs1 != rs2
|
|
||||||
&& (lookup_attribute ("non overlapping", DECL_ATTRIBUTES (decl))
|
&& (lookup_attribute ("non overlapping", DECL_ATTRIBUTES (decl))
|
||||||
|| lookup_attribute ("non overlapping", DECL_ATTRIBUTES (s2->decl))))
|
|| lookup_attribute ("non overlapping", DECL_ATTRIBUTES (s2->decl))))
|
||||||
return 0;
|
return 0;
|
||||||
@ -2288,9 +2291,14 @@ symtab_node::equal_address_to (symtab_node *s2, bool memory_accessed)
|
|||||||
are different unless they are declared as alias of one to another while
|
are different unless they are declared as alias of one to another while
|
||||||
the code folding comparisons doesn't.
|
the code folding comparisons doesn't.
|
||||||
We probably should be consistent and use this fact here, too, but for
|
We probably should be consistent and use this fact here, too, but for
|
||||||
the moment return false only when we are called from the alias oracle. */
|
the moment return false only when we are called from the alias oracle.
|
||||||
|
Return 0 in C constant initializers and C++ manifestly constant
|
||||||
|
expressions, the likelyhood that different vars will be aliases is
|
||||||
|
small and returning -1 lets us reject too many initializers. */
|
||||||
|
if (memory_accessed || folding_initializer)
|
||||||
|
return 0;
|
||||||
|
|
||||||
return memory_accessed && rs1 != rs2 ? 0 : -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Worker for call_for_symbol_and_aliases. */
|
/* Worker for call_for_symbol_and_aliases. */
|
||||||
|
7
gcc/testsuite/g++.dg/cpp0x/constexpr-compare1.C
Normal file
7
gcc/testsuite/g++.dg/cpp0x/constexpr-compare1.C
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// { dg-do compile { target c++11 } }
|
||||||
|
|
||||||
|
extern int a, b;
|
||||||
|
static_assert (&a == &a, "");
|
||||||
|
static_assert (&a != &b, "");
|
||||||
|
constexpr bool c = &a == &a;
|
||||||
|
constexpr bool d = &a != &b;
|
8
gcc/testsuite/g++.dg/cpp1y/constexpr-94716.C
Normal file
8
gcc/testsuite/g++.dg/cpp1y/constexpr-94716.C
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// PR c++/94716
|
||||||
|
// { dg-do compile { target c++14 } }
|
||||||
|
|
||||||
|
template <int> char v = 0;
|
||||||
|
static_assert (&v<2> == &v<2>, "");
|
||||||
|
static_assert (&v<0> != &v<1>, "");
|
||||||
|
constexpr bool a = &v<2> == &v<2>;
|
||||||
|
constexpr bool b = &v<0> != &v<1>;
|
8
gcc/testsuite/g++.dg/cpp1z/constexpr-compare1.C
Normal file
8
gcc/testsuite/g++.dg/cpp1z/constexpr-compare1.C
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// { dg-do compile { target c++17 } }
|
||||||
|
|
||||||
|
inline int a = 0;
|
||||||
|
inline int b = 0;
|
||||||
|
static_assert (&a == &a);
|
||||||
|
static_assert (&a != &b);
|
||||||
|
constexpr bool c = &a == &a;
|
||||||
|
constexpr bool d = &a != &b;
|
5
gcc/testsuite/gcc.dg/init-compare-1.c
Normal file
5
gcc/testsuite/gcc.dg/init-compare-1.c
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
/* { dg-do compile } */
|
||||||
|
|
||||||
|
extern int a, b;
|
||||||
|
int c = &a == &a;
|
||||||
|
int d = &a != &b;
|
Loading…
Reference in New Issue
Block a user