diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/c-family/c-attribs.c | 12 | ||||
-rw-r--r-- | gcc/cp/rtti.c | 9 | ||||
-rw-r--r-- | gcc/symtab.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-typeid2.C | 14 |
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, ""); |