[Bug c++/89085] New: call of overload is ambiguous with parameter packs

2019-01-28 Thread lumosimann at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89085

Bug ID: 89085
   Summary: call of overload is ambiguous with parameter packs
   Product: gcc
   Version: 9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lumosimann at gmail dot com
  Target Milestone: ---

The following example behaves differently for GCC and Clang and I am almost
sure that Clang is right, because the second overload is clearly more
specialized:

template 
int a(T const&, Args&&...) {
return 0;
}

template 
int a(int const&, Args&&...) {
return 1;
}

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

See https://godbolt.org/z/7eRGmW

Note that the issue requires that

1. parts of the function template needs to be specialized when calling
(removing the first template parameter resolved the problem)

2. it requires a parameter pack


Just some further notes:

- When I add another Arg to the first overload (see
https://godbolt.org/z/AF7TeC), gcc compiles and chooses the first overload, and
clang rejects, and again I think that clang is right
- One way how we can do a workaround: https://godbolt.org/z/WmKdL5

[Bug c++/84162] New: Internal compiler error: in tsubst, at cp/pt.c:13617 / SEGFAULT

2018-02-01 Thread lumosimann at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84162

Bug ID: 84162
   Summary: Internal compiler error: in tsubst, at cp/pt.c:13617 /
SEGFAULT
   Product: gcc
   Version: 7.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lumosimann at gmail dot com
  Target Milestone: ---

Created attachment 43316
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43316&action=edit
Segfault with flag -DV1

## Summary

Template instantiation leads to internal compile error or segfault.

## GCC version

Initially observed on GCC 7.2.1, but reproducible in all versions from 4.7.1
onwards up to 7.3 (compile using godbolt).

## Command

g++ -o out compilererror.cpp -std=c++11 -DV1

leads to a segfault

and

g++ -o out compilererror.cpp -std=c++11 -DV2

leads to an internal compiler error

## Diagnostics

# V1:

compilererror.cpp: In instantiation of ‘void C::Fail() [with void (C::* f)() =
&C::h]’:
compilererror.cpp:32:17:   required from here
compilererror.cpp:25:45: internal compiler error: Segmentation fault
  typename Object>::fail a;
 ^

# V2:

compilererror.cpp: In instantiation of ‘void C::Fail() [with SomeEnum
 = (SomeEnum)0; void (C::* f)() = &C::h]’:
compilererror.cpp:34:34:   required from here
compilererror.cpp:25:45: internal compiler error: in tsubst, at cp/pt.c:13617
  typename Object>::fail a;
 ^

[Bug c++/84162] Internal compiler error: in tsubst, at cp/pt.c:13617 / SEGFAULT

2018-02-01 Thread lumosimann at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84162

--- Comment #1 from Lukas Mosimann  ---
The minimal example is already reduced a lot; until now, I wasn't able to track
the error down to an even smaller chunk of code.

[Bug c++/89831] New: passing 'const ...' as 'this' argument discards qualifiers

2019-03-26 Thread lumosimann at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89831

Bug ID: 89831
   Summary: passing 'const ...' as 'this' argument discards
qualifiers
   Product: gcc
   Version: 9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lumosimann at gmail dot com
  Target Milestone: ---

Starting from GCC 8.1, the following code does not compile anymore:

```
struct Q { 
int operator[](int i) { return 0; }
int operator[](int i) const { return 0; }
};

struct Base {
Q x;
};
struct X : public Base {
template 
void f(T) const {
auto q = Base::x[0];
}   
};
int main() { X{}.f(3); }
```

https://godbolt.org/z/UefNCx

- using `operator()` instead of `operator[]` fixes the problem
- using `x[0]` instead of `Base::x[0]` fixes the problem
- removing the template from `X::f` fixes the problem


In older versions and with clang, compilation is okay.

[Bug c++/89881] New: Incorrect warning "-Wunneeded-internal-declaration"

2019-03-28 Thread lumosimann at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89881

Bug ID: 89881
   Summary: Incorrect warning "-Wunneeded-internal-declaration"
   Product: gcc
   Version: 9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lumosimann at gmail dot com
  Target Milestone: ---

Suppose you have a concept implementation (pre-C++17). This might be something
like this:

#include 

template 
struct check_concept : std::false_type {};

template 
struct check_concept())), int>>> : std::true_type
{};

