PR c++/85646 - lambda visibility.
authorJason Merrill <jason@redhat.com>
Mon, 7 May 2018 23:50:16 +0000 (19:50 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 7 May 2018 23:50:16 +0000 (19:50 -0400)
* decl2.c (determine_visibility): Don't mess with template arguments
from the containing scope.
(vague_linkage_p): Check DECL_ABSTRACT_P before looking at a 'tor
thunk.

From-SVN: r260017

gcc/cp/ChangeLog
gcc/cp/decl2.c
gcc/testsuite/g++.dg/ext/visibility/lambda1.C [new file with mode: 0644]

index 75f52078faa5c21ad3dbb43327cdf455cf58f14f..65991150ef0aa775466ea99365cad733d6649987 100644 (file)
@@ -1,3 +1,11 @@
+2018-05-07  Jason Merrill  <jason@redhat.com>
+
+       PR c++/85646 - lambda visibility.
+       * decl2.c (determine_visibility): Don't mess with template arguments
+       from the containing scope.
+       (vague_linkage_p): Check DECL_ABSTRACT_P before looking at a 'tor
+       thunk.
+
 2018-05-07  Nathan Sidwell  <nathan@acm.org>
 
        Remove fno-for-scope
index b0bf8241f7164b5d3d3be8d58484a817d950ddbd..9aae34a814ce14752f4f62f1a107eab47213881a 100644 (file)
@@ -1939,10 +1939,13 @@ vague_linkage_p (tree decl)
 {
   if (!TREE_PUBLIC (decl))
     {
-      /* maybe_thunk_body clears TREE_PUBLIC on the maybe-in-charge 'tor
-        variants, check one of the "clones" for the real linkage.  */
+      /* maybe_thunk_body clears TREE_PUBLIC and DECL_ABSTRACT_P on the
+        maybe-in-charge 'tor variants; in that case we need to check one of
+        the "clones" for the real linkage.  But only in that case; before
+        maybe_clone_body we haven't yet copied the linkage to the clones.  */
       if ((DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl)
           || DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl))
+         && !DECL_ABSTRACT_P (decl)
          && DECL_CHAIN (decl)
          && DECL_CLONED_FUNCTION_P (DECL_CHAIN (decl)))
        return vague_linkage_p (DECL_CHAIN (decl));
@@ -2422,21 +2425,8 @@ 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 (DECL_LANG_SPECIFIC (fn) && DECL_USE_TEMPLATE (fn))
-           template_decl = fn;
-         else if (template_decl)
-           {
-             /* FN must be a regenerated lambda function, since they don't
-                have template arguments.  Find a containing non-lambda
-                template instantiation.  */
-             tree ctx = fn;
-             while (ctx && !get_template_info (ctx))
-               ctx = get_containing_scope (ctx);
-             template_decl = ctx;
-           }
+            but have no TEMPLATE_INFO, so don't try to check it.  */
+         template_decl = NULL_TREE;
        }
       else if (VAR_P (decl) && DECL_TINFO_P (decl)
               && flag_visibility_ms_compat)
diff --git a/gcc/testsuite/g++.dg/ext/visibility/lambda1.C b/gcc/testsuite/g++.dg/ext/visibility/lambda1.C
new file mode 100644 (file)
index 0000000..359f8e4
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/85646
+// { dg-do compile { target c++11 } }
+// { dg-additional-options -fvisibility=hidden }
+
+template<typename T>
+void foo() {
+    struct inner {
+        inner() {
+            (void)([this] { });
+        }
+    };
+}
+
+int main() { foo<int>(); }