This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH for c++/85646, lambda visibility


I spent a while tweaking the visibility code while I was working on
the lambdas in templates overhaul, but ended up putting that aside.
This PR led me to pull that out again, but I hadn't realized that some
of the code I was messing with was only a year old, from Nathan's fix
for c++/79296.  Specifically, the code to look at template arguments
from an enclosing function, which I had been thinking looked
unnecessary.

Looking at 79296 again, it turns out that the reason the old code
wasn't working properly was my change to vague_linkage_p to handle
thunked 'tor variants by looking at the flags on one of the thunks
rather than the maybe-in-charge variant.  This code is correct for the
state after maybe_{clone,thunk}_body, but wrong before then, as the
linkage isn't copied to the variants until that point.  So this patch
adds a check of DECL_ABSTRACT_P so that we only look at a thunk once
we've decided it's a thunk.

With that fixed, I can revert the part of Nathan's patch, as modified
by me later for lambda issues, that looks at template arguments from
the enclosing function.

Tested x86_64-pc-linux-gnu, applying to trunk and 8.
commit 41895340ffee90823ff6c191d3518385337e2378
Author: Jason Merrill <jason@redhat.com>
Date:   Mon May 7 16:58:08 2018 -0400

            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.

diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index b0bf8241f71..9aae34a814c 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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
index 00000000000..359f8e4af5a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/visibility/lambda1.C
@@ -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>(); }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]