[Bug c++/71446] Incorrect overload resolution when using designated initializers

2019-02-25 Thread roman.perepelitsa at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71446

--- Comment #4 from Roman Perepelitsa  ---
Please take a look at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71446#c1.
This code compiles. Given that it contains `{.value = 0}`, one would reasonably
expect that it creates an instance of a struct with the data member `value` set
to zero. However, it doesn't. The literal `{.value = 0}` creates an instance of
type `std::initialize_list`. This is very misleading. The code should
either not compile or do what was intended (which is also what C++20 requires
and what clang does).

[Bug c++/69957] New: Ambiguous overload due to incorrect partial ordering of V<> and V

2016-02-25 Thread roman.perepelitsa at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69957

Bug ID: 69957
   Summary: Ambiguous overload due to incorrect partial ordering
of V<> and V
   Product: gcc
   Version: 5.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: roman.perepelitsa at gmail dot com
  Target Milestone: ---

=== Program #1 ===

  template  struct V {};

  template 
  void Foo(V, V) {}

  template 
  void Foo(V<>, V) {}

  int main() {
Foo(V<>(), V<>());
  }

Expected: compiles.
Actual: error: call of overloaded 'Foo(V<>, V<>)' is ambiguous.

=== Program #2 ===

(This might be a different bug)

  template  struct V {};

  template 
  void Foo(V, V) {}

  template 
  void Foo(V<>, Us&&...) {}

  int main() {
Foo(V<>(), V<>());
  }

Expected: error: call of overloaded 'Foo(V<>, V<>)' is ambiguous.
Actual: compiles.

[Bug c++/57433] Local classes have an associated namespace

2016-03-23 Thread roman.perepelitsa at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57433

Roman Perepelitsa  changed:

   What|Removed |Added

 CC||roman.perepelitsa at gmail dot 
com

--- Comment #1 from Roman Perepelitsa  ---
Here's another example:

  template  void Bar(T t) { Foo(t); }
  template  void Foo(T) {}

  void Test() {
Bar([]{});
  }

Clang rejects this code (expected behaviour), gcc accepts it (unexpected
behaviour). Gcc erroneously finds Foo() by ADL.

A more elaborate example:

  namespace n1 {
  template  void Foo(T) {}
  auto F = []{};
  auto G = []{ return []{}; }();
  }  // namespace n1

  namespace n2 {
  void Test() {
Foo(n1::F);  // gcc and clang accept
Foo(n1::G);  // gcc accepts, clang rejects
  }
  }  // namespace n2

F is a lambda defined in namespace scope of n1. When Test() calls Foo(n1::F),
n1::Foo() is found via ADL. Nothing surprising here.

Now, G is also a lambda from n1 but it's defined locally, in a function. When
gcc resolves Foo(n1::G), it finds n1::Foo() by ADL, but clang doesn't.

We can use structs instead of lambdas and the effect will be the same. We also
can use regular non-template functions:

  namespace n1 {
  struct S {};
  auto MakeQ = []{ struct Q {}; return Q(); };
  using Q = decltype(MakeQ());
  void Foo(S) {}
  void Foo(Q) {}
  }  // namespace n1

  namespace n2 {
  void Test() {
Foo(n1::S());  // gcc and clang accept
Foo(n1::Q());  // gcc accepts, clang rejects
  }
  }  // namespace n2

[Bug c++/70544] New: Overload resolution with explicitly specified template arguments

2016-04-05 Thread roman.perepelitsa at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70544

Bug ID: 70544
   Summary: Overload resolution with explicitly specified template
arguments
   Product: gcc
   Version: 5.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: roman.perepelitsa at gmail dot com
  Target Milestone: ---

When compiling this program:

  template 
  void F(Args&&...);

  template 
  int F(Args&&...);

  int main() {
int{F(0)};
  }

Expected behavior: compile error (call to `F` is ambiguous).
Actual behaviour: compiles successfully.

