From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mailx.courier-mta.com (mailx.courier-mta.com [68.166.206.83]) by sourceware.org (Postfix) with UTF8SMTPS id 24FCA386100F for ; Tue, 16 Feb 2021 03:41:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 24FCA386100F Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=courier-mta.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mrsam@courier-mta.com Received: from monster.email-scan.com (monster.email-scan.com [::ffff:192.168.0.2]) (TLS: TLSv1.3,256bits,TLS_AES_256_GCM_SHA384) by www.courier-mta.com with UTF8SMTPS id 00000000002C04ED.00000000602B3EE2.000063A4; Mon, 15 Feb 2021 22:41:22 -0500 Received: from monster.email-scan.com (localhost [127.0.0.1]) (IDENT: uid 1004) by monster.email-scan.com with UTF8SMTP id 000000000001E574.00000000602B3EE2.0000EB3C; Mon, 15 Feb 2021 22:41:22 -0500 Message-ID: X-Mailer: http://www.courier-mta.org/cone/ From: Sam Varshavchik To: gcc-help@gcc.gnu.org Subject: Overriding visibility of template instances Date: Mon, 15 Feb 2021 22:41:22 -0500 Mime-Version: 1.0 Content-Type: multipart/signed; boundary="=_monster.email-scan.com-59947-1613446882-0001"; micalg=pgp-sha1; protocol="application/pgp-signature" X-Spam-Status: No, score=1.4 required=5.0 tests=BAYES_00, KAM_DMARC_STATUS, RCVD_IN_PBL, SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Level: * X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-help@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-help mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Feb 2021 03:41:25 -0000 This is a MIME GnuPG-signed message. If you see this text, it means that your E-mail or Usenet software does not support MIME signed messages. The Internet standard for MIME PGP messages, RFC 2015, was published in 1996. To open this message correctly you will need to install E-mail or Usenet software that supports modern Internet standards. --=_monster.email-scan.com-59947-1613446882-0001 Content-Type: text/plain; format=flowed; delsp=yes; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 7bit I ran into an issue, a link failure, while building with gcc 10 my shared library and a program that links with the shared library. I believe that older versions of gcc/binutils did not result in this link failure, this is somethink new. For a general explanation: I am trying to minimize which symbols my shared library exports. To that end I make judicious use of hidden symbol visibility, marking entire classes as hidden, and not making template implementations publicly visible as well; instantiating entire templates with hidden visibility; as well as not making the template implementations, only declarations. I should also mention that I understand the reason for the following link failure, and I am trying to figure out the best way to fix it, but I'm running into a brick wall, that I'll explain after the minimal code dump. The following results in this link failure: /usr/bin/ld: prog.o:(.data.rel.ro._ZTV4impl[_ZTV4impl]+0x20): undefined reference to `intermediate::initialize()' ############################################################### ## ## Makefile LTOFLAGS = all: prog prog: prog.o lib.so g++ -o prog $(LTOFLAGS) prog.o lib.so prog.o: prog.cpp header.H Makefile g++ $(LTOFLAGS) -c -fpic -DPIC -o prog.o prog.cpp lib.so: lib.o g++ -shared $(LTOFLAGS) -o lib.so lib.o lib.o: lib.cpp header.H Makefile g++ $(LTOFLAGS) -c -fpic -DPIC -o lib.o lib.cpp ############################################################### ## ## header.H struct base { base(); virtual ~base(); /////////////////////////////////////////////////// // // REMOVE VIRTUAL TO FIX THE LINK ERROR: virtual void initialize(); }; /////////////////////////////////////////////////////////////// // // REMOVE THE HIDDEN ATTRIBUTE TO FIX THE LINK ERROR: struct __attribute__((visibility("hidden"))) aux {}; template struct intermediate : public T { intermediate(); void initialize(); ~intermediate(); }; struct __attribute__((visibility("default"))) child; struct child : intermediate { child(); ~child(); }; ############################################################### ## ## lib.cpp #include "header.H" template intermediate::intermediate()=default; template intermediate::~intermediate()=default; template void intermediate::initialize() { } /////////////////////////////////////////////////////////////////////// // // UNCOMMENT TO FIX THE LINK ERROR // // template void __attribute__((visibility("default"))) // intermediate::initialize(); // base::base()=default; base::~base()=default; void base::initialize() { } child::child()=default; child::~child()=default; ############################################################### ## ## prog.cpp #include "header.H" struct impl : public child { }; int main() { impl i; return 0; } ############################################################### ## ## End of example The problem is that prog.cpp needs a reference to intermediate::initialize in order to compile the vtable for the impl class. aux has hidden visibility, and gcc 10 instantiates intermediate with all of its symbols having hidden visibility. The link failure goes away if I do not define base::initialize as virtual, so that class method is not needed for the vtable, or I do not declare the "aux" class as having hidden visibility. The aux class is not needed, and only triggers the hidden visibility of any instance of the intermediate template. The link failure also goes away if I explicitly instantiate intermediate::initialize with default visibility in lib.cpp. prog.cpp does not need the actual definition of this method, it doesn't invoke it, and only needs its symbol. I am trying to figure out if there's any way to fix this linking failure while: 1) having "aux" keep its hidden visibility 2) and without having to explicitly instantiate every instance of intermediate::initialize() with default visibility Adding __attribute__((visibility("default"))) to the declaration of the template class method still results in the link failure: void initialize() __attribute((visibility("default"))); Explicitly declaring default visibility for the template still results in a link failure: template struct __attribute((visibility("default"))) intermediate : public T { Sprinkling push/pop visibility pragmas also makes no difference. That's all I could think of. Any other options I overlooked? --=_monster.email-scan.com-59947-1613446882-0001 Content-Type: application/pgp-signature Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEMWrVnbBKLOeG9ifkazpiviedvyUFAmArPuIACgkQazpivied vyXBXw//T9+Fwgi/WFCeYi2abPbYzjnRvJ81c1BXpTv/8XXbKQwaJhv5okbO8qbV WDDFFq0qzzugBvFb46H4poEZivMVGGlSU/t2comK2r7WH+BDmphiuULfG4ETO6Gu ee7NTaRwLT/DCQhpfCG6YPI/Q2koW4/LhnZXxcNnU5xJ54bhD64bkVslYVaxTOFE Bk5+yzSJ6J9TWRMb04hThrW3A440nwiYZio0uPSRDPSyYKgwnUq/TMfTNdqMIVdT PUw7dTMwj4SmW2w/+A3pTOzDV9QkhsXGI7k7GfHlN/yRqiPi9MmrO5/ICEz1wZov tig/pm5grHkL+IY+BWuGedV4sVRolitkFIE87b4e//X3Z+3tbYpF+lqSxv1GH3dC Y94wajcUQfGPco2w4DsFUKzC7zXMhEe9j43x3kCin22WtcW2232WhZ+wvVwkR6z1 R9B/781YBATCCDH7D4fnFi9jZF/p49YwTSwO5EEuOGxPAesJ5E/jyou6ApmX2QSa z/0QbqhUOoHfyx01XaOmaCv2Y9Wc/LQMjSmO5kg0DnBP3fip+FC2EaoOLJPPm5Fh 513BAzIRg+IMoiHRxwR8na0A20zLFQ2CEkC5ttDVlPoZX7KIUFffztOq8efGlsp8 fMfRPfO+qLRrnvqrxtfhWaww6yngktdVtFoZR0cxrm0MKMiUXYY= =s+TE -----END PGP SIGNATURE----- --=_monster.email-scan.com-59947-1613446882-0001--