aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-11-21 16:35:09 -0500
committerJason Merrill <jason@gcc.gnu.org>2014-11-21 16:35:09 -0500
commit64bec774eda78d9b51cc1210eb9ce9c24c878016 (patch)
treeafc767f7d032ad609b159c2bb96444301e867ef9 /gcc
parent6602e1095db5259590fa8813f48a1404ba00cf10 (diff)
downloadgcc-64bec774eda78d9b51cc1210eb9ce9c24c878016.zip
gcc-64bec774eda78d9b51cc1210eb9ce9c24c878016.tar.gz
gcc-64bec774eda78d9b51cc1210eb9ce9c24c878016.tar.bz2
re PR c++/63942 (constexpr conflicts with previous declaration)
PR c++/63942 * name-lookup.c (supplement_binding_1): Override a mangling alias. * mangle.c (implicit_alias_p, remove_implicit_alias): New. (mangle_decl): Avoid creating conflicting alias with -fabi-compat-version=0, too. * cp-tree.h: Adjust. From-SVN: r217950
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/mangle.c27
-rw-r--r--gcc/cp/name-lookup.c6
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nullptr32.C21
5 files changed, 59 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 652ec9c..b1d9cea 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
2014-11-21 Jason Merrill <jason@redhat.com>
+ PR c++/63942
+ * name-lookup.c (supplement_binding_1): Override a mangling alias.
+ * mangle.c (maybe_remove_implicit_alias): New.
+ (mangle_decl): Always avoid creating conflicting alias.
+ * cp-tree.h: Adjust.
+
PR c++/63849
* mangle.c (decl_mangling_context): Use template_type_parameter_p.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b3781ab..428d559 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6299,6 +6299,7 @@ extern tree add_exception_specifier (tree, tree, int);
extern tree merge_exception_specifiers (tree, tree);
/* in mangle.c */
+extern bool maybe_remove_implicit_alias (tree);
extern void init_mangle (void);
extern void mangle_decl (tree);
extern const char *mangle_type_string (tree);
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 9f0d9d8..a244669 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -3428,6 +3428,28 @@ 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. */
+
+bool
+maybe_remove_implicit_alias (tree decl)
+{
+ if (DECL_P (decl) && DECL_ARTIFICIAL (decl)
+ && DECL_IGNORED_P (decl)
+ && (TREE_CODE (decl) == FUNCTION_DECL
+ || (TREE_CODE (decl) == VAR_DECL
+ && TREE_STATIC (decl))))
+ {
+ symtab_node *n = symtab_node::get (decl);
+ if (n && n->cpp_implicit_alias)
+ {
+ n->remove();
+ return true;
+ }
+ }
+ return false;
+}
+
/* Create an identifier for the external mangled name of DECL. */
void
@@ -3491,8 +3513,9 @@ mangle_decl (const tree decl)
}
#ifdef ASM_OUTPUT_DEF
- if (flag_abi_compat_version != 0
- && IDENTIFIER_GLOBAL_VALUE (id2))
+ /* If there's a declaration already using this mangled name,
+ don't create a compatibility alias that conflicts. */
+ if (IDENTIFIER_GLOBAL_VALUE (id2))
return;
tree alias = make_alias_for (decl, id2);
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index d42bcac..71b359e 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -561,6 +561,12 @@ supplement_binding_1 (cxx_binding *binding, tree decl)
region to refer only to the namespace to which it already
refers. */
ok = false;
+ else if (maybe_remove_implicit_alias (bval))
+ {
+ /* There was a mangling compatibility alias using this mangled name,
+ but now we have a real decl that wants to use it instead. */
+ binding->value = decl;
+ }
else
{
diagnose_name_conflict (decl, bval);
diff --git a/gcc/testsuite/g++.dg/cpp0x/nullptr32.C b/gcc/testsuite/g++.dg/cpp0x/nullptr32.C
new file mode 100644
index 0000000..a1e6710
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nullptr32.C
@@ -0,0 +1,21 @@
+// PR c++/63942
+// A mangling alias for the first constructor was conflicting with the second.
+// { dg-do compile { target c++11 } }
+// { dg-options "-fno-inline" }
+
+int i;
+template <class T> struct A
+{
+ A(const T&) { i = 42; }
+ A(const A&) { i = 36; }
+};
+
+typedef A<decltype(nullptr)> An;
+
+int main()
+{
+ An a (nullptr);
+ if (i != 42) __builtin_abort();
+ An a2 (a);
+ if (i != 36) __builtin_abort();
+}