[Bug c++/109387] New: "definition of explicitly-defaulted" error with explicit template instantiation

2023-04-03 Thread vittorio.romeo at outlook dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109387

Bug ID: 109387
   Summary: "definition of explicitly-defaulted" error with
explicit template instantiation
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

Given this code:

template  struct S { S(); };
// extern template struct S;
template  S::S() = default;
template S::S();

GCC fails to compile with this error:

error: definition of explicitly-defaulted 'S< 
>::S() 
   [with  = int]'
3 | template  S::S() = default;
  |   ^~~~

Uncommenting the extern template fixes compilation. Clang compiles the original
code without any issue.

Live example on Compiler Explorer: 
- https://gcc.godbolt.org/z/YoPhvKnxa

Related StackOverflow thread:
- https://stackoverflow.com/questions/75913223

[Bug target/109380] inline member function symbol not exported with explicit template instantiation declaration on MinGW

2023-04-02 Thread vittorio.romeo at outlook dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109380

--- Comment #2 from Vittorio Romeo  ---
Hmm, you might be correct. Seeing that the issue has not been looked at since
2017, are you aware of any workaround besides `-Wl,--export-all-symbols`? 

The issue is preventing me from applying explicit template instantiations in
the SFML codebase for commonly used template types.

[Bug c++/109380] New: inline member function symbol not exported with explicit template instantiation declaration on MinGW

2023-04-02 Thread vittorio.romeo at outlook dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109380

Bug ID: 109380
   Summary: inline member function symbol not exported with
explicit template instantiation declaration on MinGW
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

Created attachment 54801
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54801=edit
Full example (lib.h, lib.cpp, main.cpp, build.sh)

Given the following code:

// 
// lib.h
template 
struct S
{
void f();
void g() { }
};

template  void S::f() { }
extern template struct __declspec(dllexport) S;

// 
// lib.cpp
#include "lib.h"
template struct S;

// 
// main.cpp
#include "lib.h"
int main() { S{}.g(); }


When building with:

g++ -c -o main.o main.cpp && \
g++ -c -o lib.o lib.cpp && \
g++ -shared -o lib.dll lib.o -Wl,--out-implib,liblib.dll.a && \
g++ -o main.exe main.o -L. -llib


