thread_local template variable of struct inside anonymous namespace fails to link? - c++

The following example program uses a thread local template variable, and instantiates it using a type inside an anonymous namespace. This produces a linker error in gcc. In clang it actually compiles but does not run correctly.
#include <stdio.h>
template<typename T>
struct container {
container() { printf("construct: %p\n", this); }
~container() { printf("destruct: %p\n", this); }
};
template<typename T>
thread_local container<T> storage;
namespace {
struct bar {};
}
int main() {
auto& ref1 = storage<bar>;
auto& ref2 = storage<bar>;
}
On gcc this fails with a link error:
a.cpp:6:2: warning: ‘container<T>::~container() noexcept [with T = {anonymous}::bar]’ used but never defined
~container() { printf("destruct: %p\n", this); }
^
/tmp/ccgh0P15.o: In function `__tls_init':
a.cpp:(.text+0xa9): undefined reference to `container<(anonymous namespace)::bar>::~container()'
With clang the program compiles but produces very troubling output:
construct: 0x7fb8d1c003d0
construct: 0x7fb8d1c003d0
destruct: 0x7fb8d1c003d0
destruct: 0x7fb8d1c003d0
Are there some rough edges surrounding thread_local/templated variables that I am running into here? I am unclear why this would ever produce a link error (the link error disappears if I remove thread_local). In the case of clang how could a double destroy of an object with static storage duration be anything but a compiler bug? In clang the issue disappears if I remove the anonymous namespace OR the thread_local specification, OR by removing one of the references in main().
Can anyone shed some light on this, I am mainly just curious if I am misunderstanding something. Thanks!
EDIT:
clang++ -v
Apple LLVM version 10.0.0 (clang-1000.11.45.5)
g++ -v
gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)

Related

Why constexpr implicit conversion doesn't always work?

#include <iostream>
struct Index {
constexpr operator int() const { return 666; }
};
template <int i> void foo() {
std::cout << i << std::endl;
}
void wrapper(Index index) {
foo<index>();
}
int main() {
Index index;
// foo<index>(); // error: the value of ‘index’ is not usable in a constant expression
wrapper(index);
}
Hello, everyone.
I'm using a constexpr conversion of a variable "index" to an int value, which is substituted to a "foo" templated function.
If I directly call foo<index>() from "main", I get a compiler error.
If the same call is done from the "wrapper", then everything compiles and works fine.
What am I missing there?
Compile command: g++ -std=c++14 main.tex with g++ (GCC) 5.3.1 20160406 (Red Hat 5.3.1-6).
A very similar error was reported here. It was first reported with GCC 4.9.0
In the analysis provided:
This is a GCC bug. It appears to be some sort of confusion in the way GCC handles internal linkage non-type template parameters of pointer type.
It has since been resolved.

Clang warning in dubious case: function 'foo' could be declared with attribute 'noreturn'?