The type T fulfills the concept if there exists a function f that takes T and
returns int. There may be other functions required for the concept.

Now we are going to use the concept, maybe in a unittest.

namespace {
struct my_type {};
int f(my_type); // my_type implements the concept

static_assert(check_concept::value, "");
}

This will warn about f being unneeded. Somehow it is, because it is not
actually emitted, but on the hand, f is needed because we want to ensure that f
fulfills the concept.

Is the warning correct or not?

See also https://godbolt.org/z/fROBm1

[Bug c++/89881] Incorrect warning "-Wunneeded-internal-declaration"

2019-03-29 Thread lumosimann at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89881

--- Comment #2 from Lukas Mosimann  ---
Yes you're right. But also GCC reports a warning, saying that the function is
only declared, but not defined.

This might be exactly what we want, if the function is only used at compile
time, as a kind of type mapping.

So I'm not sure, but in my opinion, if a function is declared, but not defined,
and it is used in a decltype - that is totally ok and no warning should be
omitted at all.

[Bug c++/87663] New: Exorbitant compile times

2018-10-20 Thread lumosimann at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87663

Bug ID: 87663
   Summary: Exorbitant compile times
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: lumosimann at gmail dot com
  Target Milestone: ---

Created attachment 44864
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=44864&action=edit
Comparison

Let's try to calculate fiboncacchi numbers at compile time in exponential time.
This is a bad implementation of course, but I use that as a placeholder for any
other algorithm with much recursion.

Consider this code:

```
#include 
#include 

template 
struct C : std::integral_constant::value -
  C::value> {};
template 
struct D : std::integral_constant::value -
  D::value> {};

template 
struct C : std::integral_constant {};
template 
struct C : std::integral_constant {};

template 
struct D : std::integral_constant {};
template 
struct D : std::integral_constant {};

int main() {
std::cout << C_OR_D<0, N, 0>::value << std::endl;
return 0;
}
```

Let's think about compile time complexity with respect to `N` when compiling
this code (`C_OR_D` stands for either `C` or `D`).

`C`  calculates kind of a fibonacchi number with some non-important
modification to avoid overflows (`f_n = f_{n-1} - f_{n-2}`). I would expect
compile times to behave like `t_n = t_{n-1} + t_{n-2} = O(1.6^n)`.

`D` is a slightly modified version and we calculate `f_n = f_{n-1} - f_{n-1}`,
which is much more expensive of course. I would expect compile times to behave
like `t_n = t_{n-1} + t_{n-1} = O(2^n)`.


Let's first look at `D`, where I expect compile times of O(2^n):
* Compile times with Clang 7.0.0 for `D`:
> 495 ms ± 5.17 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
> 679 ms ± 4.92 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
> 1.07 s ± 10.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
> 1.85 s ± 39.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
> 3.4 s ± 20 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
> 6.48 s ± 79 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
> 12.9 s ± 227 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Note that I dropped compile times for low `n`, as long as the constant
dominates, and my stop condition is that compile-time is larger than 10 s. For
comparison, I refer to the attachment.
We see that after a while, compile times double when incrementing `n`, which is
prefect.

* Compile times with GCC 8.2.1 for `D`:
> ...
> 620 ms ± 26.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
> 973 ms ± 21.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
> 1.69 s ± 15.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
> 3.38 s ± 39.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
> 6.6 s ± 102 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
> 13.5 s ± 446 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Also here, we observe that compile times double when incrementing `n`.

In absolute numbers, gcc is slightly faster for low numbers, and worse for
large `n`. See attachment (left, "Power of Two").

Let's now look at `C` (Fibonacchi):