This linker error is erroneously produced:

   
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe:
main.o:main.cpp:(.text+0x15): undefined reference to `S::g()'
collect2.exe: error: ld returned 1 exit status


This is likely the same as bug #89088:

 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89088


And probably related to this Clang PR and review:

 https://reviews.llvm.org/D61118


I bumped into this issue today, using GCC version 12.2.0, on MinGW/MSYS2. 
The last bug report is UNCONFIRMED since 2019.

[Bug c++/89088] Dllexport for explicit template instantiation missing inline methods

2023-04-02 Thread vittorio.romeo at outlook dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89088

Vittorio Romeo  changed:

   What|Removed |Added

 CC||vittorio.romeo at outlook dot 
com

--- Comment #2 from Vittorio Romeo  ---
Bumped into this issue today. I confirm that it is still present on gcc version
12.2.0, on MSYS2.

Any workaround that does not require exporting all symbols via
'-Wl,--export-all-symbols'?

[Bug c++/107105] New: Consider folding `__and_`, `__or_`, and `__not_` at the front-end level

2022-09-30 Thread vittorio.romeo at outlook dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107105

Bug ID: 107105
   Summary: Consider folding `__and_`, `__or_`, and `__not_` at
the front-end level
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

This is another possible compilation speed improvement that came to mind after
running ClangBuildAnalyzer on a few open source projects (gzdoom, SFML, some of
my own, ...) and noticing results like these:

 Template sets that took longest to instantiate:
35407 ms: std::__and_<$> (20262 times, avg 1 ms)
17745 ms: std::unique_ptr<$> (916 times, avg 19 ms)
14302 ms: std::__uniq_ptr_data<$> (916 times, avg 15 ms)
14153 ms: std::__uniq_ptr_impl<$> (916 times, avg 15 ms)
13537 ms: std::__or_<$> (15100 times, avg 0 ms)
13046 ms: std::basic_string<$> (2248 times, avg 5 ms)
11706 ms: std::_Hashtable<$> (1051 times, avg 11 ms)
10527 ms: std::unordered_map<$> (545 times, avg 19 ms)
10379 ms: std::is_convertible<$> (11737 times, avg 0 ms)

It looks like `__and_`, `__or_`, and `__not_` are widely used throughout
libstdc++'s implementation, and are used to implement most type traits. 

I was wondering whether it would be possible and somewhat easy to fold these in
the front-end, similarly to what has been done for `std::move` and similar
functions. Another option is to use a compiler intrinsic.

I have not done any research, but I suppose that if this is possible, reducing
the number of instantiations of these small helpers would benefit pretty much
every project using libstdc++. Just an idea -- feel free to close this ticket
if this is not possible or not worth the effort.

[Bug c++/100157] Support `__type_pack_element` like Clang

2022-06-30 Thread vittorio.romeo at outlook dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100157

--- Comment #9 from Vittorio Romeo  ---
(In reply to Jonathan Wakely from comment #8)
> (In reply to Vittorio Romeo from comment #6)
> > worthwhile to keep the same name as Clang for compatibility,
> 
> No, that's not an option. Clang's is a built-in template, GCC's can't be (it
> would require considerable internal reworking to support that).
> 
> That's also why we have __integer_pack(N)... instead of __make_integer_seq<>.
> 
> Since GCC's built-in has to use different syntax, it would be a disaster to
> use the same name.
> 
> #if __has_builtin(__type_pack_element)
> // now what? is it a template or a function?
> #endif

Got it, I didn't realize that they had to be wildly different. I guess that as
long as a library developer can wrap either under a portable macro, it should
be fine.

[Bug c++/100157] Support `__type_pack_element` like Clang

2022-06-30 Thread vittorio.romeo at outlook dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100157

--- Comment #6 from Vittorio Romeo  ---
Thank you, Jonathan, for looking into this. I feel like it might be worthwhile
to keep the same name as Clang for compatibility, or maybe talk to some Clang
developers and see if there can be an agreement on naming and design that works
for both compilers -- would be nice to have something that works for both GCC
and Clang in the same way.

[Bug c++/96780] debuginfo for std::move and std::forward isn't useful

2022-03-01 Thread vittorio.romeo at outlook dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96780

--- Comment #7 from Vittorio Romeo  ---
> As discussed on IRC, we might not want to do this folding at -O0 (although 
> I'd personally be happy with it unconditionally).

I think you should reconsider this as discussed in these places:
- https://github.com/llvm/llvm-project/issues/53689
- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104719

Compiling in `-O0` is a valid choice when trying to maximize compilation speed
and debuggability, yet pretty much everyone seems to agree that they'd like to
never see `std::move`/`std::forward` in their debugger nor have them introduce
any performance overhead, even in `-O0`.

I would also suggest, as an extension, to consider a more general approach for
other standard library functions. As an example, there are good gains to be
made in terms of debug performance for things like `std::unique_ptr` (see
https://github.com/llvm/llvm-project/issues/53689#issuecomment-1055669228) or
`std::vector::iterator`.

[Bug libstdc++/104719] Use of `std::move` in libstdc++ leads to worsened debug performance

2022-02-28 Thread vittorio.romeo at outlook dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104719

--- Comment #9 from Vittorio Romeo  ---
I have done some benchmarking for three use cases, both with `-O0` and `-Og`,
hacking my `libstdc++` headers to add `[[gnu::always_inline]]` where deemed
appropriate. 

---

The use cases were:

1. `operator[]` benchmark -- `vector_squareop` and `carray_squareop` as seen
above

2. Iterator benchmark -- `vector_iter` and `carray_iter` as seen above

3. Algorithm benchmark -- `std::accumulate` versus a raw `for` loop

---

All the benchmark results, benchmarking rig specs, and used code available
here:
https://gist.github.com/vittorioromeo/efa005d44ccd4ec7279181768a0c1f0b

---

In short, these are the results:

- For all benchmarks, when using `-O0` without any modification to `libstdc++`,
the overhead of the Standard Library can be huge (+25-400%).

- For all benchmarks, when using `-Og` without any modification to `libstdc++`,
the overhead of the Standard Library is small (+5-15%).

- For the `operator[]` benchmark, when using `-O0` after applying
`[[gnu::always_inline]]` to all the functions touched by the benchmark, we
reduce the overhead from 25% to around 10%.

- For the `operator[]` benchmark, when using `-Og` after applying
`[[gnu::always_inline]]` to all the functions touched by the benchmark, we
reduce the overhead from 34% to around 11%. 

- For the iterator benchmark, when using `-O0` after applying
`[[gnu::always_inline]]` to all the functions touched by the benchmark, we
reduce the overhead from 302% to around 186%. 

- For the iterator benchmark, when using `-Og` after applying
`[[gnu::always_inline]]` to all the functions touched by the benchmark, we
reduce the overhead from 11% to around 8%. 

- For the algorithm benchmark, when using `-O0` after applying
`[[gnu::always_inline]]` to all the functions touched by the benchmark, we
reduce the overhead from 304% to around 47%.

- For the algorithm benchmark, when using `-Og`, independently of whether we
modify `libstdc++` or not, the overhead is around 36%.

[Bug libstdc++/104719] Use of `std::move` in libstdc++ leads to worsened debug performance

2022-02-28 Thread vittorio.romeo at outlook dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104719

--- Comment #6 from Vittorio Romeo  ---
> The request is to replace it with some kind of magic that does the same as 
> std::move without actually writing std::move.

More generally speaking, ensure that function such as `std::move`,
`std::forward`, `std::vector::operator[]`,
`std::vector::iterator::operator*`, and so on never appear in debugging call
stacks and do not affect performance in `-Og` (or even `-O0`. 

I think the title for my issue is a bit too specific, but I'd like to make this
a wider discussion in how to mitigate debug performance overhead caused by C++
standard library abstractions.

[Bug libstdc++/104719] Use of `std::move` in libstdc++ leads to worsened debug performance

2022-02-28 Thread vittorio.romeo at outlook dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104719

--- Comment #4 from Vittorio Romeo  ---
I see that `std::move` is indeed inlined with `-Og`, my apologies on not
noticing that. 

I like the idea of having the compiler itself fold calls to things like
`std::move` and `std::forward` as suggested in the linked
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96780. 

But I think this issue I opened should be more general for any standard library
function that ends up impacting debug performance. Another common example in
the gamedev community is `std::vector`.

In this benchmark, which uses `-Og`, you can notice a large performance
difference between a `std::vector` and `int*` dynamic array for operations
that I believe should have equal performance:
- https://quick-bench.com/q/lrS4I-lmDJ3VFP8L8rG2YHGXO-8
- https://quick-bench.com/q/Uf-t79n7uYWAKdThOL_wxSp12Y0

Are the above results also something that should be handled on the compiler
side of things? Or would, for example, marking `std::vector::operator[]` and
`std::vector::iterator::operator*` as `always_inline` remove the performance
discrepancy?

[Bug libstdc++/104719] New: Use of `std::move` in libstdc++ leads to worsened debug performance

2022-02-28 Thread vittorio.romeo at outlook dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104719

Bug ID: 104719
   Summary: Use of `std::move` in libstdc++ leads to worsened
debug performance
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

`std::accumulate` is defined as follows in `libstdc++`:

```
  template
