aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2018-01-22 16:51:53 -0500
committerJason Merrill <jason@gcc.gnu.org>2018-01-22 16:51:53 -0500
commit1fcaa1eb87540b689b435914a0d82bc9b65bcc34 (patch)
treeaa8f02923e553c2ef1ed326d60b5888d83e7467f /gcc
parent3774938ec6bd45fa4038613ff0a5d3cf56335a60 (diff)
downloadgcc-1fcaa1eb87540b689b435914a0d82bc9b65bcc34.zip
gcc-1fcaa1eb87540b689b435914a0d82bc9b65bcc34.tar.gz
gcc-1fcaa1eb87540b689b435914a0d82bc9b65bcc34.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/decl2.c11
-rw-r--r--gcc/testsuite/g++.dg/lto/pr83720_0.C55
3 files changed, 69 insertions, 6 deletions
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 <jason@redhat.com>
+
+ 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 <polacek@redhat.com>
PR c++/81933
* typeck2.c (split_nonconstant_init_1): Return false if we didn't
split out anything.
-
+
2018-01-22 Ville Voutilainen <ville.voutilainen@gmail.com>
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 <typename ae, typename af> h(ae af::*...) {
+ [] {};
+ }
+};
+class ai {};
+template <typename> class c {
+public:
+ template <typename ag> void aj(const char *, ag f) { h(f, int()); }
+};
+}
+template <typename> class al;
+template <typename e> class i {
+protected:
+ static e g(const int) { }
+};
+template <typename, typename> class j;
+template <typename an, typename e, typename... ao>
+class j<an(ao...), e> : i<e> {
+ typedef i<e> ap;
+
+public:
+ static an aq(const int &ar, ao... as) { ap::g(ar)(as...); }
+};
+template <typename an, typename... ao> class al<an(ao...)> {
+ template <typename, typename a> using ax = a;
+
+public:
+ template <typename e, typename = ax<int, void>, typename = ax<int, void>>
+ al(e);
+ using ay = an (*)(const int &, ao...);
+ ay az;
+};
+template <typename an, typename... ao>
+template <typename e, typename, typename>
+al<an(ao...)>::al(e) {
+ az = j<an(ao...), e>::aq;
+}
+class k {
+public:
+ k(al<void(b::ai)>);
+} d([](b::ai) {
+ struct be {
+ virtual void f();
+ };
+ struct bf;
+ b::c<bf>().aj("", &be::f);
+});