[Bug c++/84795] New: Explicit specialization of constexpr static data member incorrectly rejected in C++17

2018-03-09 Thread inadgob at yahoo dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84795

Bug ID: 84795
   Summary: Explicit specialization of constexpr static data
member incorrectly rejected in C++17
   Product: gcc
   Version: 8.0.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: inadgob at yahoo dot com
  Target Milestone: ---

The following code is incorrectly rejected in C++17 mode:


template struct A { static constexpr int v = 7; };

template<> constexpr int A::v = 3;

static_assert(A::v == 3);

int main() { }


Compiled with -std=c++17 -pedantic -Wall -Wextra. Diagnostic:

prog.cc:3:34: error: duplicate initialization of 'A::v'
 template<> constexpr int A::v = 3;
  ^

Rejecting this would be correct in C++14 mode, where the initializer is part of
the declaration that is instantiated as part of the implicit instantiation of
A. However, in C++17 v is implicitly inline, so its declaration is a
definition, which shouldn't be instantiated as part of the implicit
instantiation. I believe this is covered by [temp.expl.spec]/15:

> A member or a member template of a class template may be explicitly 
> specialized for a given implicit instantiation of the class template, 
> even if the member or member template is defined in the class template 
> definition.

[Bug libstdc++/77334] [5/6/7 Regression] Cannot move assign std::map with non-copyable and non-movable mapped_type

2016-08-23 Thread inadgob at yahoo dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77334

--- Comment #5 from bogdan  ---
From now on, "fast" shall have a new degree of comparison beyond the
superlative, spelled "jw-fast" (alternative spelling when appearing in text on
gcc.gnu.org: "redi-fast"). 

Cheers!

[Bug libstdc++/77334] New: Cannot move assign std::map with non-copyable and non-movable mapped_type

2016-08-22 Thread inadgob at yahoo dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77334

Bug ID: 77334
   Summary: Cannot move assign std::map with non-copyable and
non-movable mapped_type
   Product: gcc
   Version: 6.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: inadgob at yahoo dot com
  Target Milestone: ---

Consider the following code: 


#include 

struct A
{
   A(A&&) = delete;
};

int main()
{
   std::map<int, A> m1, m2;
   m2 = std::move(m1);
}


The move assignment is rejected; diagnostics here:
http://melpon.org/wandbox/permlink/s3MafVYFzQrUMN4F.

According to the allocator-aware container requirements table in
[container.requirements.general], there should be no special requirements on
value_type in this case, so the assignment should work.

This is due to the use of an if statement instead of tag dispatching to check
the allocator traits in the implementation of _Rb_tree's move assignment
operator. 

The issue seems to have appeared in version 4.9.0.

The example that prompted this bug report and more details are available here:
http://stackoverflow.com/q/39040609/4326278.

[Bug c++/71534] Initializing a static constexpr data member of a base class by using a static constexpr data member of a derived class should be an error

2016-07-23 Thread inadgob at yahoo dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71534

bogdan  changed:

   What|Removed |Added

 CC||inadgob at yahoo dot com

--- Comment #3 from bogdan  ---
Following the adoption of P0386R2 into the working draft, the declaration of
bar is now a definition, because bar is an inline variable.

This makes GCC's behaviour standard-conforming in C++1z mode as far as I can
tell. However, I think a fix should still be applied to C++14 and 11 modes, in
the interest of portability.

[Bug c++/71879] Error in unevaluated context breaks SFINAE

2016-07-18 Thread inadgob at yahoo dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71879

bogdan  changed:

   What|Removed |Added

 CC||inadgob at yahoo dot com

--- Comment #2 from bogdan  ---
(In reply to Jonathan Wakely from comment #1)
> Taking the address of Foo::foo instantiates it, which results in an
> error outside the immediate context, so you get an error not a substitution
> failure.

Yes, GCC tries to instantiate the definition of the specialization, but I don't
think it should.

[temp.inst]/3: Unless a function template specialization has been explicitly
instantiated or explicitly specialized, the function template specialization is
implicitly instantiated when the specialization is referenced in a context that
requires a function definition to exist. [...]

[temp.inst]/8: An implementation shall not implicitly instantiate a function
template, a variable template, a member template, a non-virtual member
function, a member class, or a static data member of a class template that does
not require instantiation. [...]

I don't think forming a pointer to a member function as an operand to decltype
like in this example should, by itself, require the function's definition to
exist; after all, we're only interested in the type. In this case, determining
it doesn't require deduction of any placeholder type or evaluation of any
constant expression. I don't see how the definition could influence the
resulting type.

In terms of odr-use, the template-id for the specialization appears as a
subexpression of an unevaluated operand, so it's not potentially evaluated, so
[basic.def.odr] doesn't require a definition.

The example works on Clang, EDG and MSVC, so none of them attempts to
instantiate the definition.

[Bug c++/70167] New: Some const array prvalues are incorrectly treated as lvalues

2016-03-10 Thread inadgob at yahoo dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70167

Bug ID: 70167
   Summary: Some const array prvalues are incorrectly treated as
lvalues
   Product: gcc
   Version: 5.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: inadgob at yahoo dot com
  Target Milestone: ---

The following code is incorrectly rejected: 
(compiled with -Wall -Wextra -std=c++1z -pedantic)


#include 

template void f(T(&&)[S]) { }

using arr = const int[2];

int main()
{
f(arr{1, 2});
}


Diagnostics:

prog.cc: In function 'int main()':
prog.cc:9:16: error: cannot bind 'arr {aka const int [2]}' lvalue to 'const int
(&&)[2]'
 f(arr{1, 2});
^
prog.cc:3:39: note:   initializing argument 1 of 'void f(T (&&)[S]) [with T =
const int; long unsigned int S = 2ul]'
 template void f(T(&&)[S]) { }
   ^

Also, decltype(arr{1, 2}) yields const int(&)[2], so it looks like the const
array prvalue is incorrectly treated as an lvalue here. Xvalues of such types
work correctly; non-const array rvalues are fine as well.

This also happens if the array element type is an aggregate. Replacing the
alias declaration with

struct A { int i; };
using arr = const A[2];

causes the same error.

However, it doesn't happen for elements of non-aggregate class type. Replacing
the alias declaration with 

struct A { A(int) { } };
using arr = const A[2];

makes the code compile with no diagnostics.