llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.96k stars 11.94k forks source link

Undefined references to static const members of class templates (but not when const is omitted) #26380

Open llvmbot opened 8 years ago

llvmbot commented 8 years ago
Bugzilla Link 26006
Version trunk
OS Linux
Attachments Test program to reproduce
Reporter LLVM Bugzilla Contributor
CC @DougGregor,@zahiraam

Extended Description

The below program (also attached) produces an undefined reference to Foo::Bar<int>::m when m is declared as const. Just compile it with clang++ test.cpp. It does not compile with the latest clang from the trunk, nor with clang 3.5.

However, when m does not have any additional qualifiers or when m is declared as const volatile, then the program compiles, links, and runs. You can verify this by defining QUALS as empty or as const volatile.

GCC compiles and links the program fine.

This code was distilled from xulrunner 24.8.0.

#define QUALS   const
//#define QUALS const volatile
//#define QUALS

class Foo {
public:
    template <typename T>
    struct Bar {
        static QUALS long m;
    };

    static QUALS long& getter() { return Bar<int>::m; }

    static int f();
};

template <typename T>
QUALS long Foo::Bar<T>::m = 1;

int Foo::f()
{
    return getter();
}

int main()
{
    return Foo::f();
}
llvmbot commented 2 years ago

mentioned in issue llvm/llvm-bugzilla-archive#38106

zahiraam commented 6 years ago

Here is another test case with the same fail on Linux and Windows. gcc and MSVC compile it.

#include <stdio.h>

template <class charT>
struct basic_string
{
  static const int npos;
  basic_string(int = npos) {;}
};

basic_string<char> s;

template <class charT>
const int
basic_string<charT>::npos = -1;

extern "C" { int puts(const char *); }

int main() {
  puts("Should compile without ACCVIOing");
}