_GLIBCXX20_CONSTEXPR
inline _Tp
accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
{
  // concept requirements
  __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
  __glibcxx_requires_valid_range(__first, __last);

  for (; __first != __last; ++__first)
__init = _GLIBCXX_MOVE_IF_20(__init) + *__first;
  return __init;
}
```

Where `_GLIBCXX_MOVE_IF_20` is:

```
#if __cplusplus > 201703L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 2055. std::move in std::accumulate and other algorithms
# define _GLIBCXX_MOVE_IF_20(_E) std::move(_E)
#else
# define _GLIBCXX_MOVE_IF_20(_E) _E
#endif
```

When compiling a program using `std::accumulate` in debug mode, under `-Og`,
there is a noticeable performance impact due to the presence of `std::move`.
- With `std::move`: https://quick-bench.com/q/h_M_AUs3pgBE3bYr82rsA1_VtjU
- Without `std::move`: https://quick-bench.com/q/ysis2b1CgIZkRsO2cqfjZm9Jkio

This performance degradation is one example of why many people (especially in
the gamedev community) are not adopting standard library algorithms and modern
C++ more widely. 

Would it be possible to replace `std::move` calls internal to `libstdc++` with
a cast, or some sort of compiler intrinsic? Or maybe mark `std::move` as
"always inline" even without optimizations enabled? 

Related issue for libc++:
https://github.com/llvm/llvm-project/issues/53689

[Bug c++/100157] New: Support `__type_pack_element` like Clang

2021-04-20 Thread vittorio.romeo at outlook dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100157

Bug ID: 100157
   Summary: Support `__type_pack_element` like Clang
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

Clang provides a `__type_pack_element` builtin which allows efficient indexing
of parameter packs in variadic templates, and it seems that GCC has no
equivalent.

This forces users interested in minimizing compilation times to resort to
arcane implemenations such as these ones:
https://github.com/kvasir-io/mpl/blob/development/src/kvasir/mpl/sequence/lookup.hpp

A builtin like `__type_pack_element` would not only allow user code to compile
faster, but also anything inside libstdc++ that needs to index a type list
(e.g. `std::tuple_element_t`) would benefit from it.

This is the Clang test driver, to show an usage example:
https://github.com/llvm-mirror/clang/blob/master/test/SemaCXX/type_pack_element.cpp

This is the Clang pull request:
https://reviews.llvm.org/D15421

[Bug libstdc++/100008] New: std::clamp generates suboptimal assembly for primitive types

2021-04-09 Thread vittorio.romeo at outlook dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=18

Bug ID: 18
   Summary: std::clamp generates suboptimal assembly for primitive
types
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

`std::clamp` generates poor assembly compared to hand-written counterpart for
primitive types like `float`, even with `-Ofast -ffast-math`:

stdclamp(float, float, float):
comiss  xmm0, xmm1
jb  .L2
movaps  xmm1, xmm0
minss   xmm1, xmm2
.L2:
movaps  xmm0, xmm1
ret

myclamp(float, float, float):
maxss   xmm0, xmm1
minss   xmm0, xmm2
ret

Live example:
https://godbolt.org/z/5oxvocevK

More information on:
https://secret.club/2021/04/09/std-clamp.html

[Bug c++/79378] lambda init-capture adds const

2020-07-18 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79378

Vittorio Romeo  changed:

   What|Removed |Added

 CC||vittorio.romeo at outlook dot 
com

--- Comment #2 from Vittorio Romeo  ---
Stumbled upon this again, with this example:

template 
constexpr bool is_same_v = false;

template 
constexpr bool is_same_v = true;

auto l = [k = 0]
{
static_assert(is_same_v);
};

This bug is still not fixed in the latest version of GCC (trunk).

Related StackOverflow post: 
https://stackoverflow.com/questions/62963712/decltype-of-generalized-lambda-capture-inside-body-of-a-lambda-gcc-vs-clang

Example on Compiler Explorer:
https://gcc.godbolt.org/z/jY9cfW

[Bug c++/81676] Wrong warning with unused-but-set-parameter within 'if constexpr'

2019-08-16 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81676

Vittorio Romeo  changed:

   What|Removed |Added

 CC||vittorio.romeo at outlook dot 
com

--- Comment #3 from Vittorio Romeo  ---
Found this today, still present in gcc trunk (9.2+). Example:

int main()
{
auto f = [](auto a, auto b) {
if constexpr (sizeof(b) == 1) {
return a;
} else {
return b;
}
};

return f(1, 1) + f(1, 'a');
}

https://gcc.godbolt.org/z/SOvLEV

[Bug tree-optimization/90571] Missed optimization opportunity when returning function pointers based on run-time boolean

2019-05-23 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90571

--- Comment #4 from Vittorio Romeo  ---
> I wonder how the "original" testcase looked
like - the one in this bug is probably simplified from real-world code?

This is what the original author of the code (Filipp Gelman) said:

> I was reviewing some code that checked configuration. The configuration 
> struct has several functions taking no arguments and returning bool. The 
> value of an enum determined which of these was called.
> I thought that the choice of which member function to call depends only on 
> the enum and not on anything else in the configuration, so I tried splitting 
> selecting the member function from calling it.
> This code looks much closer to what I reviewed: https://godbolt.org/z/L_W_oi
> The author wrote `test1`. I considered suggesting `test2`, but was surprised 
> by it not optimizing to the same code.

[Bug c++/90571] New: Missed optimization opportunity when returning function pointers based on run-time boolean

2019-05-22 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90571

Bug ID: 90571
   Summary: Missed optimization opportunity when returning
function pointers based on run-time boolean
   Product: gcc
   Version: 10.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

Given the following two functions:

int f() { return 0; }
int g() { return 1; }

And the following code to invoke one of them depending on a boolean `b`:

int t0(bool b) { return (b ?  : )(); }
int t1(bool b) { return b ? f() : g(); }
int t2(bool b) { return b ? t0(true) : t0(false); }

Both `g++ (trunk)` and `clang++ (trunk)` with `-std=c++2a -Ofast -march=native`
fail to optimize the following code:

int main(int ac, char**) { return t0(ac & 1); }

Producing the following assembly:

> main:
>   and edi, 1
>   mov eax, OFFSET FLAT:f()
>   mov edx, OFFSET FLAT:g()
>   cmove rax, rdx
>   jmp rax
> 

Invoking `t1` or `t2` (instead of `t0`) produces the following optimized
assembly:

> main:
> mov eax, edi
> not eax
> and eax, 1
> ret

Everything can be reproduced live on **gcc.godbolt.org**:
https://godbolt.org/z/gh7270

[Bug c++/90215] [8/9 Regression] ICE with lambda in fold expression over comma and assignment

2019-04-24 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90215

--- Comment #4 from Vittorio Romeo  ---
Simplified quite a lot, removed `` dependency:
https://gcc.godbolt.org/z/6uNcCN

struct X
{
template 
void f(F f)
{
f(0);
}
};

template 
void bug(Xs... xs)
{
int i;

[&](auto&... ys)
{   
(xs.f([&](auto)
{
ys;
}), ...);
}(i);
}

int main()
{
bug(X{});
}

[Bug c++/90215] [8/9 Regression] ICE with lambda in fold expression over comma and assignment

2019-04-24 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90215

--- Comment #3 from Vittorio Romeo  ---
Changing the lambda to the following

std::apply([](auto&... ys)
{   
(xs.f([](auto y)
{
ys = y;
}), ...);
}, t);

produces a different ICE:

:20:9: internal compiler error: Segmentation fault
 20 | (xs.f([](auto y)
| ^

https://gcc.godbolt.org/z/hp2hMN

[Bug c++/90215] New: ICE with lambda in fold expression over comma and assignment

2019-04-23 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90215

Bug ID: 90215
   Summary: ICE with lambda in fold expression over comma and
assignment
   Product: gcc
   Version: 9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

The following code

#include 

template 
struct X
{
template 
void f(F f)
{
f(0);
}
};

template 
void bug(X... xs)
{
std::tuple t;

std::apply([&](auto&... ys)
{   
(xs.f([&](auto y)
{
ys = y;
}), ...);
}, t);
}

int main()
{
bug(X{});
} 

produces an ICE with g++ trunk (version 9.0.1 20190422):

:22:16: internal compiler error: in tsubst_copy, at cp/pt.c:15551
 22 | ys = y;
| ~~~^~~

The bug can be reproduced on godbolt.org here:
https://gcc.godbolt.org/z/NNLI5p

[Bug c++/89687] New: Empty pack expansion in `decltype` results in cryptic compiler error (dump_expr)

2019-03-12 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89687

Bug ID: 89687
   Summary: Empty pack expansion in `decltype` results in cryptic
compiler error (dump_expr)
   Product: gcc
   Version: 9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

Consider the following code:

template 
void foo(F f) 
{
[f](auto... xs) 
{
[xs...]() -> decltype(f(xs...)) { };
};
}

int main()
{
foo([]{ });
}

Live example on godbolt.org:
https://gcc.godbolt.org/z/DTC3f6

It compiles under clang++ trunk, but fails to compile under g++ trunk (9.0.1
20190311) with the following error:

: In instantiation of 'void foo(F) [with F = main()::]':
:12:14:   required from here
:6:32: error: expansion pattern '#'nontype_argument_pack' not
supported by dump_expr#' contains no parameter packs
6 | [xs...]() -> decltype(f(xs...)) { };
|   ~^~~
Compiler returned: 1

[Bug c++/88557] Lambda in template parameter list compiler segmentation fault (ICE)

2018-12-20 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88557

--- Comment #1 from Vittorio Romeo  ---
The "ice-on-invalid-code" tag was added, but I thought this was valid C++2a
code. Am I mistaken?

[Bug c++/88557] New: Lambda in template parameter list compiler segmentation fault (ICE)

2018-12-19 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88557

Bug ID: 88557
   Summary: Lambda in template parameter list compiler
segmentation fault (ICE)
   Product: gcc
   Version: 9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

The following code

template
void f() { }

causes an internal compiler error on gcc 9.x version 20181218:

: In lambda function:
:1:31: error: invalid use of 'auto'
1 | template
  |   ^
:1:31: error: could not convert '0' from 'int' to 'auto'
: At global scope:
:1:20: error: use of '' before deduction of 'auto'
1 | template
  |^~~
: In static member function 'static auto::_FUN()':
:1:20: error: invalid use of 'auto'
: At global scope:
:1:36: internal compiler error: Segmentation fault
1 | template
  |^

Live example on godbolt.org:
https://gcc.godbolt.org/z/zSKWsv

---

Similarly, the following code

template(){ return 0; }.operator()()>
void f() { }

produces another ICE:

: In member function '::operator decltype
(((const*)((const* const)0))->operator()()) (*)()() const':
:1:20: internal compiler error: in type_dependent_expression_p, at
cp/pt.c:25602
1 | template(){ return 0; }.operator()()>
  |

Live example on godbolt.org:
https://gcc.godbolt.org/z/uOfYy5

[Bug libstdc++/85771] New: `std::variant<...>` insanely slow to compile compared to `union` (256 types)

2018-05-14 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85771

Bug ID: 85771
   Summary: `std::variant<...>` insanely slow to compile compared
to `union` (256 types)
   Product: gcc
   Version: 8.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

Consider the following set of types:

struct Type0 { int x; };
struct Type1 { int x; };
struct Type2 { int x; };
// ...
struct Type253 { int x; };
struct Type254 { int x; };
struct Type255 { int x; };

Now imagine creating both a `std::variant` and a `union` out of them, then
compiling some code that prints out the active alternative with `-O3`:

union MyVariant { Type0 type0; /* ... */; Type255 type255; };
std::variant<Type0, /* ... */, Type255> v;

These are the *compilation time* results I get:

UNION
real0m0.182s
user0m0.104s
sys 0m0.068s

VARIANT
real0m2.259s
user0m1.960s
sys 0m0.280s

I can get similar results on widely different machines (40 core company
development box, my laptop, and an online compiler).

Fully-reproducible live demo on coliru:
http://coliru.stacked-crooked.com/a/65d2ec5f4d7eb1ca

I think that this kind of difference is unacceptable, and `std::variant` types
with a lot of alternatives can occur in realistic use cases. If we want to
promote safety and abstraction over C-style code, the compilation time costs
must be sane.

[Bug c++/47226] [C++0x] GCC doesn't expand template parameter pack that appears in a lambda-expression

2018-04-09 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226

--- Comment #19 from Vittorio Romeo  ---
(In reply to Jonathan Wakely from comment #18)
> (In reply to Vittorio Romeo from comment #17)
> > Was the patch merged in trunk?
> 
> It was committed to trunk: r251433
> 
> > The following still fails to compile on 20180407
> 
> Could you create a new bug for that please?

Created
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85305

[Bug c++/85305] New: Parameter pack expression in lambda capture list fails as part of a fold expression

2018-04-09 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85305

Bug ID: 85305
   Summary: Parameter pack expression in lambda capture list fails
as part of a fold expression
   Product: gcc
   Version: 8.0.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

The following code snippet...

template 
void foo()
{
([i = Is]{}(), ...); 
}

...does not compile on gcc trunk 20180408 with the following error:

: In function 'void foo()':
:4:11: error: parameter packs not expanded with '...':
 ([i = Is]{}(), ...);
   ^~

:4:11: note: 'Is'
:4:16: error: operand of fold expression has no unexpanded
parameter packs
 ([i = Is]{}(), ...);
  ~~^~

Live example on godbolt.org:
https://godbolt.org/g/YBk6L6

[Bug c++/47226] [C++0x] GCC doesn't expand template parameter pack that appears in a lambda-expression

2018-04-08 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226

--- Comment #17 from Vittorio Romeo  ---
Was the patch merged in trunk?
The following still fails to compile on 20180407

template 
int foo()
{
([i = Is]{}(), ...); 
return 0;
}

[Bug c++/84916] Tweaks to template type elision

2018-03-16 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84916

Vittorio Romeo  changed:

   What|Removed |Added

 CC||vittorio.romeo at outlook dot 
com

--- Comment #2 from Vittorio Romeo  ---
This might be of interest as well:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71167

[Bug c++/81486] Class template argument deduction fails with (), succeeds with {}

2017-11-11 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81486

--- Comment #2 from Vittorio Romeo  ---
Here's a snippet that seems to reproduce this bug, even without an explicit
deduction guide:

template 
struct foo
{
template 
foo(Us...) { }
};

int main()
{
auto f = foo();
}

On godbolt:
https://godbolt.org/g/CgqLq5

[Bug c++/80871] Template partial ordering considered non-ambiguous with deduced and non-deduced parameter packs

2017-11-11 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80871

Vittorio Romeo  changed:

   What|Removed |Added

 CC||vittorio.romeo at outlook dot 
com

--- Comment #1 from Vittorio Romeo  ---
Got hit again today, while trying to write an `overload(...)` class:

template 
struct overload : Ts...
{
template 
constexpr overload(TFwds&&... xs) 
: Ts{FWD(xs)}...
{
}

using Ts::operator()...;
};

template 
overload(TFwds&&...) -> overload<std::decay_t...>;

With the code above

auto o = overload{[]{}};

fails to compile. See: https://godbolt.org/g/Rb3ZKt

[Bug c++/52869] [DR 1207] "this" not being allowed in noexcept clauses

2017-09-16 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52869

Vittorio Romeo  changed:

   What|Removed |Added

 CC||vittorio.romeo at outlook dot 
com

--- Comment #3 from Vittorio Romeo  ---
Any news on this? It is making writing noexcept specifications very hard since
2012...

[Bug c++/79180] Nested lambda-capture causes segfault for parameter pack

2017-07-15 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79180

Vittorio Romeo  changed:

   What|Removed |Added

 CC||vittorio.romeo at outlook dot 
com

--- Comment #4 from Vittorio Romeo  ---
Experienced this bug today. Another example + information available here:
https://stackoverflow.com/questions/45117719

Possibly related:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71386

[Bug c++/79590] ICE (internal compiler error) in nothrow_spec_p with generic lambda and `noexcept(noexcept(...))` expression

2017-04-12 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79590

--- Comment #2 from Vittorio Romeo  ---
This is still present. Here are some more examples:



int main()
{
[](auto x) noexcept(noexcept(x)) { } (0);
}

:3:40: internal compiler error: in nothrow_spec_p, at cp/except.c:1159
 [](auto x) noexcept(noexcept(x)) { } (0);
^



int main()
{
[](auto) noexcept(noexcept(0)) { } (0);
}

: In function 'int main()':
:3:38: internal compiler error: in nothrow_spec_p, at cp/except.c:1159
 [](auto) noexcept(noexcept(0)) { } (0);
  ^

[Bug c++/80370] [7 Regression] ICE when using structured bindings and nested generic lambdas (tsubst_decomp_names)

2017-04-10 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80370

--- Comment #4 from Vittorio Romeo  ---
Even shorter:


template  struct tuple_size { static constexpr int value = 1; };
template  struct tuple_element { typedef int type; };
template  struct tuple {};
template  int get(T);

int
main ()
{
  [](auto) { [](tuple b) { auto [c] = b; }; }(0);
}

[Bug c++/64488] [c++11] Expand initializer list with lambdas in variadic template. Reject valid code.

2017-02-20 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64488

Vittorio Romeo  changed:

   What|Removed |Added

 CC||vittorio.romeo at outlook dot 
com

--- Comment #3 from Vittorio Romeo  ---
Further simplification:

template 
void foo() 
{
using arr = int(*[])();
(void) arr{[]{ return Is; }...};
}

int main() { foo<1,2,3>(); }



* clang++ 3.3 (up to 5.0) happily compiles the code with -std=c++11.

* g++ 4.7 (up to 7.0) fails to compile with -std=c++11 (or c++14/c++1z)

[Bug c++/71332] New: Passing non-copyable type by reference to variadic generic lambda after a copyable type by value results in a compile-time error

2016-05-29 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71332

Bug ID: 71332
   Summary: Passing non-copyable type by reference to variadic
generic lambda after a copyable type by value results
in a compile-time error
   Product: gcc
   Version: 6.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

Created attachment 38592
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=38592=edit
Minimal code example

* Example on gcc.godbolt.org:
https://godbolt.org/g/HxMq0K

* Related StackOverflow question:
http://stackoverflow.com/questions/37508217

---

I've encountered a situation where passing a non-copyable type (by reference)
to a variadic generic lambda after a copyable type (by copy) causes a
compilation error on `g++` (both on `5.3` and `6.1`) but not on `clang++`.

int main()
{
auto f = [](auto&&...)
{
};

non_copyable nc;

f(nc); // ok on both compilers
f(nc, int{}); // ok on both compilers
f(int{}, nc); // error only on gcc 
} 

`g++` gives the following error for the `f(int{}, nc)` call: 

x.cpp: In function ‘void test()’:
x.cpp:19:19: error: use of deleted function
‘non_copyable::non_copyable(const non_copyable&)’
 f(int{}, nc);
^
x.cpp:8:5: note: declared here
 non_copyable(const non_copyable&) = delete;
 ^~~~

It seems that if the first argument is passed by copy, all the other arguments
are passed by copy as well. This looks like a bug, because using an
hand-written callable object that should be equivalent to the lambda works on
both compilers:

// should be equivalent to `[](auto&&...){ }`
struct do_nothing
{
template 
constexpr auto operator()(Ts&&...) const noexcept
{
}
};

// ...

do_nothing{}(nc); // ok on both compilers
do_nothing{}(nc, int{}); // ok on both compilers
do_nothing{}(int{}, nc); // ok on both compilers

There seems to be an inconsistency between callable objects and generic
variadic lambdas on `g++`.

[Bug c++/71167] New: Long typenames produce extremely hard to read diagnostics and slow down compilation time

2016-05-17 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71167

Bug ID: 71167
   Summary: Long typenames produce extremely hard to read
diagnostics and slow down compilation time
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

Long typenames, usually generated by heavy template metaprogramming code,
result in errors that are extremely hard to read and parse. Furthermore, they
slow down compilation time significantly.

Here's a benchmark and example from the boost::di project:
http://melpon.org/wandbox/permlink/7Fh0u2oaQbDmkNV0

The benchmark shows:
* How unnecessarily long and hard-to-understand errors are.
* How typename erasure techniques can improve compilation times (define
TYPENAME_ERASURE to see compilation time improvements).

I've encountered this same issue in one of my projects (ECST) - errors were
impossible to understand before GCC 6 was released. GCC 6's produced errors
pinpoint the issue more accurately, but still produce an enormous amount of
unnecessary output.

I think this is primarily a defect in error reporting. A flag to control long
typename output would be desired and possibly necessary for projects that
require the generation of long typenames.

I also think that having compilation times speed up when erasing typenames
signals some sort of potential compilation optimization for long typenames.

P.S.: clang has similar issues.

Links:
boost::di -> https://github.com/boost-experimental/di
ECST -> https://github.com/SuperV1234/ecst

[Bug c++/70942] New: [c++14] Incorrect deduction of generic lambda `auto&&` parameter

2016-05-04 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70942

Bug ID: 70942
   Summary: [c++14] Incorrect deduction of generic lambda `auto&&`
parameter
   Product: gcc
   Version: 6.1.0
Status: UNCONFIRMED
  Severity: critical
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

Created attachment 38410
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=38410=edit
Minimal code example

g++ 6.1 was recently introduced into Arch Linux's testing repositories, and
some of my code that successfully compiled with g++ 5.3.0 does not compile
anymore. I've made a minimal example:

gcc.godbolt.org link: 
https://godbolt.org/g/73RTHf


// This code compiles with g++ 5.3.0
// This does not compile with g++ 6.1

#include 
#include 
#include 

#define FWD(...) ::std::forward<decltype(__VA_ARGS__)>(__VA_ARGS__)

struct sinker
{
template 
void sink(T&)
{
}
};

template 
void caller(T& v, TF&& f)
{
sinker s;
f(s, v);
}

template 
void interface(T& v)
{
return caller(v, [](auto& xs, auto&& xv) -> decltype(auto)
{
xs.sink(FWD(xv));
});
}

int main()
{
int x = 0;
interface(x);
}

This is the reported error:

: In instantiation of ‘get_impl(T&)::<lambda(auto:1&, auto:2&&)> [with
auto:1 = sinker; auto:2 = int; T = int]’:
:25:58:   required by substitution of ‘template
get_impl(T&)
  [with T = int]::<lambda(auto:1&, auto:2&&)>::operator 
  decltype (((get_impl(T&) [with T = int]::<lambda(auto:1&,
auto:2&&)>)0u).operator()(static_cast<auto:1&>(),
   static_cast<auto:2&&>())) (*)(auto:1&, auto:2&&)() const
[with auto:1 = sinker; auto:2 = int]’
:19:6:   required from ‘void chunk_fn_impl(T&, TF&&) [with T = int; TF =
get_impl(T&) [with T = int]::<lambda(auto:1&, auto:2&&)>]’
:25:25:   required from ‘void get_impl(T&) [with T = int]’
:36:15:   required from here
:27:13: error: invalid initialization of non-const reference of type ‘int&’
from an rvalue of type ‘int’
 xs.sink(FWD(md));
 ^~
:10:10: note:   initializing argument 1 of ‘void sinker::sink(T&) [with T =
int]’
 void sink(T&)
  ^~~~

---

Changing:

return caller(v, [](auto& xs, auto&& xv) -> decltype(auto)

to:

return caller(v, [](auto& xs, auto& xv) -> decltype(auto)

allows the code to successfully compile.

---

I do not understand why this error is happening, as `xv` is being
perfectly-forwarded and the `FWD(xv)` call should produce a lvalue reference.
Note that the code worked as intended in g++ 5.3.0 and clang++ 3.7.

gcc.godbolt.org link: 
https://godbolt.org/g/73RTHf

Try compiling with multiple g++ versions and changing `auto&&` to `auto&`.

Is this a g++ 6.1 bug? Or was the code incorrectly compiling with previous
versions of g++ and clang++?

---

More information:
http://stackoverflow.com/questions/37023265

[Bug c++/70631] New: Warn about redundant comparisons with -Wlogical-op

2016-04-11 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70631

Bug ID: 70631
   Summary: Warn about redundant comparisons with -Wlogical-op
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: enhancement
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

https://godbolt.org/g/Tt8hfe

int main()
{
int x = 0;

// warning: logical 'or' of collectively exhaustive tests is always true
[-Wlogical-op]
if(x != 5 || x != 6) { } 

// warning: logical 'and' of mutually exclusive tests is always false
[-Wlogical-op]
if(x == 5 && x == 6) { } 

// no warnings
if(true || x == 10) { }
if(false && x == 10) { }

// no warnings
if(x == 5 || x != 6) { } // x==5 is redundant
if(x == 5 && x != 6) { } // x!=6 is redundant
}

I think gcc should warn about the redundant comparisons with -Wlogical-op.

More information:
https://www.reddit.com/r/cpp/comments/4e9kf1/logical_expressions_in_cc_mistakes_made_by/

[Bug c++/69066] New: SFINAE compilation error on lambda with trailing return type

2015-12-27 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69066

Bug ID: 69066
   Summary: SFINAE compilation error on lambda with trailing
return type
   Product: gcc
   Version: 5.3.0
Status: UNCONFIRMED
  Severity: major
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

auto bound_f = [=](auto... xs) -> decltype(f(x, xs...))
{
return f(x, xs...);
};

return curry_impl<decltype(bound_f),
is_zero_callable<decltype(bound_f)>{}>::exec(bound_f);

---

`is_zero_callable` is a type-trait like struct making use of `void_t` detection
techniques.

clang++ compiles the code correctly and triggers SFINAE thanks to `bound_f`'s
explicit trailing return type.

g++ fails to compile the code (see godbolt example).

---

Example on gcc.godbolt.org: https://goo.gl/2hWTTN
Additional information: http://stackoverflow.com/a/34484150/598696

[Bug c++/69057] constexpr static variable template assertion segmentation fault

2015-12-26 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69057

--- Comment #1 from Vittorio Romeo  ---
> in constexpr expansion of ‘from_enum(array)’
> internal compiler error: Segmentation fault
  static constexpr GLenum target_value{from_enum(buffer_target::array)};

[Bug c++/69057] New: constexpr static variable template assertion segmentation fault

2015-12-26 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69057

Bug ID: 69057
   Summary: constexpr static variable template assertion
segmentation fault
   Product: gcc
   Version: 5.3.0
Status: UNCONFIRMED
  Severity: critical
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

gcc.godbolt.org example: https://goo.gl/yGCVOB

---

#include 

using GLenum = unsigned int;

template 
inline constexpr auto from_enum(const T& x) noexcept
{
// Comment this line to prevent segmentation fault:
assert(true);
// 

return (GLenum)x;
}

enum class buffer_target : GLenum
{
array
};

struct vbo
{
static constexpr GLenum target_value{from_enum(buffer_target::array)};
GLenum x{target_value};
};

int main()
{
return 0;
}

[Bug c++/68965] New: `-Wunused-parameter` is reported in variadic lambda or function using sizeof...(xs)

2015-12-17 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68965

Bug ID: 68965
   Summary: `-Wunused-parameter` is reported in variadic lambda or
function using sizeof...(xs)
   Product: gcc
   Version: 5.3.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

gcc.godbolt.org: https://goo.gl/oJf4gs

auto count = [](auto&&... xs)
{
return sizeof...(xs);
};

struct count_struct
{
template
auto operator()(Ts&&... xs)
{
return sizeof...(xs);
}
};

int main()
{
count(1,2,3,4,5,6,7);
count_struct{}(1,2,3,4,5,6,7);
}

Compile with `-Wunused-parameter -std=c++14`.

g++ 5.1.0 will produce no warnings.
g++ 5.2.0 will produce no warnings.
g++ 5.3.0 will produce warnings for both `count` and `count_struct`.

The warnings seem erroneous, as `xs` is being used inside `sizeof...`.

[Bug c++/68876] New: Segmentation fault with variadic templates, std::forward and decltype

2015-12-12 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68876

Bug ID: 68876
   Summary: Segmentation fault with variadic templates,
std::forward and decltype
   Product: gcc
   Version: 5.3.0
Status: UNCONFIRMED
  Severity: critical
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

Not sure what's causing the segmentation fault, but here's a minimal example.
The segfault happens with g++ 5.1, 5.2 and 5.3.

gcc.godbolt.org link: https://goo.gl/eQhvm4



#include 

struct static_for_result
{
template 
constexpr decltype(auto) operator()(Ts&&... xs)
{
auto fn_call = [this, ]()
{
return ([](auto&&...)
{
})(std::forward<decltype(xs)>(xs)...);
};

return int{};
}
};

template 
constexpr decltype(auto) static_for(TF&&)
{
return static_for_result{};
}

int main()
{
auto empty_for = static_for([&](auto, auto)
{
})(0);

return 0;
}

[Bug c++/68071] New: Generic lambda variadic argument pack cannot be empty

2015-10-23 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68071

Bug ID: 68071
   Summary: Generic lambda variadic argument pack cannot be empty
   Product: gcc
   Version: 5.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

struct C
{
template
auto operator()(T&& x, TRest&&...){ return x; }
};

int main()
{
// Compiles both with clang and gcc.
auto c = C{};
c(1);

// Compiles with clang 3.7.
// Does not compile with gcc 5.2.
auto l = [](auto&& x, auto&&...) { return x; };
l(1);
}

decltype(l)::operator() should be equivalent to C::operator(), but if variadic
pack is left empty in the generic lambda, gcc refuses to compile:

15 : error: no match for call to '(main()::) (int)' l(1);
15 : note: candidate: decltype (((main()::)0u).main()::(x, )) (*)(auto:1&&,
auto:2&&, ...)

15 : note: candidate expects 3 arguments, 2 provided
14 : note: candidate: template main()::
auto l = [](auto&& x, auto&&...) { return x; };

14 : note: template argument deduction/substitution failed:
15 : note: candidate expects 2 arguments, 1 provided
l(1);

Live example on godbolt.org:
https://goo.gl/2ikAUK


[Bug c++/67274] Inconsistent `this-` required when calling member function in a lambda capturing `this` through another function

2015-08-19 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67274

--- Comment #1 from Vittorio Romeo vittorio.romeo at outlook dot com ---
More test cases, using minor variations to the code posted above:

With bar() = call([this](auto x){ foo(x); });
clang++ 3.6+ compiles.
g++ 5.2+ does not compile.

With bar() = call([this](auto x){ this-foo(x); });
clang++ 3.6+ compiles.
g++ 5.2+ compiles.

With bar() = call([this](int x){ foo(x); });
clang++ 3.6+ compiles.
g++ 5.2+ compiles.

With bar() = [this](auto x){ foo(x); }(1);
clang++ 3.6+ compiles.
g++ 5.2+ compiles.


[Bug c++/67274] New: Inconsistent `this-` required when calling member function in a lambda capturing `this` through another function

2015-08-19 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67274

Bug ID: 67274
   Summary: Inconsistent `this-` required when calling member
function in a lambda capturing `this` through another
function
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

Passing a `this`-capturing generic lambda (to a template function) that calls a
member function of `this` without an explicit `this-` results in an error:

error: cannot call member function 'void Example::foo(int)' without object 
 call([this](auto x){ foo(x); });`

