Commit 1cc1ac7f by Jason Merrill Committed by Jason Merrill

re PR c++/44282 (fastcall is not mangled at all)

	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.

From-SVN: r224101
parent 82b544ad
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> 2015-06-03 Manuel López-Ibáñez <manu@gcc.gnu.org>
Paolo Carlini <paolo.carlini@oracle.com> Paolo Carlini <paolo.carlini@oracle.com>
......
...@@ -4101,7 +4101,8 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) ...@@ -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) (DECL_LANG_SPECIFIC (NODE)->u.base.not_really_extern)
#define DECL_REALLY_EXTERN(NODE) \ #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. /* A thunk is a stub function.
......
...@@ -2205,10 +2205,6 @@ write_CV_qualifiers_for_type (const tree type) ...@@ -2205,10 +2205,6 @@ write_CV_qualifiers_for_type (const tree type)
/* Mangle attributes that affect type identity as extended qualifiers. /* 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 We don't do this with classes and enums because their attributes
are part of their definitions, not something added on. */ are part of their definitions, not something added on. */
...@@ -2246,6 +2242,8 @@ write_CV_qualifiers_for_type (const tree type) ...@@ -2246,6 +2242,8 @@ write_CV_qualifiers_for_type (const tree type)
} }
++num_qualifiers; ++num_qualifiers;
if (abi_version_crosses (9))
G.need_abi_warning = true;
} }
} }
...@@ -3535,11 +3533,11 @@ get_mangled_id (tree decl) ...@@ -3535,11 +3533,11 @@ get_mangled_id (tree decl)
return targetm.mangle_decl_assembler_name (decl, id); return targetm.mangle_decl_assembler_name (decl, id);
} }
/* If DECL is a mangling alias, remove it from the symbol table and return /* If DECL is an implicit mangling alias, return its symtab node; otherwise
true; otherwise return false. */ return NULL. */
bool static symtab_node *
maybe_remove_implicit_alias (tree decl) decl_implicit_alias_p (tree decl)
{ {
if (DECL_P (decl) && DECL_ARTIFICIAL (decl) if (DECL_P (decl) && DECL_ARTIFICIAL (decl)
&& DECL_IGNORED_P (decl) && DECL_IGNORED_P (decl)
...@@ -3549,10 +3547,21 @@ maybe_remove_implicit_alias (tree decl) ...@@ -3549,10 +3547,21 @@ maybe_remove_implicit_alias (tree decl)
{ {
symtab_node *n = symtab_node::get (decl); symtab_node *n = symtab_node::get (decl);
if (n && n->cpp_implicit_alias) if (n && n->cpp_implicit_alias)
{ return n;
n->remove(); }
return true; 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; return false;
} }
...@@ -3592,21 +3601,38 @@ mangle_decl (const tree decl) ...@@ -3592,21 +3601,38 @@ mangle_decl (const tree decl)
} }
SET_DECL_ASSEMBLER_NAME (decl, id); 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. */ /* Don't do this for a fake symbol we aren't going to emit anyway. */
&& TREE_CODE (decl) != TYPE_DECL && TREE_CODE (decl) != TYPE_DECL
&& !DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl) && !DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)
&& !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_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 /* If the mangling will change in the future, emit an alias with the
future mangled name for forward-compatibility. */ future mangled name for forward-compatibility. */
int save_ver; int save_ver;
tree id2; tree id2;
SET_IDENTIFIER_GLOBAL_VALUE (id, decl); if (!set)
if (IDENTIFIER_GLOBAL_VALUE (id) != decl) {
inform (DECL_SOURCE_LOCATION (decl), "a later -fabi-version= (or =0) " SET_IDENTIFIER_GLOBAL_VALUE (id, decl);
"avoids this error with a change in mangling"); inform (DECL_SOURCE_LOCATION (decl), "a later -fabi-version= (or "
"=0) avoids this error with a change in mangling");
}
save_ver = flag_abi_version; save_ver = flag_abi_version;
flag_abi_version = flag_abi_compat_version; flag_abi_version = flag_abi_compat_version;
......
// { dg-do run { target { { i?86-*-* x86_64-*-* } && ia32 } } } // { dg-do run { target { { i?86-*-* x86_64-*-* } && ia32 } } }
// { dg-options "-Wabi=8" }
// { dg-final { scan-assembler "_Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_" } } // { dg-final { scan-assembler "_Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_" } }
typedef __SIZE_TYPE__ size_t; typedef __SIZE_TYPE__ size_t;
template <typename F, typename 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); typedef F (*WrapF)(F);
f (t1, t2); f (t1, t2);
} }
......
...@@ -6,13 +6,13 @@ struct B { ...@@ -6,13 +6,13 @@ struct B {
template<typename T> static int cmp1(T a, T b); template<typename T> static int cmp1(T a, T b);
static int cmp2(char a, char b); static int cmp2(char a, char b);
// { dg-final { scan-assembler "_ZN1B1fIcEEvR1AIT_X4cmp1EE" } } // { 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" } } // { 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" } } // { 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" } } // { 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() void g()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment