aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2015-06-23 10:08:30 -0400
committerJason Merrill <jason@gcc.gnu.org>2015-06-23 10:08:30 -0400
commitd88511aec7338a93753fbba2c97d18539250c491 (patch)
treeb64a9cc3052b051948ce2c2171bb946a4ac81d64
parent115ef7c52e7cae6101df2f062b4650c82e50072d (diff)
downloadgcc-d88511aec7338a93753fbba2c97d18539250c491.zip
gcc-d88511aec7338a93753fbba2c97d18539250c491.tar.gz
gcc-d88511aec7338a93753fbba2c97d18539250c491.tar.bz2
re PR c++/65879 (Bogus linkage errors for member class of anonymous class)
PR c++/65879 * decl.c (grokfndecl): Check the linkage of ctype, not just TYPE_ANONYMOUS_P. * tree.c (no_linkage_check): Skip the 'this' pointer. From-SVN: r224844
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/decl.c2
-rw-r--r--gcc/cp/tree.c12
-rw-r--r--gcc/testsuite/g++.dg/abi/anon2.C4
-rw-r--r--gcc/testsuite/g++.dg/other/anon7.C10
5 files changed, 24 insertions, 9 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index de8fdac..d08d02c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,10 @@
2015-06-23 Jason Merrill <jason@redhat.com>
+ PR c++/65879
+ * decl.c (grokfndecl): Check the linkage of ctype, not just
+ TYPE_ANONYMOUS_P.
+ * tree.c (no_linkage_check): Skip the 'this' pointer.
+
PR c++/66501
* class.c (type_has_nontrivial_assignment): New.
* init.c (build_vec_init): Use it.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index d14ffe2..a8fc1a5 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -7794,7 +7794,7 @@ grokfndecl (tree ctype,
/* Members of anonymous types and local classes have no linkage; make
them internal. If a typedef is made later, this will be changed. */
- if (ctype && (TYPE_ANONYMOUS_P (ctype)
+ if (ctype && (!TREE_PUBLIC (TYPE_MAIN_DECL (ctype))
|| decl_function_context (TYPE_MAIN_DECL (ctype))))
publicp = 0;
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index a9c9214..bc8428d 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -2299,14 +2299,14 @@ no_linkage_check (tree t, bool relaxed_p)
return no_linkage_check (TYPE_PTRMEM_CLASS_TYPE (t), relaxed_p);
case METHOD_TYPE:
- r = no_linkage_check (TYPE_METHOD_BASETYPE (t), relaxed_p);
- if (r)
- return r;
- /* Fall through. */
case FUNCTION_TYPE:
{
- tree parm;
- for (parm = TYPE_ARG_TYPES (t);
+ tree parm = TYPE_ARG_TYPES (t);
+ if (TREE_CODE (t) == METHOD_TYPE)
+ /* The 'this' pointer isn't interesting; a method has the same
+ linkage (or lack thereof) as its enclosing class. */
+ parm = TREE_CHAIN (parm);
+ for (;
parm && parm != void_list_node;
parm = TREE_CHAIN (parm))
{
diff --git a/gcc/testsuite/g++.dg/abi/anon2.C b/gcc/testsuite/g++.dg/abi/anon2.C
index cee9237..396edd3 100644
--- a/gcc/testsuite/g++.dg/abi/anon2.C
+++ b/gcc/testsuite/g++.dg/abi/anon2.C
@@ -23,9 +23,9 @@ namespace N2 {
typedef struct { } B;
struct C {
// { dg-final { scan-assembler-not ".weak\(_definition\)?\[ \t\]_?_ZN2N23._31C3fn1ENS0_1BE" { target c++11 } } }
- static void fn1 (B) { } // { dg-error "no linkage" "" { target { ! c++11 } } }
+ static void fn1 (B) { }
// { dg-final { scan-assembler-not ".weak\(_definition\)?\[ \t\]_?_ZN2N23._31C3fn2ES1_" { target c++11 } } }
- static void fn2 (C) { } // { dg-error "no linkage" "" { target { ! c++11 } } }
+ static void fn2 (C) { }
};
} const D;
diff --git a/gcc/testsuite/g++.dg/other/anon7.C b/gcc/testsuite/g++.dg/other/anon7.C
new file mode 100644
index 0000000..12c1ab2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/anon7.C
@@ -0,0 +1,10 @@
+// PR c++/65879
+
+static struct
+{
+ void f();
+ struct Inner
+ {
+ void g();
+ };
+} x;