Workaround for debug symbol error with auto member function? - c++

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;
}

Related

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

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)

Template Argument Deduction Broken in Clang 6 for Temporary Objects

Template argument deduction appears to be broken in Clang 6 for temporary objects.
g++ 8.1.0 compiles and runs the example correctly.
Clang 6.0.0 and 6.0.2 both error at the indicated line with this message:
error: expected unqualified-id
Print{1,"foo"s,2}; /********** Broken in Clang **********/
All Other lines work correctly.
The behavior is the same in both cases whether -std=c++17 or -std=c++2a is used.
The Clang c++ Status Page indicates that template argument deduction was implemented as of Clang 5 (P0091R3, P0512R0).
Is this a bug? Are there workarounds (e.g. compiler flags, not code changes)?
example:
template<class ...Ts>
void print(Ts...ts){ (( cout << ... << ts )); }
template<class ...Ts>
struct Print {
Print(Ts...ts){ (( cout << ... << ts )); }
};
int main(){
Print{1,"foo"s,2}; /********** Broken in Clang **********/
Print<int,string,int>{1,"foo"s,2};
auto p1 = Print{1,"foo"s,2};
Print p2{1,"foo"s,2};
print(1,"foo"s,2);
}
This is Clang bug 34091.
Luckily, it is already fixed, and the trunk build of Clang compiles this without issue.
As far as I know, however, there is currently no way to work around this without code changes, short of upgrading to the next Clang release whenever that comes out.

Mystifying UB/segfault only on gcc - is the code ill-formed? [duplicate]

I have the following SSCCE:
#include <iostream>
#include <string>
void foo(const std::string &a) {
std::cout << a << std::endl;
}
template <typename... Args>
void bar(Args &&... args) {
[&]() {
[&]() {
foo(args...);
}();
}();
}
int main() {
const std::string x("Hello World!");
bar(x);
}
Under clang++ (3.9.1) this compiles and emits "Hello World". Gcc 6.3 fails with a segmentation fault under -O3.
I can fix the problem by explicitly passing the pointer and the pack by reference, replacing [&]() with [&args...](). However, up to now, I thought that [&] would do the same as listing all arguments one by one.
So what is going wrong here?
P.S:
This is not limited to -O3. -O0 does not segfault but does not return the expected result ("Hello World!"):
[:~/tmp] $ g++-6 -std=c++1z param.cpp && ./a.out
[:~/tmp] $
P.P.S: Further reduced SSCCE. Now I don't even get a diagnostic with -Wall -Wextra anymore.
I strongly suspect a g++ bug.
Here are some notes:
replacing std::string with any elementary type, e.g., int still does not work
clang and VC++ will work just as intended
not passing parameter pack by reference causes an internal compiler error with g++ 7.0.1 with the following output:
internal compiler error: in make_decl_rtl, at varasm.c:1304
...
Please
submit a full bug report, with preprocessed source if appropriate.
Please include the complete backtrace with any bug report. See
http://gcc.gnu.org/bugs.html for instructions.

GCC causes segfault for lambda-captured parameter pack

I have the following SSCCE:
#include <iostream>
#include <string>
void foo(const std::string &a) {
std::cout << a << std::endl;
}
template <typename... Args>
void bar(Args &&... args) {
[&]() {
[&]() {
foo(args...);
}();
}();
}
int main() {
const std::string x("Hello World!");
bar(x);
}
Under clang++ (3.9.1) this compiles and emits "Hello World". Gcc 6.3 fails with a segmentation fault under -O3.
I can fix the problem by explicitly passing the pointer and the pack by reference, replacing [&]() with [&args...](). However, up to now, I thought that [&] would do the same as listing all arguments one by one.
So what is going wrong here?
P.S:
This is not limited to -O3. -O0 does not segfault but does not return the expected result ("Hello World!"):
[:~/tmp] $ g++-6 -std=c++1z param.cpp && ./a.out
[:~/tmp] $
P.P.S: Further reduced SSCCE. Now I don't even get a diagnostic with -Wall -Wextra anymore.
I strongly suspect a g++ bug.
Here are some notes:
replacing std::string with any elementary type, e.g., int still does not work
clang and VC++ will work just as intended
not passing parameter pack by reference causes an internal compiler error with g++ 7.0.1 with the following output:
internal compiler error: in make_decl_rtl, at varasm.c:1304
...
Please
submit a full bug report, with preprocessed source if appropriate.
Please include the complete backtrace with any bug report. See
http://gcc.gnu.org/bugs.html for instructions.

gcc/g++ internal error (c++ templated lambda)

i was just making a few changes to my program, when all of a sudden g++ complained with an internal compiler error.
Clang however compiles it without any problems and also does not give any warnings, that would indicate anything weird.
I distilled the problem down to this:
#include <functional>
template<typename T>
class A{
T someVar;
};
template<typename T>
class B {
int x;
std::function<A<double>(A<int>&)> someLambda = [&](A<int>& aInt){
int xVar = x;
A<double> aRet;
return aRet;
};
};
int main(int argc, char** argv){
B<int> a;
return 0;
}
I tried both GCC 4.9.2 and 4.8.4, with both failing (internal compiler error).
Flags I used:
g++ -std=c++11 -O0 -g -Wall main.cpp -o gccBin
clang++ -std=c++11 -O0 -g -Wall main.cpp -o clangBin
main.cpp: In instantiation of 'struct B<int>::<lambda(class A<int>&)>':
main.cpp:10:7: required from here
main.cpp:14:24: internal compiler error: in tsubst_copy, at cp/pt.c:12569
int xVar = x;
^
libbacktrace could not find executable to open
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
Clang++(3.5.1) compiles it without a problem, as I mentioned.
I also tried multiple machines, everywhere the same.
Is there some kind of error I overlooked? I searched a bit on the internet and the only similar problems i could find should have been fixed by now (as the bugtracker states).
Could maybe someone try and run this code on their machine or give other advice?
Thank you,
Lazarus
It's a compiler bug. Just go ahead and file a bug report to the GCC dudes!