summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2015-06-03 21:09:25 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2015-06-03 21:09:25 +0000
commit6ad473596f6ce40d809f689071268930b8342a4d (patch)
tree6fe433ffcd80debde3c1abdac4a1b98a58a3ae21
parent153a1d8cac0767437e7d900a3914171f6a0d0901 (diff)
downloadgcc-6ad473596f6ce40d809f689071268930b8342a4d.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@224101 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/mangle.c60
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle-regparm.C3
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle58.C8
5 files changed, 59 insertions, 23 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 39888b970b0..a9be43a8ffc 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 76be7cca6f1..7690af77d8d 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 8fd06e3c2cd..cc5faf7755e 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 e5d6f37e639..122d37390db 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 f9aadc2a900..d2c90b43a2d 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()