If the lambda is not generic, or if the lambda is not passed to any other
function but called in place, it compiles without an explicit `this-`. 

For reference, clang 3.6+ is cool with the code in all situations.

---

Minimal example:
http://melpon.org/wandbox/permlink/M2eH3FUOentPfieM

templatetypename TF
void call(TF f)
{
f(1);   
}

struct Example
{
void foo(int){ }

void bar()
{
call([this](auto x){ foo(x); });
}
};

int main()
{
Example{}.bar();
return 0;
}

---

StackOverflow question with more examples:
http://stackoverflow.com/questions/32097759


[Bug c++/67273] New: Incorrect -Wshadow warning with generic lambdas

2015-08-19 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67273

Bug ID: 67273
   Summary: Incorrect -Wshadow warning with generic lambdas
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: minor
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com
  Target Milestone: ---

The `-Wshadow` flag fires an incorrect warning using generic lambdas with
`auto` type deduction.

Minimal example:
http://melpon.org/wandbox/permlink/ynGNXTYN8rY40BgY

---

Code (copy-pasted from example):

// `auto i` - incorrect warning
auto autol0()
{
return [](auto i){ std::cout  i; };
}

auto autol1()
{
return [](auto i){ autol0()(i); };
}

// `int i` - no warnings
auto intl0()
{
return [](int i){ std::cout  i; };
}

