aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c-family/c-attribs.c12
-rw-r--r--gcc/cp/rtti.c9
-rw-r--r--gcc/symtab.c8
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-typeid2.C14
4 files changed, 43 insertions, 0 deletions
diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index bd42036..dbb892e 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -159,6 +159,7 @@ static tree handle_omp_declare_variant_attribute (tree *, tree, tree, int,
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_attribute_table[] =
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 },
@@ -3765,6 +3768,15 @@ handle_omp_declare_target_attribute (tree *, tree, tree, int, bool *)
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. */
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 30ae18a..a4dedc3 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -475,6 +475,15 @@ get_tinfo_decl_direct (tree type, tree name, int pseudo_ix)
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. */
diff --git a/gcc/symtab.c b/gcc/symtab.c
index d037fe6..f9e4571 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -2276,6 +2276,14 @@ symtab_node::equal_address_to (symtab_node *s2, bool memory_accessed)
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.
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-typeid2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-typeid2.C
new file mode 100644
index 0000000..78c6b8e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-typeid2.C
@@ -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, "");