diff options
author | Jason Merrill <jason@redhat.com> | 2015-06-23 10:08:30 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2015-06-23 10:08:30 -0400 |
commit | d88511aec7338a93753fbba2c97d18539250c491 (patch) | |
tree | b64a9cc3052b051948ce2c2171bb946a4ac81d64 | |
parent | 115ef7c52e7cae6101df2f062b4650c82e50072d (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/decl.c | 2 | ||||
-rw-r--r-- | gcc/cp/tree.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/anon2.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/anon7.C | 10 |
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; |