Bug 80947 - [7 Regression] Different visibility for the lambda and its capture list members with -fvisibility=hidden
Summary: [7 Regression] Different visibility for the lambda and its capture list membe...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 6.3.0
: P2 normal
Target Milestone: 8.0
Assignee: Not yet assigned to anyone
URL:
Keywords: c++-lambda, diagnostic, visibility
Depends on:
Blocks: lambdas
  Show dependency treegraph
 
Reported: 2017-06-01 22:52 UTC by Vlad Zolotarov
Modified: 2022-03-11 00:32 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work: 5.4.0, 8.0
Known to fail: 6.4.0, 7.2.0, 7.5.0
Last reconfirmed: 2017-09-14 00:00:00


Attachments
an ii value generated by g++-6 (85 bytes, text/plain)
2017-06-05 11:08 UTC, Vlad Zolotarov
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Vlad Zolotarov 2017-06-01 22:52:14 UTC
I'm trying to compile a C++14 program using standard g++-6 and g++-7 compilers coming with Ubuntu 16.04:

g++-6 (Ubuntu/Linaro 6.3.0-18ubuntu2~16.04) 6.3.0 20170519
g++-7 (Ubuntu 7.1.0-5ubuntu2~16.04) 7.1.0

The error I get with both of them is the same.

The issue doesn't reproduce with the
g++ (Ubuntu 5.4.1-2ubuntu1~16.04) 5.4.1 20160904

The issue doesn't reproduce when I use -fvisibility=default.

The error looks as follows:


g++-6 -MD -MT build/release/gms/versioned_value.o -MF build/release/gms/versioned_value.o.d -std=gnu++1y -g  -Wall -Werror -fvisibility-inlines-hidden -fvisibility=hidden  -pthread -I/home/vladz/work/urchin/seastar -I/home/vladz/work/urchin/seastar/fmt -I/home/vladz/work/urchin/seastar/build/release/gen  -march=nehalem -fconcepts -Ifmt -DBOOST_TEST_DYN_LINK -Wno-overloaded-virtual -DFMT_HEADER_ONLY -DHAVE_GCC6_CONCEPTS -DHAVE_HWLOC -DHAVE_NUMA -DHAVE_LZ4_COMPRESS_DEFAULT  -O2 -I/usr/include/jsoncpp -DBOOST_TEST_DYN_LINK  -Wno-maybe-uninitialized -Wno-tautological-compare -Wno-missing-braces -Wno-error=deprecated-declarations -DHAVE_LIBSYSTEMD=1 -I. -I build/release/gen -I seastar -I seastar/build/release/gen -c -o build/release/gms/versioned_value.o gms/versioned_value.cc
In file included from ./utils/exponential_backoff_retry.hh:25:0,
                 from ./sstables/compaction_manager.hh:32,
                 from ./database.hh:67,
                 from ./repair/repair.hh:31,
                 from ./message/messaging_service.hh:34,
                 from gms/versioned_value.cc:39:
/home/vladz/work/urchin/seastar/core/sleep.hh: In instantiation of ‘struct seastar::sleep(std::chrono::duration<_Rep, _Period>)::sleeper::sleeper(std::chrono::duration<_Rep, _Period>) [with Clock = std::chrono::_V2::steady_clock; Rep = long int; Period = std::ratio<1l, 1000l>]::<lambda()>’:
/home/vladz/work/urchin/seastar/core/sleep.hh:48:47:   required from ‘seastar::sleep(std::chrono::duration<_Rep, _Period>)::sleeper::sleeper(std::chrono::duration<_Rep, _Period>) [with Clock = std::chrono::_V2::steady_clock; Rep = long int; Period = std::ratio<1l, 1000l>]’
/home/vladz/work/urchin/seastar/core/sleep.hh:52:5:   required from ‘seastar::future<> seastar::sleep(std::chrono::duration<_Rep, _Period>) [with Clock = std::chrono::_V2::steady_clock; Rep = long int; Period = std::ratio<1l, 1000l>]’
./utils/exponential_backoff_retry.hh:45:36:   required from here
/home/vladz/work/urchin/seastar/core/sleep.hh:48:24: error: ‘seastar::sleep(std::chrono::duration<_Rep, _Period>)::sleeper::sleeper(std::chrono::duration<_Rep, _Period>) [with Clock = std::chrono::_V2::steady_clock; Rep = long int; Period = std::ratio<1l, 1000l>]::<lambda()>’ declared with greater visibility than the type of its field ‘seastar::sleep(std::chrono::duration<_Rep, _Period>)::sleeper::sleeper(std::chrono::duration<_Rep, _Period>) [with Clock = std::chrono::_V2::steady_clock; Rep = long int; Period = std::ratio<1l, 1000l>]::<lambda()>::<this capture>’ [-Werror=attributes]
             : tmr([this] { done.set_value(); })
                        ^