auto intl1()
{
return [](int i){ intl0()(i); };
}

---

Warning (copy-pasted from example):

prog.cc:5:21: warning: declaration of 'int i' shadows a parameter [-Wshadow]
 return [](auto i){ std::cout  i; };
 ^
prog.cc:10:20: note: shadowed declaration is here
 return [](auto i){ autol0()(i); };
^


[Bug c++/67248] Variable template cannot be used as dependent name

2015-08-17 Thread vittorio.romeo at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67248

Vittorio Romeo vittorio.romeo at outlook dot com changed:

   What|Removed |Added

 CC||vittorio.romeo at outlook dot 
com

--- Comment #1 from Vittorio Romeo vittorio.romeo at outlook dot com ---
Relevant StackOverflow question:
http://stackoverflow.com/questions/32050119/variable-template-in-template-class-unexpected-error-possible-bug


[Bug c++/59329] New: Using `assert(...)` is not allowed in constexpr functions

2013-11-28 Thread vittorio.romeo at outlook dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59329

Bug ID: 59329
   Summary: Using `assert(...)` is not allowed in constexpr
functions
   Product: gcc
   Version: 4.8.2
Status: UNCONFIRMED
  Severity: trivial
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com

inline constexpr int exampleFunction(int min, int max)
{
assert(min = max);
return min + max;
}

