Template Argument Deduction Broken in Clang 6 for Temporary Objects - c++

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.

Related

GCC and Clang differ in static_assert related to __builtin_constant_p

I happen to find that GCC and Clang differ in the compilation of the following code:
struct Foo
{
int mem = 42;
};
int main()
{
constexpr Foo foo;
static_assert(__builtin_constant_p(foo));
return 0;
}
I compile with g++ -std=c++17 and clang++ -std=c++17.
In particular,
g++ g++-9 (Homebrew GCC 9.3.0_1) 9.3.0 compiles, whereas
clang++ Apple clang version 11.0.3 (clang-1103.0.32.62) fails to compile, complaining that
error: static_assert failed due to requirement '__builtin_constant_p(foo)'
static_assert(__builtin_constant_p(foo));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~
I didn't find any hint that there should be any difference regarding __builtin_constant_p.
For __builtin_constant_p
GCC says
You can use the built-in function __builtin_constant_p to determine if a value is known to be constant at compile time ...
Clang
says
Clang supports a number of builtin library functions with the same syntax as GCC, including things like __builtin_nan, __builtin_constant_p, __builtin_choose_expr, __builtin_types_compatible_p, __builtin_assume_aligned, __sync_fetch_and_add, etc.
Question: While I know __builtin_constant_p is a compiler extension, which one should be the correct one?
Both are poorly documented so I doubt there is a proper answer to your question.
If you need a workaround: it seems that clang gives up if the argument is not an int.
So this works:
struct Foo
{
int mem = 42;
};
int main()
{
constexpr Foo foo;
static_assert(__builtin_constant_p(foo.mem));
return 0;
}

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.

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

Clang: Template deduction failed 'double' vs '<double>'

Consider the following code, which uses a function with variable arguments:
#include <iostream>
// Typedef function type
template<typename... Output>
using Func = void(Output*...);
// Function runner
template<typename... Output>
void run_func(Func<Output...>& func, Output*... output) {
for (int i=0 ; i < 10 ; ++i) {
func(output...);
}
}
void f(double* d) {
*d *= 2;
};
int main() {
double value = 1.0;
run_func(f, &value);
printf("%f\n", value);
}
Compiling this with g++ 4.7.3 works fine, and running produces 1024.0 as expected.
Compiling using icpc 14.0.2 crashes it...
templ.cc(21): internal error: assertion failed: lower_expr: bad kind (shared/cfe/edgcpfe/lower_il.c, line 18582)
run_func(f, &value);
^
Compiling with clang 3.5.0-1 gives the following error message:
templ.cc:21:3: error: no matching function for call to 'run_func'
run_func(f, &value);
^~~~~~~~
templ.cc:9:6: note: candidate template ignored: deduced conflicting types for parameter 'Output' ('double' vs. <double>)
void run_func(Func<Output...>& func, Output*... output) {
^
Is this a bug, or should have g++ not compiled this?
Why is clang deducing these "conflicting" types of double and <double>, is <double> meant to represent an unpacked arglist for example?
Update icpc 14.0.3 does not crash, and the program compiles and runs correctly.
See DPD200244439 at Intel® Composer XE 2013 SP1 Compilers Fixes List
Following the above discussion, it seems that this is indeed a bug in clang.
As pointed out by gha.st, skipping template using and using the native function type directly works:
void run_func(void (&func)(Output*...), Output*... output) {
I have a filed a bug against this here.