I have been playing around a bit with the [[noreturn]] attribute, which I'm trying to get a handle of and make use of (I understand [[noreturn]] is a C++11 standard attribute and __attribute__((noreturn)) is a GCC/Clang extension). As part of this, I enabled the Clang warning -Wmissing-noreturn.
> clang++ -v
Ubuntu clang version 3.7.1-svn253742-1~exp1 (branches/release_37) (based on LLVM 3.7.1)
Target: x86_64-pc-linux-gnu
Thread model: posix
foo.cpp:
enum bar
{
A = 1,
B,
C
};
void foo()
{
switch (bar())
{
case A:
case B:
case C:
default:
break;
}
}
int main()
{
foo();
return 0;
}
Then compile:
> clang++ foo.cpp -o foo -Wmissing-noreturn -std=c++14
foo.cpp:9:1: warning: function 'foo' could be declared with attribute 'noreturn'
[-Wmissing-noreturn]
{
^
1 warning generated.
It appears to me that it would return! What's going on here? Is this a compiler bug?
If you remove the "= 1" from A, then it compiles fine without a warning.
If I do make the foo() function [[noreturn]] void foo(), then it does crash with a segmentation fault.
Ok sorry for delete the last answer. It was wrong. Ok noreturn meann that the function never end. and the segementation fould is because bar is not a variable
Just to give a follow up to an old question: clang is correct, even if a little pedantic.
Indeed the attribute noreturn is applicable to your foo() function, since it doesn't return anything. The fact that clang of 2016 gets confused with the slight variation in the enumeration that is a problem.
But we should forgive clang for this pecadillo, for C++11 grammar is not what could be called very simple.

Field name same as field type using unnamed namespace

Consider this sample of code:
#include <iostream>
namespace /* unnamed namespace */
{
struct Foo
{
int a;
int b;
};
}
struct Boo
{
Foo Foo; /* field name same as field type */
int c;
void print();
};
void Boo::print()
{
std::cout<<"c = "<<c<<std::endl;
std::cout<<"Foo "<<Foo.a<<" "<<Foo.b<<std::endl;
}
int main()
{
Boo boo;
boo.c=30;
boo.Foo.a=-21;
boo.Foo.b=98;
boo.print();
return 0;
}
Clang can compile it without errors.
Debian clang version 3.5.0-9 (tags/RELEASE_350/final) (based on LLVM 3.5.0)
Microsoft cl.exe compile it without errors. (I don't remember version. I use VS 2012)
And GCC: gcc version 4.9.2 (Debian 4.9.2-10):
main.cpp:14:6: error: declaration of ‘{anonymous}::Foo Boo::Foo [-fpermissive]
Foo Foo; /* field name same as field type */
^
main.cpp:5:9: error: changes meaning of ‘Foo’ from ‘struct {anonymous}::Foo’[-fpermissive]
struct Foo
^
What is good behavior of compiler? Why GCC can't compile it, but clang and cl.exe does? What C++ standard says?
Both are correct. Per §3.3.7/1
The following rules describe the scope of names declared in classes.
[..]
A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. No diagnostic is required for a violation of this rule.
Neither are obligated to give an error, gcc chose to and clang apparently chose not to. It's conforming either way.

Workaround for debug symbol error with auto member function?

There seems to be an issue with debug symbols and auto.
I have an auto function in a class:
#include <cstddef>
template <typename T>
struct binary_expr {
auto operator()(std::size_t i){
return 1;
}
};
int main(){
binary_expr<double> b;
return 0;
}
When I compile with G++ (4.8.2) and -g, I have this error:
g++ -g -std=c++1y auto.cpp
auto.cpp: In instantiation of ‘struct binary_expr<double>’:
auto.cpp:11:25: required from here
auto.cpp:4:8: internal compiler error: in gen_type_die_with_usage, at dwarf2out.c:19484
struct binary_expr {
^
Please submit a full bug report,
with preprocessed source if appropriate.
See <https://bugs.gentoo.org/> for instructions.
With clang++ (3.4) and -g, I have this:
clang++ -g -std=c++1y auto.cpp
error: debug information for auto is not yet supported
1 error generated.
If I remove the -g or set the type explicitly, it works perfectly.
Isn't clang++ supposed to be C++14 feature complete ?
Is there a workaround for these limitations or I'm screwed ?
This now seems to works on Clang 3.5 SVN. Live Example. It seems that the culprit was a commit from May 2013, see this message on the Clang mailing list.
PR16091: Error when attempting to emit debug info for undeduced auto
return types
Perhaps we should just suppress this, rather than erroring, but since
we have the infrastructure for it I figured I'd use it - if this is
determined to be not the right thing we should probably remove that
infrastructure entirely. I guess it's lying around from the early days
of implementing debug info support.
// RUN: %clang_cc1 -emit-llvm-only -std=c++1y -g %s 2>&1 | FileCheck %s
2
3 struct foo {
4 auto func(); // CHECK: error: debug information for auto is not yet supported
5 };
6
7 foo f;
However, I cannot find the commit that removed this info, perhaps there was an improvement that now prevents that this behavior is being triggered.
Even after some time, the only workaround I have found is to make the function template, pretty stupid workaround... Apparently, clang has no problem with auto functions that are template. I don't know if this works in every case, but until now it had worked for me.
#include <cstddef>
template <typename T>
struct binary_expr {
template<typename E = void>
auto operator()(std::size_t i){
return 1;
}
};
int main(){
binary_expr<double> b;
return 0;
}

Unused const object of class with virtual desctructor causes segmentation fault

I was struggling with segmentation fault after returning from main in C++0x code compiled under GCC with MinGW, and have narrowed it to simple case:
class A {
public:
virtual ~A();
};
A::~A() {
}
const A a;
int main() {
return 0;
}
The reason is correlated with:
const qualifier before object, removing it stops seg fault,
Lack of constructor in class A - adding empty one stops seg fault.
Version of compialtor - newer TDM MinGW with gcc 4.8.1 does not build code causing seg fault.
Am I triggering some undefined behavior, or really compiler bug is reason of such behavior?
Affected compiler:
gcc --version
gcc.exe (tdm-1) 4.7.1
g++ --version
g++.exe (tdm-1) 4.7.1
ld --version
GNU ld (GNU Binutils) 2.22
This appears to be gcc bug 55893 that was fixed in 4.7.3. The attached testcase is very similar to yours:
struct foo
{
virtual ~foo () { }
};
int main ()
{
static const foo tmp;
}
The error occurs because gcc places the const object in read-only memory, because it is trivially constructible, without checking that the object has a non-trivial destructor. The destructor, being virtual, attempts to update the vtable pointer, leading to the segfault.