[Bug libstdc++/64096] std::list, set and map violate a rule about allocator::construct

2014-11-28 Thread palpatin91 at mail dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64096

rylai palpatin91 at mail dot ru changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |WONTFIX

--- Comment #2 from rylai palpatin91 at mail dot ru ---
Known issues


[Bug libstdc++/64096] New: std::list, set and map violate a rule about allocator::construct

2014-11-27 Thread palpatin91 at mail dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64096

Bug ID: 64096
   Summary: std::list, set and map violate a rule about
allocator::construct
   Product: gcc
   Version: 4.9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: palpatin91 at mail dot ru

According to the 23.2.1p3 C++11 Standard:
===
For the components affected by this subclause that declare an allocator_type,
objects stored in these components shall be constructed using the
allocator_traitsallocator_type::construct function and destroyed using the
allocator_traitsallocator_type::destroy function (20.6.8.2). These functions
are called only for the container’s element type, not for internal types used
by the container. [ Note: This means, for example, that a node-based container
might need to construct nodes containing aligned buffers and call construct to
place the element into the buffer. —end note ]
===

Here allocator_type is a direct template's type argument, and allocator_traits
just call allocator's construct method, if it exists. However, std::list, set
and map (and also multiset and multimap) violate this rule and call construct
method from an allocator of rebinded type, not of an original one. I know, that
we need rebinding for memory allocation, but for construct call we should use
original one. 23.2.1p13 also proves this:
===
Given a container type X having an allocator_type identical to A and a
value_type identical to T and given an lvalue m of type A, a pointer p of type
T*, an expression v of type T, and an rvalue rv of type T, the following terms
are defined. (If X is not allocator-aware, the terms below are defined as if A
were std::allocatorT.)
— T is CopyInsertable into X means that the following expression is
well-formed: allocator_traitsA::construct(m, p, v);
— T is MoveInsertable into X means that the following expression is
well-formed: allocator_traitsA::construct(m, p, rv);
— T is EmplaceConstructible into X from args, for zero or more arguments args,
means that the following expression is well-formed:
allocator_traitsA::construct(m, p, args);
===

Now some code that confirms a bug:
===
#include vector
#include list
#include set
#include map
#include unordered_set
#include unordered_map
#include type_traits

templatetypename T
struct my_allocator : public std::allocatorT {
my_allocator() noexcept {}

templatetypename U
my_allocator(const my_allocatorU source) noexcept
: std::allocatorT(source) {}

templatetypename U
struct rebind {
using other = my_allocatorU;
};

templatetypename U, typename... Args
void construct(U*, Args...) {
static_assert(!std::is_sameU, U::value, Wrong construct);
}
};

template typename T, typename U
bool operator==(const my_allocatorT, const my_allocatorU)
{ return true; }

template typename T, typename U
bool operator!=(const my_allocatorT, const my_allocatorU)
{ return false; }

template
struct my_allocatorint : public std::allocatorint {
my_allocator() noexcept {}

templatetypename U
my_allocator(const my_allocatorU source) noexcept
: std::allocatorint(source) {}

templatetypename U
struct rebind {
using other = my_allocatorU;
};
};

using map_int_int_value_type = std::mapint, int::value_type;

template
struct my_allocatormap_int_int_value_type
: public std::allocatormap_int_int_value_type {
my_allocator() noexcept {}

templatetypename U
my_allocator(const my_allocatorU source) noexcept
: std::allocatormap_int_int_value_type(source) {}

templatetypename U
struct rebind {
using other = my_allocatorU;
};
};

