#include "stringpool.h"
#include "attribs.h"
#include "builtins.h"
+#include "fold-const.h"
static const char *ipa_ref_use_name[] = {"read","write","addr","alias"};
return 0;
}
+ if (rs1 == rs2)
+ return -1;
+
/* 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;
are different unless they are declared as alias of one to another while
the code folding comparisons doesn't.
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. */
--- /dev/null
+// { 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;
--- /dev/null
+// 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>;
--- /dev/null
+// { 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;