Comment from Richard Smith: "I suspect this might be fallout from GCC's
workaround for core issue 1395 (after substituting explicitly-specified
template arguments, the first 'F' has one pack element deduced and the second
'F' has none, so I suspect the second may look more specialized under GCC's
approach to 1395 but not Clang's)."

Note that the following program gets rejected by GCC (as expected):

  template 
  void F(T);

  template 
  void F(U);

  int main() {
F(0);
  }

[Bug c++/71382] New: Unary plus doesn't works with pointers to instantiations of function templates

2016-06-02 Thread roman.perepelitsa at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71382

Bug ID: 71382
   Summary: Unary plus doesn't works with pointers to
instantiations of function templates
   Product: gcc
   Version: 5.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: roman.perepelitsa at gmail dot com
  Target Milestone: ---

This compiles:

  void F();
  void G() { +(&F); }

This doesn't:

  template  void F();
  void G() { +(&F); }

error: wrong type argument to unary plus

Expected behaviour: both examples compile.

[Bug c++/71446] New: Incorrect overload resolution when using designated initializers

2016-06-07 Thread roman.perepelitsa at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71446

Bug ID: 71446
   Summary: Incorrect overload resolution when using designated
initializers
   Product: gcc
   Version: 5.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: roman.perepelitsa at gmail dot com
  Target Milestone: ---

Actual behaviour: the following program compiles.
Expected behaviour: doesn't compile.

  #include 

  struct S {
int value;
  };

  int F(S);
  char* F(std::initializer_list);

  char* p = F({.value = 0});

The compiler should either resolve `F({.value = 0})` as `int F(S)` or generate
a `sorry, not implemented` error. It shouldn't resolve it as `char*
F(std::initializer_list)`.

[Bug c++/71446] Incorrect overload resolution when using designated initializers

2016-06-08 Thread roman.perepelitsa at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71446

--- Comment #1 from Roman Perepelitsa  ---
The same bug can lead to incorrect behaviour at run time.

  #include 
  #include 

  struct S {
int value;
  };

  void F(S) { puts("right"); }
  void F(std::initializer_list) { puts("wrong"); }

  int main() {
F({.value = 0});
  }

Should print "right" but actually prints "wrong".

[Bug libstdc++/71096] std::get did not work for nested derived classes from std::tuple if one element is empty

2016-11-22 Thread roman.perepelitsa at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71096

Roman Perepelitsa  changed:

   What|Removed |Added

 CC||roman.perepelitsa at gmail dot 
com

--- Comment #1 from Roman Perepelitsa  ---
Slightly simpler example (no user-defined templates):

  #include 

  struct A {};
  struct B : std::tuple {};

  int main() {
std::tuple t;
std::get<0>(t);  // compile error
  }

Note that both A and B are empty in the sense of std::is_empty. If you make
either of them non-empty by adding a data member, the code will compile.

  #include 

  struct A { char c; };  // not empty
  struct B : std::tuple {};

  int main() {
std::tuple t;
std::get<0>(t);  // compiles
  }

Likewise, the code compiles when getting the element by type instead of index.

  #include 

  struct A {};
  struct B : std::tuple {};

  int main() {
std::tuple t;
std::get(t);  // compiles
  }

[Bug middle-end/68360] GCC bitfield processing code is very inefficient

2016-11-18 Thread roman.perepelitsa at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68360

Roman Perepelitsa  changed:

   What|Removed |Added

 CC||roman.perepelitsa at gmail dot 
com

--- Comment #3 from Roman Perepelitsa  ---
Here's another example where GCC generates suboptimal code for bitfield
initialization on x64: https://godbolt.org/g/WeqAr5.

  #include 

  struct S {
S(uint32_t a, uint32_t b);

uint32_t a : 2;
uint32_t b : 30;
  };

  S::S(uint32_t a, uint32_t b) : a(a), b(b) {}

Here's the code generated for the constructor when compiled with -O2.

Clang 3.9:

andl$3, %esi
leal(%rsi,%rdx,4), %eax
movl%eax, (%rdi)
retq

GCC 7.0:

movl%esi, %eax
movzbl  (%rdi), %esi
andl$3, %eax
andl$-4, %esi
orl %eax, %esi
leal0(,%rdx,4), %eax
movb%sil, (%rdi)
movl(%rdi), %edx
andl$3, %edx
orl %eax, %edx
movl%edx, (%rdi)
ret

[Bug c++/60044] New: Template argument of alias template not evaluated

2014-02-03 Thread roman.perepelitsa at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60044

Bug ID: 60044
   Summary: Template argument of alias template not evaluated
   Product: gcc
   Version: 4.8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: roman.perepelitsa at gmail dot com

$ cat test.cc
#include 

template 
using Void = void;

template 
struct Foo {
  const char* value = "primary template";
};

template 
struct Foo> {
  const char* value = "specialization";
};

int main() {
  puts(Foo().value);
}

$ g++ -std=c++11 test.cc && ./a.out
specialization

Expected output:
primary template


[Bug c++/62115] [5 Regression] ICE with invalid default argument

2014-11-06 Thread roman.perepelitsa at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62115

Roman Perepelitsa  changed:

   What|Removed |Added

 CC||roman.perepelitsa at gmail dot 
com

--- Comment #4 from Roman Perepelitsa  ---
r216124 has also fixed another bug, which may result in valid code being
rejected and also in incorrect code generation for valid code.

#include 

struct Base { int value; };
struct Derived : Base {};

void Foo(int&&) {}

int main() {
  Derived d;
  Foo(std::move(d).value);
}

Before r216124 this program produced the following compile error:

   test.cc: In function 'int main()':
test.cc:10:25: error: cannot bind 'int' lvalue to 'int&&'
   Foo(std::move(d).value);
 ^
test.cc:6:6: error:   initializing argument 1 of 'void Foo(int&&)'
void Foo(int&&) {}

If function Foo() was overloaded for const int& and int&, or if it used perfect
forwarding, it would result in successful compilation and incorrect runtime
behaviour.

Would it be possible to backport the fix to gcc-4_9-branch?


[Bug libstdc++/61947] New: Ambiguous calls when constructing std::tuple

2014-07-29 Thread roman.perepelitsa at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61947

Bug ID: 61947
   Summary: Ambiguous calls when constructing std::tuple
   Product: gcc
   Version: 4.8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: roman.perepelitsa at gmail dot com

#include 

struct ConvertibleToAny {
  template  operator T() const { return T(); }
};

int main() {
  std::tuple t(ConvertibleToAny{});
}

Produces:

third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:262:4:
error: call to constructor of '_Head_base<0UL, (anonymous
namespace)::ConvertibleToAny &&, __empty_not_final::value>' is ambiguous
  _Base(std::forward<_UHead>(__head)) { }
  ^ 
third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:405:4:
note: in instantiation of function template specialization 'std::_Tuple_impl<0,
(anonymous namespace)::ConvertibleToAny &&>::_Tuple_impl<(anonymous
namespace)::ConvertibleToAny, void>' requested here
: _Inherited(std::forward<_UElements>(__elements)...) { }
  ^
experimental/users/romanp/tuple_bug/tuple-bug.cc:13:34: note: in instantiation
of function template specialization 'std::tuple<(anonymous
namespace)::ConvertibleToAny &&>::tuple<(anonymous
namespace)::ConvertibleToAny, void>' requested here
  std::tuple t(ConvertibleToAny{});
 ^
third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:128:12:
note: candidate is the implicit move constructor
struct _Head_base<_Idx, _Head, false>
   ^
third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:128:12:
note: candidate constructor (the implicit copy constructor) has been implicitly
deleted
third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:142:7:
note: candidate constructor
  _Head_base(__uses_alloc0)

The call shouldn't be ambiguous. It should pick the following constructor:

[tuple.cnstr]

  template 
  explicit tuple(UTypes&&... u);

  Requires: sizeof...(Types) == sizeof...(UTypes). is_constructible::value is true for all i.
  Effects: Initializes the elements in the tuple with the corresponding value
in std::forward(u).

is_constructible::value is true, so the
precondition is satisfied.

This bug affects std::bind as it's built on top of std::tuple.

#include 

struct ConvertibleToAny {
  template  operator T() const { return T(); }
};

void Sink(int) {}

int main() {
  std::bind(Sink, std::placeholders::_1)(ConvertibleToAny{});
}

Error:

third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:262:4:
error: call to constructor of '_Head_base<0UL, (anonymous
namespace)::ConvertibleToAny &&, __empty_not_final::value>' is ambiguous
  _Base(std::forward<_UHead>(__head)) { }
  ^ 
third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:405:4:
note: in instantiation of function template specialization 'std::_Tuple_impl<0,
(anonymous namespace)::ConvertibleToAny &&>::_Tuple_impl<(anonymous
namespace)::ConvertibleToAny, void>' requested here
: _Inherited(std::forward<_UElements>(__elements)...) { }
  ^
third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:868:14:
note: in instantiation of function template specialization
'std::tuple<(anonymous namespace)::ConvertibleToAny &&>::tuple<(anonymous
namespace)::ConvertibleToAny, void>' requested here
{ return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
 ^
third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/functional:1354:13:
note: in instantiation of function template specialization
'std::forward_as_tuple<(anonymous namespace)::ConvertibleToAny>' requested here
  std::forward_as_tuple(std::forward<_Args>(__args)...),
   ^
experimental/users/romanp/tuple_bug/tuple-bug.cc:15:41: note: in instantiation
of function template specialization 'std::_Bind))(int)>::operator()<(anonymous
namespace)::ConvertibleToAny, void>' requested here
  std::bind(Sink, std::placeholders::_1)(ConvertibleToAny{});

[Bug c++/62227] New: Templated move not elided

2014-08-22 Thread roman.perepelitsa at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62227

Bug ID: 62227
   Summary: Templated move not elided
   Product: gcc
   Version: 4.8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: roman.perepelitsa at gmail dot com

#include 

struct S {
  S(int) {}
  S(const S&) = default;   // (1)
  template   // (2)
  S(S&& other) {
puts("move");
  }
};

int main() {
  S s = 42;
  (void)s;
}

This program unexpectedly prints "move". The expected output is empty (move is
elided).

The program prints nothing (as expected) if any of the following is done:

  - Line (1) is removed.
  - Line (2) is removed.
  - The program is compiled with clang.


[Bug c++/60044] Template argument of alias template not evaluated

2015-12-18 Thread roman.perepelitsa at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60044

Roman Perepelitsa  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |FIXED

--- Comment #3 from Roman Perepelitsa  ---
Fixed by r217250.

[Bug c++/63875] Bogus unused-but-set-parameter warning when expanding a variadic template argument pack

2016-07-14 Thread roman.perepelitsa at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63875

Roman Perepelitsa  changed:

   What|Removed |Added

 CC||roman.perepelitsa at gmail dot 
com

--- Comment #3 from Roman Perepelitsa  ---
This appears to be fixed in gcc 6.1: the provided snippet compiles cleanly.