<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - clang unresolved symbol for protobuf RepeatedField template"
   href="https://bugs.llvm.org/show_bug.cgi?id=46313">46313</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>clang unresolved symbol for protobuf RepeatedField template
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>10.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>-New Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>steven@uplinklabs.net
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org, neeilans@live.com, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=23613" name="attach_23613" title="testcase for bug">attachment 23613</a> <a href="attachment.cgi?id=23613&action=edit" title="testcase for bug">[details]</a></span>
testcase for bug

I first noticed this in an automated build for the GameNetworkingSockets
library:

<a href="https://travis-ci.org/github/ValveSoftware/GameNetworkingSockets/jobs/697717206#L1564">https://travis-ci.org/github/ValveSoftware/GameNetworkingSockets/jobs/697717206#L1564</a>

The builder is using Docker to run various distributions of Linux and build the
library against that distribution's system libraries, including protobuf.

In this case, the Docker image is for Arch Linux, which has Clang 10.0, GCC
10.1, and protobuf 3.12.0.

Building the shared library fails because it believes a symbol is missing at
link time:

google::protobuf::RepeatedField<unsigned
int>::RepeatedField(google::protobuf::RepeatedField<unsigned int> const&)

Mangled symbol name is: _ZN6google8protobuf13RepeatedFieldIiEC2ERKS2_

With GCC 10.1, this all compiles and links fine. But this one symbol gives
trouble on Clang 10.0.

This is the difference in unresolved symbols (wrt RepeatedField) in the objects
as compiled by clang/gcc:

# object built with Clang 10.0
$ nm
build-meson-sodium25519/src/25a6634@@GameNetworkingSockets@sha/meson-generated_steamnetworkingsockets_messages.pb.cc.o
 | grep RepeatedField
                 U _ZN6google8protobuf13RepeatedFieldIiE12InternalSwapEPS2_
                 U _ZN6google8protobuf13RepeatedFieldIiE7ReserveEi
                 U _ZN6google8protobuf13RepeatedFieldIiE9MergeFromERKS2_
                 U _ZN6google8protobuf13RepeatedFieldIiEC2ERKS2_
                 U _ZN6google8protobuf13RepeatedFieldIiED1Ev
                 U _ZNK6google8protobuf13RepeatedFieldIiE3GetEi

# object built with gcc 10.1
$ nm
build-meson-sodium25519-gcc/src/25a6634@@GameNetworkingSockets@sha/meson-generated_steamnetworkingsockets_messages.pb.cc.o
 | grep RepeatedField
                 U _ZN6google8protobuf13RepeatedFieldIiE7ReserveEi
                 U _ZN6google8protobuf13RepeatedFieldIiED1Ev

With some effort, I managed to create a reduced test case for this. It's a bit
of a challenge when g++ -E or clang++ -E will generate outputs that cannot be
compiled by the other compiler, but it was easier to tweak the output of "g++
-E -fdirectives-only" to be compilable with Clang than it was the other way
around. I wanted to ensure the test case compiled with both and satisfied the
constraint that _ZN6google8protobuf13RepeatedFieldIiEC2ERKS2_ was undefined in
the clang object and absent from the GCC object. My first attempt used only
clang to create a reduced test case and the symbol ended up being undefined for
*both* compilers, which isn't the desired scenario.

The reduced test case could probably be more concise if someone knows what's
going on with it:

---
namespace google {
namespace protobuf {
enum a { LOGLEVEL_FATAL };
class b {
public:
  b(a, const char *, int);
  ~b();
  b operator<<(const char *);
  b operator<<(char);
};
class c {
public:
  void operator=(b);
};
#define d(f) c() = b(LOGLEVEL_##f, __FILE__, __LINE__)
#define e(f, l) l ? (void)0 : d(f)
#define g(i) e(FATAL, i) << ""
#define h(k, j) g(j)
template <typename> class RepeatedField {
public:
  RepeatedField(const RepeatedField &);
  int o();
  int m;
};
template <typename p>
inline RepeatedField<p>::RepeatedField(const RepeatedField &p1) {
  if (p1.m) {
    int t = o(), n = t;
    h(, n) << m;
  }
}
extern template class RepeatedField<int>;
} // namespace protobuf
} // namespace google
class A {
  A(const A &);
  google::protobuf::RepeatedField<int> q;
};
A::A(const A &p1) : q(p1.q) {}
---

I've attached a tarball with the original partially preprocessed source, the
script I used for creduce, and the two objects built by clang/gcc.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>