* Compile times with Clang 7.0.0 for `C`:
> ...
> 1.41 s ± 13.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
> 2.06 s ± 17.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
> 3.18 s ± 51.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
> 5.16 s ± 273 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
> 8.01 s ± 219 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
> 13.1 s ± 385 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Isn't this nice? This is a fibonacchi sequence! Let's continue with GCC.

* Compile times with GCC 8.2.1 for `C`:
> ...
> 964 ms ± 14.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
> 1.8 s ± 38 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
> 4.95 s ± 252 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
> 17.8 s ± 822 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

What is that? Compile times explode! It turns out that compile times for this
example are around O(3^n), much worse than `D` for almost any `n`.

In absolute numbers, gcc becomes soon terribly slow. See attachment (right,
"Fibonacchi").

Questions:

* Why does this behavior occur?
* Could this behavior have any impact on real-life code? I would assume yes.

[Bug c++/87663] Exorbitant compile times

2018-10-20 Thread lumosimann at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87663

--- Comment #1 from Lukas Mosimann  ---
By the way: I could drop parameter `Z` from `C` and `D`. I forgot to remove
that when I was experimenting with extensions like `f_n = f_{n-1} + f_{n-2} +
f_{n-3}`.

[Bug c++/87663] Exorbitant compile times

2018-10-26 Thread lumosimann at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87663

--- Comment #3 from Lukas Mosimann  ---
```
template 
struct integral_constant {
static constexpr T value = v;
using value_type = T;
using type = integral_constant;
};

template 
struct F : integral_constant::value -
 F::value> {};
template 
struct P : integral_constant::value -
 P::value> {};

template 
struct F : integral_constant {};
template 
struct F : integral_constant {};

template 
struct P : integral_constant {};
template 
struct P : integral_constant {};

int main() {
P_OR_F<0, N, 0>::value;
return 0;
}
```

This is a shorter reproducible without other headers. The problem is the line
`using value_type = T`. I would love to debug this, but I don't know where to
start.

[Bug c++/87663] Exorbitant compile times

2018-10-26 Thread lumosimann at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87663

--- Comment #4 from Lukas Mosimann  ---
Okay one last comment from my side (sorry for this two updates in short
intervals). I tried to further simplify it, and I came up with this code which
I think has the same problem.

```
template 
struct integral_constant {
static constexpr T value = v;
using value_type = int; // remove this line
};

template 
struct F : integral_constant::value -
  F::value> {};

template 
struct F : integral_constant {};

int main() {
F<0, 15>::value;
return 0;
}
```

`integral_constant` with `value_type` compiles in 32 seconds on my machine.

`integral_constant` without `value_type` compiles in 1.6 seconds.

So we are talking about an 20x increase in compilation time. Things get worse
with larger N, e.g. `F<0, 16>`: 3.5 s vs. 167 s (48x increase).

[Bug c++/87663] Exorbitant compile times

2018-10-28 Thread lumosimann at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87663

--- Comment #5 from Lukas Mosimann  ---
I was able to track down the error. The problem is caused due to
`set_underlying_type` in cfamily/c_common.c. I tried to disable that function
by simply returning on entry - and compilation times for cc1plus are completely
restored in all examples in this issue. This of course breaks other code, but
for the case of demonstration this is enough.
The first example with Version C used to compile in N=23: 181s, N=24: 493s,
N=25: 1348s. We would expect this to be a fibonacchi sequence - and this are
the new compile times for the same source: N=23: 5s, N=24: 8s, N=25: 13s.
Tests of  

Consider the example in the last comment. There the problem arises because the
variant list gets huge as this function adds type variants for the int-typedef
over and over. When looking for the right variant later, we need to iterate
over potentially all this variants.

Now I need your help: I don't know the code base for gcc that well. Why do we
need this functionality, and how could we solve this issue? I could imagine
that this can also impact real code - but it's hard to say because the
quick-fix above only works in simple codes. I would love to continue working on
this, but I need some hints how I could do this (or that it cannot be done
without major rework).