int main()
{
{
using container = std::vectorint, my_allocatorint;
container c;
c.emplace_back(0);
}
{
using container = std::listint, my_allocatorint;
container c;
c.emplace_back(0);
}
{
using container = std::setint, std::lessint, my_allocatorint;
container c;
c.emplace(0);
}
{
using container = std::multisetint, std::lessint,
my_allocatorint;
container c;
c.emplace(0);
}
{
using container = std::unordered_setint, std::hashint,
std::equal_toint, my_allocatorint;
container c;
c.emplace(0);
}
{
using container = std::unordered_multisetint, std::hashint,
std::equal_toint, my_allocatorint;
container c;
c.emplace(0);
}
{
using container = std::mapint, int, std::lessint,
my_allocatormap_int_int_value_type

[Bug c++/61216] New: wrong name lookup for operator functions with using-declaration

2014-05-18 Thread palpatin91 at mail dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61216

Bug ID: 61216
   Summary: wrong name lookup for operator functions with
using-declaration
   Product: gcc
   Version: 4.8.1
Status: UNCONFIRMED
  Severity: trivial
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: palpatin91 at mail dot ru

In GCC 4.8.1 for Windows XP:
-
gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=f:/dev-cpp/mingw32/bin/../libexec/gcc/mingw32/4.8.1/lto-wrap
per.exe
Target: mingw32
Configured with: ../gcc-4.8.1/configure --prefix=/mingw --host=mingw32
--build=m
ingw32 --without-pic --enable-shared --enable-static --with-gnu-ld --enable-lto
--enable-libssp --disable-multilib
--enable-languages=c,c++,fortran,objc,obj-c++
,ada --disable-sjlj-exceptions --with-dwarf2 --disable-win32-registry
--enable-l
ibstdcxx-debug --enable-version-specific-runtime-libs
--with-gmp=/usr/src/pkg/gm
p-5.1.2-1-mingw32-src/bld --with-mpc=/usr/src/pkg/mpc-1.0.1-1-mingw32-src/bld
--
with-mpfr= --with-system-zlib --with-gnu-as --enable-decimal-float=yes
--enable-
libgomp --enable-threads --with-libiconv-prefix=/mingw32
--with-libintl-prefix=/
mingw --disable-bootstrap LDFLAGS=-s CFLAGS=-D_USE_32BIT_TIME_T
Thread model: win32
gcc version 4.8.1 (GCC)
-

following code fragment gives compilation error:
-
class C {

};

namespace N {
C operator ++(C obj) { return obj; }
}

C operator ++(C obj) { return obj; }

int main()
{
using N::operator ++;
C c;
++c;
}
-
main.cpp: In function 'int main()':
main.cpp:69:2: error: ambiguous overload for 'operator++' (operand type is 'C')
  ++c;
  ^
main.cpp:69:2: note: candidates are:
main.cpp:60:4: note: C N::operator++(C)
 C operator ++(C obj) { return obj; }
^
main.cpp:63:4: note: C operator++(C)
 C operator ++(C obj) { return obj; }
^
-
But according to 13.3.1.2p3:
The set of non-member candidates is the result of the unqualified lookup of
operator@ in the context
of the expression according to the usual rules for name lookup in unqualified
function calls (3.4.2)
except that all member functions are ignored.

And the following code compiles just fine:
-
namespace N {
void f() {}
}

void f() {}

int main()
{
using N::f;
f();
}
-
So I assume in case of operator functions it should compile also and choose
N::operator ++ version


[Bug c++/61216] wrong name lookup for operator functions with using-declaration

2014-05-18 Thread palpatin91 at mail dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61216

rylai palpatin91 at mail dot ru changed:

   What|Removed |Added

   Severity|trivial |minor


[Bug c++/61216] wrong name lookup for operator functions with using-declaration

2014-05-18 Thread palpatin91 at mail dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61216

--- Comment #2 from rylai palpatin91 at mail dot ru ---
(In reply to Daniel Krügler from comment #1)
Thank you to point it out.

[Bug c++/61216] wrong name lookup for operator functions with using-declaration

2014-05-18 Thread palpatin91 at mail dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61216

rylai palpatin91 at mail dot ru changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |INVALID

--- Comment #3 from rylai palpatin91 at mail dot ru ---
Closed.