public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/107597] New: LTO causes static inline variables to get a non-uniqued global symbol
@ 2022-11-09 19:09 cfsteefel at arista dot com
  2022-11-10  7:31 ` [Bug c++/107597] " rguenth at gcc dot gnu.org
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: cfsteefel at arista dot com @ 2022-11-09 19:09 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107597

            Bug ID: 107597
           Summary: LTO causes static inline variables to get a
                    non-uniqued global symbol
           Product: gcc
           Version: 8.4.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: cfsteefel at arista dot com
  Target Milestone: ---

The following was seen with gcc 11.3.1 (centos7 based) and gcc 8.4 (also
centos7 based).

The following code produces a GNU extension unique symbol for NonTemplated::x
when flto is not used ('u' in nm), but a global non-unique symbol when flto is
used, even when building a shared library ('B' in nm).

class NonTemplated {
   static inline int x;
   public:
   void doFoo() {
      x++;
   }
};

int main() {
   NonTemplated n;
   n.doFoo();
   return 0;
}

> g++ -std=gnu++17 -O2 -shared -fPIC -o libFoo.so -flto test.cpp
> nm ./libFoo.so | c++filt | grep NonTemplated
000000000020102c B NonTemplated::x


> g++ -std=gnu++17 -O2 -shared -fPIC -o libFoo.so test.cpp
> nm ./libFoo.so | c++filt | grep NonTemplated
000000000020102c u NonTemplated::x

When compiled under clang++, the symbol is `V` (weak) regardless of flto is
used or not.

The resulting symptom of this is that Address Sanitizer will flag the variable
NonTemplated::X as an ODR violation, if the class is included into more than
one flto compiled shared library.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/107597] LTO causes static inline variables to get a non-uniqued global symbol
  2022-11-09 19:09 [Bug c++/107597] New: LTO causes static inline variables to get a non-uniqued global symbol cfsteefel at arista dot com
@ 2022-11-10  7:31 ` rguenth at gcc dot gnu.org
  2022-11-11 17:42 ` hubicka at ucw dot cz
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-11-10  7:31 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107597

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |amodra at gcc dot gnu.org,
                   |                            |hubicka at gcc dot gnu.org,
                   |                            |jason at gcc dot gnu.org,
                   |                            |rguenth at gcc dot gnu.org
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2022-11-10
           Keywords|                            |lto, wrong-code
             Status|UNCONFIRMED                 |NEW

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
1
libFoo.so-t.o 2
192 c3d22ca2af7ab12c PREVAILING_DEF_IRONLY_EXP main
197 c3d22ca2af7ab12c PREVAILING_DEF_IRONLY_EXP _ZN12NonTemplated1xE

confirmed (binutils 2.37).  I think the above shows the linker doesn't
properly communicate the uniqueness but we might be able to recover from
the bits we have in the streamed IL?

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/107597] LTO causes static inline variables to get a non-uniqued global symbol
  2022-11-09 19:09 [Bug c++/107597] New: LTO causes static inline variables to get a non-uniqued global symbol cfsteefel at arista dot com
  2022-11-10  7:31 ` [Bug c++/107597] " rguenth at gcc dot gnu.org
@ 2022-11-11 17:42 ` hubicka at ucw dot cz
  2022-11-14 17:38 ` cfsteefel at arista dot com
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: hubicka at ucw dot cz @ 2022-11-11 17:42 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107597

--- Comment #2 from Jan Hubicka <hubicka at ucw dot cz> ---
Hi,
What happens is that we read the symbol as:
  Visibility: externally_visible semantic_interposition
prevailing_def_ironly_exp public weak comdat comdat_group:_ZN12NonTemplated1xE
one_only
While in visibility pass we promote it to:
  Visibility: externally_visible semantic_interposition
prevailing_def_ironly_exp public comdat
So we disolve comdat group and turn off weak. This leads to better code
generation and we know it does not affect dynamic linking since in
shared library all symbols are interposable.

So this is kind of feature.   How the ODR violations are detected?
I wonder if keeping weak flag disturbs something.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/107597] LTO causes static inline variables to get a non-uniqued global symbol
  2022-11-09 19:09 [Bug c++/107597] New: LTO causes static inline variables to get a non-uniqued global symbol cfsteefel at arista dot com
  2022-11-10  7:31 ` [Bug c++/107597] " rguenth at gcc dot gnu.org
  2022-11-11 17:42 ` hubicka at ucw dot cz
@ 2022-11-14 17:38 ` cfsteefel at arista dot com
  2022-11-21 10:12 ` marxin at gcc dot gnu.org
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: cfsteefel at arista dot com @ 2022-11-14 17:38 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107597

--- Comment #3 from Christoph Steefel <cfsteefel at arista dot com> ---
Address sanitizer is the one that flags it.
This is the code I used to reproduce the failure.

test.h:
class NonTemplated {
   static inline int x;
   public:
   void doFoo() {
      x++;
   }
};

int foo();
int bar();

test1.cpp:
#include "test.h"
int foo() {
   NonTemplated n;
   n.doFoo();
   return 1;
}

test2.cpp:
#include "test.h"
int bar() {
   NonTemplated n;
   n.doFoo();
   return 1;
}

main.cpp:
#include "test.h"
int main(){
   foo();
   bar();
   return 0;
}