[Bug c++/87663] using / typedef on recursive template leads to long compile time

2018-10-29 Thread lumosimann at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87663

--- Comment #7 from Lukas Mosimann  ---
Thanks! I will do that.

First lets sum up state here such that it's not required to read through all
comments. I am playing around with integral constant and an "exponential
wrapper". First the "exponential wrapper":

```
template 
struct F : integral_constant::value -
  F::value> {};

template 
struct F : integral_constant {};

int main() {
F<0, 14>::value;
return 0;
}
```
I.e., we simply instantiate a huge set of integral constants. Now I play with
different integral_constants a measure compilation time.

=== V1 0.8s ===
template 
struct integral_constant {
static constexpr T value = v;
};


=== V2 4.4s === (used by type_traits)
template 
struct integral_constant {
static constexpr T value = v;
using value_type = T;
};

=== V3 4.2s ===
template 
struct integral_constant {
using value_type = T;
static constexpr T value = v;
};

=== V4 23 s === (!!)
template 
struct integral_constant {
using value_type = T;
static constexpr value_type value = v;
};

Currently I am working with a modified version of V2 (4.4s):

template 
struct integral_constant {
static constexpr T value = v;
using value_type = int;
};

In this case I see that we always create a new type variant of int (I guess one
per integral constant) through set_underlying type, and at another point we
iterate through large parts of the list to get the correct variant again (over
build_qualified_type). More precisely:
1) We first do build_qualified_type for value. This iterates through the whole
list and at some point finds "plain const int" (no typedef) - no new type
variant required.
2) We create a new type variant of int referring to the alias in this specific
integral_constant. This is prepended to the list of type variants, i.e., in the
next 1) we need to iterate over one additional entry than before to find "plain
const int".
Therefore, integral constant instantiation gets more expensive with each
instance.

I have seen the comment above set_underlying type, but my question is more
whether this is always needed (it is only talking about debugging and protoize
- so is it also required in a build without debugging information?).
And yes, it might also be possible to do it more efficient: Do all variants
need to be stored in this list? Is this the natural order for a list - and is a
list the right data structure for this?

I will post to the mailing list pointing to this comment.

[Bug tree-optimization/118796] [15 Regression] ICE when building atlas-ecmwf 0.40.0 (copy_reference_ops_from_ref, at tree-ssa-sccvn.cc:1109)

2025-03-25 Thread lumosimann at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118796

Lukas Mosimann  changed:

   What|Removed |Added

 CC||lumosimann at gmail dot com

--- Comment #7 from Lukas Mosimann  ---
Since I just also ran across this in atlas, I think this is a reproducer:

https://godbolt.org/z/exhYqsG4P

Maybe could be shortened a bit more, but should be already very short.

In the last steps of reducing the issue, the error messages change a bit...

[Bug tree-optimization/118796] [15 Regression] ICE when building atlas-ecmwf 0.40.0 (copy_reference_ops_from_ref, at tree-ssa-sccvn.cc:1109)

2025-03-25 Thread lumosimann at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118796

--- Comment #9 from Lukas Mosimann  ---
Pretty sure they are related, just need to add one line back (line 7):

https://godbolt.org/z/5dqG3bj7e

to get the same error:

internal compiler error: in copy_reference_ops_from_ref, at
tree-ssa-sccvn.cc:1113
0x26727e5 diagnostic_context::diagnostic_impl(rich_location*,
diagnostic_metadata const*, diagnostic_option_id, char const*, __va_list_tag
(*) [1], diagnostic_t)
???:0
0x2689776 internal_error(char const*, ...)
???:0
0x9dedc2 fancy_abort(char const*, int, char const*)
???:0
0x13f2106 vn_reference_lookup(tree_node*, tree_node*, vn_lookup_kind,
vn_reference_s**, bool, tree_node**, tree_node*, bool)
???:0
Please submit a full bug report, with preprocessed source (by using
-freport-bug).
Please include the complete backtrace with any bug report.
See  for instructions.