diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 3 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 60 |
3 files changed, 53 insertions, 18 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 39888b9..a9be43a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2015-06-03 Jason Merrill <jason@redhat.com> + + PR c++/44282 + * mangle.c (mangle_decl): Always SET_IDENTIFIER_GLOBAL_VALUE. + (write_CV_qualifiers_for_type): Set G.need_abi_warning. + (decl_implicit_alias_p): Split out from maybe_remove_implicit_alias. + * cp-tree.h (DECL_REALLY_EXTERN): Handle null DECL_LANG_SPECIFIC. + 2015-06-03 Manuel López-Ibáñez <manu@gcc.gnu.org> Paolo Carlini <paolo.carlini@oracle.com> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 76be7cc..7690af7 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4101,7 +4101,8 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) (DECL_LANG_SPECIFIC (NODE)->u.base.not_really_extern) #define DECL_REALLY_EXTERN(NODE) \ - (DECL_EXTERNAL (NODE) && ! DECL_NOT_REALLY_EXTERN (NODE)) + (DECL_EXTERNAL (NODE) \ + && (!DECL_LANG_SPECIFIC (NODE) || !DECL_NOT_REALLY_EXTERN (NODE))) /* A thunk is a stub function. diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 8fd06e3..cc5faf7 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -2205,10 +2205,6 @@ write_CV_qualifiers_for_type (const tree type) /* Mangle attributes that affect type identity as extended qualifiers. - We mangle them onto the obstack, then copy the result into a string - vector and back up the obstack. Once we've handled all of them we - sort them and write them out in order. - We don't do this with classes and enums because their attributes are part of their definitions, not something added on. */ @@ -2246,6 +2242,8 @@ write_CV_qualifiers_for_type (const tree type) } ++num_qualifiers; + if (abi_version_crosses (9)) + G.need_abi_warning = true; } } @@ -3535,11 +3533,11 @@ get_mangled_id (tree decl) return targetm.mangle_decl_assembler_name (decl, id); } -/* If DECL is a mangling alias, remove it from the symbol table and return - true; otherwise return false. */ +/* If DECL is an implicit mangling alias, return its symtab node; otherwise + return NULL. */ -bool -maybe_remove_implicit_alias (tree decl) +static symtab_node * +decl_implicit_alias_p (tree decl) { if (DECL_P (decl) && DECL_ARTIFICIAL (decl) && DECL_IGNORED_P (decl) @@ -3549,10 +3547,21 @@ maybe_remove_implicit_alias (tree decl) { symtab_node *n = symtab_node::get (decl); if (n && n->cpp_implicit_alias) - { - n->remove(); - return true; - } + return n; + } + return NULL; +} + +/* If DECL is a mangling alias, remove it from the symbol table and return + true; otherwise return false. */ + +bool +maybe_remove_implicit_alias (tree decl) +{ + if (symtab_node *n = decl_implicit_alias_p (decl)) + { + n->remove(); + return true; } return false; } @@ -3592,21 +3601,38 @@ mangle_decl (const tree decl) } SET_DECL_ASSEMBLER_NAME (decl, id); - if (G.need_abi_warning + if (id != DECL_NAME (decl) + && !DECL_REALLY_EXTERN (decl) /* Don't do this for a fake symbol we aren't going to emit anyway. */ && TREE_CODE (decl) != TYPE_DECL && !DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl)) { + bool set = false; + + /* Check IDENTIFIER_GLOBAL_VALUE before setting to avoid redundant + errors from multiple definitions. */ + tree d = IDENTIFIER_GLOBAL_VALUE (id); + if (!d || decl_implicit_alias_p (d)) + { + set = true; + SET_IDENTIFIER_GLOBAL_VALUE (id, decl); + } + + if (!G.need_abi_warning) + return; + /* If the mangling will change in the future, emit an alias with the future mangled name for forward-compatibility. */ int save_ver; tree id2; - SET_IDENTIFIER_GLOBAL_VALUE (id, decl); - if (IDENTIFIER_GLOBAL_VALUE (id) != decl) - inform (DECL_SOURCE_LOCATION (decl), "a later -fabi-version= (or =0) " - "avoids this error with a change in mangling"); + if (!set) + { + SET_IDENTIFIER_GLOBAL_VALUE (id, decl); + inform (DECL_SOURCE_LOCATION (decl), "a later -fabi-version= (or " + "=0) avoids this error with a change in mangling"); + } save_ver = flag_abi_version; flag_abi_version = flag_abi_compat_version; |