diff options
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 3 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 60 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/mangle-regparm.C | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/mangle58.C | 8 |
5 files changed, 59 insertions, 23 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; diff --git a/gcc/testsuite/g++.dg/abi/mangle-regparm.C b/gcc/testsuite/g++.dg/abi/mangle-regparm.C index e5d6f37..122d373 100644 --- a/gcc/testsuite/g++.dg/abi/mangle-regparm.C +++ b/gcc/testsuite/g++.dg/abi/mangle-regparm.C @@ -1,10 +1,11 @@ // { dg-do run { target { { i?86-*-* x86_64-*-* } && ia32 } } } +// { dg-options "-Wabi=8" } // { dg-final { scan-assembler "_Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_" } } typedef __SIZE_TYPE__ size_t; template <typename F, typename T> -void IndirectExternCall(F f, T t1, T t2) { +void IndirectExternCall(F f, T t1, T t2) { // { dg-warning "mangled name" } typedef F (*WrapF)(F); f (t1, t2); } diff --git a/gcc/testsuite/g++.dg/abi/mangle58.C b/gcc/testsuite/g++.dg/abi/mangle58.C index f9aadc2..d2c90b4 100644 --- a/gcc/testsuite/g++.dg/abi/mangle58.C +++ b/gcc/testsuite/g++.dg/abi/mangle58.C @@ -6,13 +6,13 @@ struct B { template<typename T> static int cmp1(T a, T b); static int cmp2(char a, char b); // { dg-final { scan-assembler "_ZN1B1fIcEEvR1AIT_X4cmp1EE" } } - template <typename T> static void f (A<T,cmp1> &); + template <typename T> static void f (A<T,cmp1> &) {} // { dg-final { scan-assembler "_ZN1B1gIcEEvR1AIT_XsrS_4cmp1EE" } } - template <typename T> static void g (A<T,B::cmp1> &); + template <typename T> static void g (A<T,B::cmp1> &) {} // { dg-final { scan-assembler "_ZN1B1fIcEEvR1AIT_L_ZNS_4cmp2EccEE" } } - template <typename T> static void f (A<T,cmp2> &); // { dg-warning "mangle" } + template <typename T> static void f (A<T,cmp2> &) {} // { dg-warning "mangle" } // { dg-final { scan-assembler "_ZN1B1gIcEEvR1AIT_L_ZNS_4cmp2EccEE" } } - template <typename T> static void g (A<T,B::cmp2> &); // { dg-warning "mangle" } + template <typename T> static void g (A<T,B::cmp2> &) {} // { dg-warning "mangle" } }; void g() |