>  g++ -shared -o libTest1.so -flto -fsemantic-interposition -fPIC test1.cpp -fsanitize=address
> g++ -shared -o libTest2.so -flto -fsemantic-interposition -fPIC test2.cpp -fsanitize=address
> g++ -shared -o libMain.so -flto -fsemantic-interposition -fPIC main.cpp -fsanitize=address
> g++ libMain.so libTest1.so  libTest2.so -fsanitize=address

> LD_LIBRARY_PATH=. ./a.out
=================================================================
==9794==ERROR: AddressSanitizer: odr-violation (0x7f6340a3d0e0):
  [1] size=4 'x' test.h:2:22
  [2] size=4 'x' test.h:2:22
... (backtrace elided)

My general understanding is that address sanitizer doesn't instrument weak or
unique symbols, but will clearly instrument the non-weak symbol here.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/107597] LTO causes static inline variables to get a non-uniqued global symbol
  2022-11-09 19:09 [Bug c++/107597] New: LTO causes static inline variables to get a non-uniqued global symbol cfsteefel at arista dot com
                   ` (2 preceding siblings ...)
  2022-11-14 17:38 ` cfsteefel at arista dot com
@ 2022-11-21 10:12 ` marxin at gcc dot gnu.org
  2022-12-28  9:37 ` marxin at gcc dot gnu.org
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: marxin at gcc dot gnu.org @ 2022-11-21 10:12 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107597

Martin Liška <marxin at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Assignee|unassigned at gcc dot gnu.org      |marxin at gcc dot gnu.org
                 CC|                            |marxin at gcc dot gnu.org
             Status|NEW                         |ASSIGNED

--- Comment #4 from Martin Liška <marxin at gcc dot gnu.org> ---
I'll take a look at why it's not caught by ASAN.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/107597] LTO causes static inline variables to get a non-uniqued global symbol
  2022-11-09 19:09 [Bug c++/107597] New: LTO causes static inline variables to get a non-uniqued global symbol cfsteefel at arista dot com
                   ` (3 preceding siblings ...)
  2022-11-21 10:12 ` marxin at gcc dot gnu.org
@ 2022-12-28  9:37 ` marxin at gcc dot gnu.org
  2022-12-28  9:39 ` marxin at gcc dot gnu.org
  2023-01-04 17:28 ` hubicka at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: marxin at gcc dot gnu.org @ 2022-12-28  9:37 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107597

--- Comment #5 from Martin Liška <marxin at gcc dot gnu.org> ---
> 
> So this is kind of feature.   How the ODR violations are detected?

ASAN emits 

> I wonder if keeping weak flag disturbs something.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/107597] LTO causes static inline variables to get a non-uniqued global symbol
  2022-11-09 19:09 [Bug c++/107597] New: LTO causes static inline variables to get a non-uniqued global symbol cfsteefel at arista dot com
                   ` (4 preceding siblings ...)
  2022-12-28  9:37 ` marxin at gcc dot gnu.org
@ 2022-12-28  9:39 ` marxin at gcc dot gnu.org
  2023-01-04 17:28 ` hubicka at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: marxin at gcc dot gnu.org @ 2022-12-28  9:39 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107597

Martin Liška <marxin at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Assignee|marxin at gcc dot gnu.org          |unassigned at gcc dot gnu.org
             Status|ASSIGNED                    |NEW

--- Comment #6 from Martin Liška <marxin at gcc dot gnu.org> ---
> So this is kind of feature.   How the ODR violations are detected?
> I wonder if keeping weak flag disturbs something.

ASAN emits so-called ODR indicators for all global symbols that survive the
following check: asan_needs_odr_indicator_p (tree decl)
in asan.cc:3216

And that's we see 2 of them:

marxin@marxinbox:~/Programming/testcases/PR107597> nm libTest1.so | grep odr
00000000000040c0 B __odr_asan._ZN12NonTemplated1xE
marxin@marxinbox:~/Programming/testcases/PR107597> nm libTest2.so | grep odr
00000000000040c0 B __odr_asan._ZN12NonTemplated1xE

which eventually ends up with the run-time error.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/107597] LTO causes static inline variables to get a non-uniqued global symbol
  2022-11-09 19:09 [Bug c++/107597] New: LTO causes static inline variables to get a non-uniqued global symbol cfsteefel at arista dot com
                   ` (5 preceding siblings ...)
  2022-12-28  9:39 ` marxin at gcc dot gnu.org
@ 2023-01-04 17:28 ` hubicka at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: hubicka at gcc dot gnu.org @ 2023-01-04 17:28 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107597

--- Comment #7 from Jan Hubicka <hubicka at gcc dot gnu.org> ---
So I guess it is asan being confused by our optimization.  We intentionaly
duplicate the symbol in order to reduce cost of dynamic linking in situations
where we know it does not change semantics, but asan looks for such duplicates
and consider them ODR violations.

I guess we want to disable the optimization with -fsanitize-address.  I will
try to cook up a patch.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2023-01-04 17:28 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-09 19:09 [Bug c++/107597] New: LTO causes static inline variables to get a non-uniqued global symbol cfsteefel at arista dot com
2022-11-10  7:31 ` [Bug c++/107597] " rguenth at gcc dot gnu.org
2022-11-11 17:42 ` hubicka at ucw dot cz
2022-11-14 17:38 ` cfsteefel at arista dot com
2022-11-21 10:12 ` marxin at gcc dot gnu.org
2022-12-28  9:37 ` marxin at gcc dot gnu.org
2022-12-28  9:39 ` marxin at gcc dot gnu.org
2023-01-04 17:28 ` hubicka at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).