From 1fcaa1eb87540b689b435914a0d82bc9b65bcc34 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 22 Jan 2018 16:51:53 -0500 Subject: [PATCH] PR c++/83720 - ICE with lambda and LTO. * decl2.c (determine_visibility): Clear template_decl for function-scope decls. Propagate anonymous linkage from containing function. From-SVN: r256964 --- gcc/cp/ChangeLog | 9 +++++- gcc/cp/decl2.c | 11 ++++---- gcc/testsuite/g++.dg/lto/pr83720_0.C | 55 ++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lto/pr83720_0.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3cbb2a4..8ec76a4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,9 +1,16 @@ +2018-01-22 Jason Merrill + + PR c++/83720 - ICE with lambda and LTO. + * decl2.c (determine_visibility): Clear template_decl for + function-scope decls. Propagate anonymous linkage from containing + function. + 2018-01-22 Marek Polacek PR c++/81933 * typeck2.c (split_nonconstant_init_1): Return false if we didn't split out anything. - + 2018-01-22 Ville Voutilainen PR c++/83895 diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index a2b2e28..6324c55 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2388,7 +2388,9 @@ determine_visibility (tree decl) containing function by default, except that -fvisibility-inlines-hidden doesn't affect them. */ tree fn = DECL_CONTEXT (decl); - if (DECL_VISIBILITY_SPECIFIED (fn)) + if (! TREE_PUBLIC (fn)) + constrain_visibility (decl, VISIBILITY_ANON, false); + else if (DECL_VISIBILITY_SPECIFIED (fn)) { DECL_VISIBILITY (decl) = DECL_VISIBILITY (fn); DECL_VISIBILITY_SPECIFIED (decl) = @@ -2414,10 +2416,9 @@ determine_visibility (tree decl) /* Local classes in templates have CLASSTYPE_USE_TEMPLATE set, but have no TEMPLATE_INFO. Their containing template - function does, and the local class could be constrained - by that. */ - if (template_decl) - template_decl = fn; + function determines their visibility, so we neither + need nor want the template_decl handling. */ + template_decl = NULL_TREE; } else if (VAR_P (decl) && DECL_TINFO_P (decl) && flag_visibility_ms_compat) diff --git a/gcc/testsuite/g++.dg/lto/pr83720_0.C b/gcc/testsuite/g++.dg/lto/pr83720_0.C new file mode 100644 index 0000000..4e63c9b --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr83720_0.C @@ -0,0 +1,55 @@ +// PR c++/83720 +// { dg-lto-do assemble } + +#pragma GCC diagnostic ignored "-Wreturn-type" + +namespace b { +class h { +public: + template h(ae af::*...) { + [] {}; + } +}; +class ai {}; +template class c { +public: + template void aj(const char *, ag f) { h(f, int()); } +}; +} +template class al; +template class i { +protected: + static e g(const int) { } +}; +template class j; +template +class j : i { + typedef i ap; + +public: + static an aq(const int &ar, ao... as) { ap::g(ar)(as...); } +}; +template class al { + template using ax = a; + +public: + template , typename = ax> + al(e); + using ay = an (*)(const int &, ao...); + ay az; +}; +template +template +al::al(e) { + az = j::aq; +} +class k { +public: + k(al); +} d([](b::ai) { + struct be { + virtual void f(); + }; + struct bf; + b::c().aj("", &be::f); +}); -- 2.7.4