cc1plus: all warnings being treated as errors


Error message implies that the visibility of the lambda in question is  greater than the visibility of the capture list value "this".

Since lambdas are translated into the classes with the operator()(...)  and (it seems like) captured values are translated into the fields of this class it looks like for some reason the visibility of that class is higher than the one of those fields.

Another workaround that would make the error go away is to explicitly use the __attribute__ ((visibility ("hidden"))) or __attribute__ ((visibility ("default"))) for the sleeper struct.

Attached is an *.ii value generated by g++-6
Comment 1 Vlad Zolotarov 2017-06-05 11:08:33 UTC
Created attachment 41472 [details]
an ii value generated by g++-6
Comment 2 lars 2017-06-07 07:57:33 UTC
I am being bitten by this as well. I posted a question on stackoverflow about this and was presented with this bug.

My question contains a small example of how to produce this warning, so I thought it might be of interest:

https://stackoverflow.com/questions/44390898/gcc-6-x-warning-about-lambda-visibility
Comment 3 Avi Kivity 2017-09-14 15:10:00 UTC
A gentle ping, in the unlikely case that this bug was forgotten.
Comment 4 Jonathan Wakely 2017-09-14 15:22:59 UTC
(In reply to Vlad Zolotarov from comment #1)
> Created attachment 41472 [details]
> an ii value generated by g++-6

This is a URL not a preprocessed file.

Reproducer from comment 2 (thanks):

template<class T>
class MyClass  {
public:
    MyClass() {
        auto outer = [this]()
            {
                auto fn = [this]   { };
            };
    }
};
int main() { MyClass<int> r; }
Comment 5 Vlad Zolotarov 2017-09-14 17:55:59 UTC
(In reply to Jonathan Wakely from comment #4)
> (In reply to Vlad Zolotarov from comment #1)
> > Created attachment 41472 [details]
> > an ii value generated by g++-6
> 
> This is a URL not a preprocessed file.

The file is too big to be attached directly therefore I've attached the URL that leads you to the file in question like it was recommended by Bugzilla when I tried to attach the file.

> 
> Reproducer from comment 2 (thanks):
> 
> template<class T>
> class MyClass  {
> public:
>     MyClass() {
>         auto outer = [this]()
>             {
>                 auto fn = [this]   { };
>             };
>     }
> };
> int main() { MyClass<int> r; }
Comment 6 Jonathan Wakely 2017-09-14 18:47:23 UTC
(In reply to Vlad Zolotarov from comment #5)
> (In reply to Jonathan Wakely from comment #4)
> > (In reply to Vlad Zolotarov from comment #1)
> > > Created attachment 41472 [details]
> > > an ii value generated by g++-6
> > 
> > This is a URL not a preprocessed file.
> 
> The file is too big to be attached directly therefore I've attached the URL
> that leads you to the file in question like it was recommended by Bugzilla
> when I tried to attach the file.

Did you try compressing it? Even if that's still too big you can just put the URL in a comment, creating an attachment that contains a URL is just pointless indirection.
Comment 7 Jonathan Wakely 2017-09-14 18:51:27 UTC
Wow bugzilla really does suggest that. How stupid.
Comment 8 Vlad Zolotarov 2017-09-14 19:00:26 UTC
(In reply to Jonathan Wakely from comment #7)
> Wow bugzilla really does suggest that. How stupid.

And the (In reply to Jonathan Wakely from comment #6)
> (In reply to Vlad Zolotarov from comment #5)
> > (In reply to Jonathan Wakely from comment #4)
> > > (In reply to Vlad Zolotarov from comment #1)
> > > > Created attachment 41472 [details]
> > > > an ii value generated by g++-6
> > > 
> > > This is a URL not a preprocessed file.
> > 
> > The file is too big to be attached directly therefore I've attached the URL
> > that leads you to the file in question like it was recommended by Bugzilla
> > when I tried to attach the file.
> 
> Did you try compressing it? 


The "Reporting Bugs" at https://gcc.gnu.org/bugs/ explicitly says not to attach any archives.

Even if that's still too big you can just put
> the URL in a comment, creating an attachment that contains a URL is just
> pointless indirection.
Comment 9 Jonathan Wakely 2017-09-14 19:44:21 UTC
It says not to attach an archive containing the things we don't want (e.g. sources without includes). And a .gz file is not an archive.
Comment 10 Vlad Zolotarov 2017-09-14 20:07:30 UTC
(In reply to Jonathan Wakely from comment #9)
> It says not to attach an archive containing the things we don't want (e.g.
> sources without includes). And a .gz file is not an archive.


"Please avoid posting an archive (.tar, .shar or .zip); we generally need just a single file to reproduce the bug (the .i/.ii/.f preprocessed file), and, by storing it in an archive, you're just making our volunteers' jobs harder."

But if you insist I can gzip and post it. Whatever makes it easier to fix the issue. Please, let me know if that's what you want.
Comment 11 Jonathan Wakely 2017-09-15 12:52:05 UTC
(In reply to Vlad Zolotarov from comment #10)
> (In reply to Jonathan Wakely from comment #9)
> > It says not to attach an archive containing the things we don't want (e.g.
> > sources without includes). And a .gz file is not an archive.
> 
> 
> "Please avoid posting an archive (.tar, .shar or .zip); we generally need

And those are all archive formats, not just compression formats like gzip.

> just a single file to reproduce the bug (the .i/.ii/.f preprocessed file),

A gzipped single file is a single file.

> and, by storing it in an archive, you're just making our volunteers' jobs
> harder."

A gzipped file is not an archive.

An attachment that is a URL that must be copied and pasted to get a Google Docs page with data that must be copied and pasted or downloaded is also making it harder!
 
> But if you insist I can gzip and post it. Whatever makes it easier to fix
> the issue. Please, let me know if that's what you want.

There's no need now because comment 4 shows the issue, but next time yes, please attach the preprocessed source directly. If it's too big compress it, or better still reduce it: https://gcc.gnu.org/wiki/A_guide_to_testcase_reduction

That way the reproducer is in our bugzilla permanently. Files hosted externally might go away or change, so we want the file *here*.
Comment 12 Paolo Carlini 2017-09-18 09:20:25 UTC
As far as the snippet in Comment #4 is concerned, current trunk seems fine to me. To be clear, I'm only adding -fvisibility-inlines-hidden -fvisibility=hidden to the command line (which reproduces the issue in gcc-7-branch; in fact -fvisibility=hidden is enough).

Jonathsn, can you double check and confirm that the snippet is supposed to require only the above?
Comment 13 Jonathan Wakely 2017-09-18 11:01:50 UTC
(In reply to Paolo Carlini from comment #12)
> As far as the snippet in Comment #4 is concerned, current trunk seems fine
> to me.

Ah yes. It was fixed on trunk by r251433
Comment 14 Paolo Carlini 2017-09-18 11:45:37 UTC
I see. I'm adding the testcase, but it's still a 6/7 Regression, hopefully part of the lambda overhaul can be easily backported.
Comment 15 paolo@gcc.gnu.org 2017-09-18 23:57:57 UTC
Author: paolo
Date: Mon Sep 18 23:57:26 2017
New Revision: 252957

URL: https://gcc.gnu.org/viewcvs?rev=252957&root=gcc&view=rev
Log:
2017-09-18  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/80947
	* g++.dg/cpp0x/lambda/lambda-80947.C: New.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-80947.C
Modified:
    trunk/gcc/testsuite/ChangeLog
Comment 16 Duarte 2018-05-03 17:29:01 UTC
This is happening again in g++ (GCC) 8.0.1 20180324 (Red Hat 8.0.1-0.20).
Comment 17 Duarte 2018-05-03 21:04:17 UTC
It also fails on GCC 8.1. This is the reproducer:

template<typename T>
void foo() {
    struct inner {
        inner() {
            ([this] { });
        }
    };
}

int main() { foo<int>(); }

It fails when compiled with -fvisibility=hidden, but succeeds with -fvisibility=default.

It also compiles fine without the template.
Comment 18 Jakub Jelinek 2018-10-26 10:07:32 UTC
GCC 6 branch is being closed
Comment 19 Richard Biener 2019-11-14 09:54:38 UTC
Fixed in GCC 8.