The above function fails to compile, because of the `assert(min = max)`. 

g++ reports that a constexpr function may only be composed of a simple return
statement.

clang++ compiles the function successfully.



Is it possible to lift this restriction?


[Bug c++/58130] [C++11] Compilation fails using const decltype(...) getter() const {...}

2013-08-17 Thread vittorio.romeo at outlook dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58130

Vittorio Romeo vittorio.romeo at outlook dot com changed:

   What|Removed |Added

 Status|WAITING |RESOLVED
 Resolution|--- |INVALID

--- Comment #3 from Vittorio Romeo vittorio.romeo at outlook dot com ---
This is not a bug, sorry for reporting it. 
I've ran some tests and it was my fault.


[Bug c++/58130] New: [C++11] Compilation fails using const decltype(...) getter() const {...}

2013-08-11 Thread vittorio.romeo at outlook dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58130

Bug ID: 58130
   Summary: [C++11] Compilation fails using const decltype(...)
getter() const {...}
   Product: gcc
   Version: 4.8.2
Status: UNCONFIRMED
  Severity: major
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vittorio.romeo at outlook dot com

Tested both on Windows 8 x86 and Arch Linux x64.
Compiling with -O3 -Wall -Wextra -pedantic

struct myStruct
{
std::vectorstd::unique_ptrItemBase items;
...

// This compiles with g++ 4.8.2 and clang++ 3.4
inline const std::vectorstd::unique_ptrItemBase getItems() const{
return category-getItems(); }

// This DOES NOT compile with g++ 4.8.2, but compiles with clang++ 3.4
inline const decltype(items) getItems() const{ return
category-getItems(); }

}


[Bug c++/58130] [C++11] Compilation fails using const decltype(...) getter() const {...}

2013-08-11 Thread vittorio.romeo at outlook dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58130

--- Comment #1 from Vittorio Romeo vittorio.romeo at outlook dot com ---
Isn't 

decltype(items)

equivalent to

   std::vectorstd::unique_ptrItemBase

?