diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index de8fdacdedf..d08d02cd3a3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2015-06-23 Jason Merrill + 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 d14ffe218fc..a8fc1a57a95 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 a9c9214132a..bc8428db0a4 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 cee92371043..396edd3de85 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 00000000000..12c1ab2039c --- /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;