[Bug c++/114643] New: Call to a template function emitted but without the code for the template function itself

2024-04-08 Thread abbeyj+gcc at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114643

Bug ID: 114643
   Summary: Call to a template function emitted but without the
code for the template function itself
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: abbeyj+gcc at gmail dot com
  Target Milestone: ---

When building the following example, a linker error is produced.

```
void foo();
template  class DynArray {
public:
  virtual void SetAlloc(unsigned);
  int *m_pElems;
  unsigned m_nNumElems;
  unsigned m_nNumAlloc;
  long m_nChunkSize;
};
void *DoRealloc(void *, long);
template  void DynArray::SetAlloc(unsigned new_size) {
  if (m_nChunkSize)
new_size = m_nChunkSize * m_nChunkSize - 1 / m_nChunkSize;
  else if (m_nNumAlloc)
if (new_size > m_nNumAlloc / 2)
  new_size = new_size > m_nNumAlloc + 1 ? new_size : m_nNumAlloc * 1.5 + 1;
  if (m_nNumElems && m_nNumAlloc && (new_size || m_pElems))
m_pElems = (T *)DoRealloc(m_pElems, 0);
}
struct object {
  DynArray d;
  void f(int size);
};
template  void deser(int size, T ) {
  x.SetAlloc(0);
  if (size) {
x.SetAlloc(size);
foo();
  }
}
void object::f(int size) {
  deser(size, d);
}
```


Build with:
$ g++ -fPIC -O3 -Wall -Werror -fvisibility=hidden reloc.cxx -shared


Output:
> /usr/bin/ld: /tmp/ccLaKma6.o: relocation R_X86_64_PC32 against undefined 
> symbol `_ZN8DynArrayIiE8SetAllocEj' can not be used when making a shared 
> object; recompile with -fPIC
> /usr/bin/ld: final link failed: Bad value
> collect2: error: ld returned 1 exit status


The symbol in the above error message demangles to
`DynArray::SetAlloc(unsigned int)`.

The error message suggests to compile with `-fPIC` but this is already being
compiled with `-fPIC`.  The issue seems to be that GCC emits a call to
`DynArray::SetAlloc` but doesn't emit code for `DynArray::SetAlloc`
itself.

The reproducer was minimized with the help of C-Reduce.  Very minor changes to
the code result in the problem not reproducing anymore.  This is the smallest
that I could manage to get it.

Godbolt link: https://godbolt.org/z/1Ynz1Khac

This appears to have started sometime around GCC 8.1 and still happens on the
trunk version that's currently available on Godbolt.

[Bug lto/114241] New: False-positive -Wodr warning when using -flto and -fno-semantic-interposition

2024-03-05 Thread abbeyj+gcc at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114241

Bug ID: 114241
   Summary: False-positive -Wodr warning when using -flto and
-fno-semantic-interposition
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: lto
  Assignee: unassigned at gcc dot gnu.org
  Reporter: abbeyj+gcc at gmail dot com
  Target Milestone: ---

When building the following example, a `-Wodr` warning is shown.  I don't think
the code violates the ODR so this warning is unexpected.  This reproducer
consists of 3 files.

d.h:
```
class A {
public:
  virtual ~A();
  virtual void a1();
};

class B : public A {
public:
  void a1();
  virtual void b1() = 0;
  virtual void b2() = 0;
};

class C : public B {
};

class D : public C {
public:
  void b1();
  void b2();
};
```


foo.cpp:
```
#include "d.h"

void foo() {
  D x;
}
```


bar.cpp:
```
#include "d.h"

void B::a1() {
}

void bar() {
  D y;
}
```


Build using:
g++ -fPIC -fno-semantic-interposition -flto -c foo.cpp
g++ -fPIC -fno-semantic-interposition -flto -c bar.cpp
g++ -shared foo.o bar.o -o lib.so


Output:
> d.h:14:7: warning: virtual table of type ‘struct C’ violates one definition 
> rule [-Wodr]
>14 | class C : public B {
>   |   ^
> d.h:14:7: note: the conflicting type defined in another translation unit has 
> virtual table with more entries
>14 | class C : public B {
>   |   ^


The warning message here is not great as it refers to "another translation
unit" but never names either of the two translation units involved.  In this
reduced example there are only two translation units but when there are many
translation units involved it is more difficult to figure out where the problem
is coming from.

The bigger issue is that I don't think this warning should have been issued at
all.  I can't see any way that the code is violating the ODR.

The earliest version that I've been able to reproduce with is 8.4

Godbolt link: https://godbolt.org/z/ncnqPMdzq

[Bug tree-optimization/111750] New: Spurious -Warray-bounds warning when using member function pointers

2023-10-09 Thread abbeyj+gcc at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111750

Bug ID: 111750
   Summary: Spurious -Warray-bounds warning when using member
function pointers
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: abbeyj+gcc at gmail dot com
  Target Milestone: ---

Created attachment 56086
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=56086=edit
Reproducer

The source code below generates a -Warray-bounds warning which I believe is
incorrect.  Compile with `g++ -c -Wall -O2`.

```
struct MyClass {
void my_method();
};

MyClass g;

void pre();

inline void FetchValue(MyClass& c, void(MyClass::*func)()) {
pre();
(c.*func)();
}

int get_int();

inline int Check() {
static const int ret = get_int();
return ret;
}

inline void ReadValue(MyClass& c, void(MyClass::*func)()) {
Check();
FetchValue(c, func);
}

void Main() {
ReadValue(g, ::my_method);
}
```

This produces:
```
In function 'void FetchValue(MyClass&, void (MyClass::*)())',
inlined from 'void ReadValue(MyClass&, void (MyClass::*)())' at
:23:15,
inlined from 'void Main()' at :27:14:
:11:14: warning: array subscript 'int (**)(...)[0]' is partly outside
array bounds of 'MyClass [1]' [-Warray-bounds=]
   11 | (c.*func)();
  | ~^~
: In function 'void Main()':
:5:9: note: object 'g' of size 1
5 | MyClass g;
  | ^
```

Godbolt link: https://godbolt.org/z/6YsWd9xhr

That this source produces a -Warray-bounds warning is somewhat surprising since
it contains no arrays, no array indexing, and no pointer arithmetic.  Small
changes such as removing the static variable or manually inlining a function
into its caller make the warning go away.  

The earliest version that I've been able to reproduce this with is GCC 11.1 and
it still reproduces on the trunk version that's currently available on
godbolt.org.