[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken

2019-12-31 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541

--- Comment #17 from Jonathan Wakely  ---
Done:

https://gitlab.com/esr/gcc-conversion/merge_requests/47

[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken

2019-12-31 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541

--- Comment #16 from Jonathan Wakely  ---
It had nothing to do with Git. It's just a python script that says commit
r279763 is related to PR x not PR y.

[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken

2019-12-30 Thread tkoenig at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541

--- Comment #15 from Thomas Koenig  ---
(In reply to Jonathan Wakely from comment #14)
> And please also fix the comment in the new test.

(In reply to Jonathan Wakely from comment #13)
> (In reply to Thomas Koenig from comment #12)
> > (In reply to Thomas Koenig from comment #11)
> > 
> > *sigh* corrected in the original PR.
> 
> Please add a 'fixup' to the bugdb.py file in the gcc-conversion repo, so
> this can be fixed in the Git conversion

How?  I know nothing about git.

[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken

2019-12-30 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541

--- Comment #14 from Jonathan Wakely  ---
And please also fix the comment in the new test.

[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken

2019-12-30 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541

--- Comment #13 from Jonathan Wakely  ---
(In reply to Thomas Koenig from comment #12)
> (In reply to Thomas Koenig from comment #11)
> 
> *sigh* corrected in the original PR.

Please add a 'fixup' to the bugdb.py file in the gcc-conversion repo, so this
can be fixed in the Git conversion (I already did this for several of your
commits with wrong PR numbers).

[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken

2019-12-30 Thread tkoenig at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541

Thomas Koenig  changed:

   What|Removed |Added

 CC||tkoenig at gcc dot gnu.org

--- Comment #12 from Thomas Koenig  ---
(In reply to Thomas Koenig from comment #11)

*sigh* corrected in the original PR.

[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken

2019-12-30 Thread tkoenig at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541

--- Comment #11 from Thomas Koenig  ---
Author: tkoenig
Date: Mon Dec 30 10:43:38 2019
New Revision: 279763

URL: https://gcc.gnu.org/viewcvs?rev=279763=gcc=rev
Log:
Remove KIND argument from INDEX so it does not mess up scalarization.

2019-12-30  Thomas Koenig  

PR fortran/91541
* intrinsic.c (add_sym_4ind): New function.
(add_functions): Use it for INDEX.
(resolve_intrinsic): Also call f1m for INDEX.
* intrinsic.h (gfc_resolve_index_func): Adjust prototype to
take a gfc_arglist instead of individual arguments.
* iresolve.c (gfc_resolve_index_func): Adjust arguments.
Remove KIND argument if present, and make sure this is
not done twice.
* trans-decl.c: Include "intrinsic.h".
(gfc_get_extern_function_decl): Special case for resolving INDEX.

2019-12-30  Thomas Koenig  

PR fortran/91541
* gfortran.dg/index_3.f90: New test.


Added:
trunk/gcc/testsuite/gfortran.dg/index_3.f90
Modified:
trunk/gcc/fortran/ChangeLog
trunk/gcc/fortran/intrinsic.c
trunk/gcc/fortran/intrinsic.h
trunk/gcc/fortran/iresolve.c
trunk/gcc/fortran/trans-decl.c
trunk/gcc/testsuite/ChangeLog

[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken

2019-08-27 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541

--- Comment #10 from Jonathan Wakely  ---
I don't think it's possible to construct an example where this would misbehave.

If allocator_traits::is_always_equal is true for X then it implies that
operator== will return true for all values of X, **and also** for any values of
Y that are constructed from values of X.

Even if allocator_traits::is_always_equal is actually false (because some
values of Y can compare non-equal), **for the specific values we care about**
(i.e. ones constructed by copying an X), operator== will always return true.
That means we don't need to reallocate, and so no exceptions are possible.

What really matters is whether we need to reallocate, **not** whether
allocator_traits::is_always_equal is true or not. As long as we don't
reallocate, we won't get exceptions, and so we won't try to throw from a
noexcept function.

So you're worrying about nothing and wasting your time and mine.

[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken

2019-08-27 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541

Jonathan Wakely  changed:

   What|Removed |Added

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

--- Comment #9 from Jonathan Wakely  ---
(In reply to frankhb1989 from comment #8)
> bool operator==(const Y& a1, const Y& a2) noexcept
> {
>   return  == 

No, this is not allowed.

A copy of an allocator must compare equal to the original, so for "X u(a);" it
holds that "u == a". And a rebound copy of an allocator must also compare
equal, so for "X u(b);" it holds that "Y(u) == b && u == X(b)".

You're trying harder and harder to show a problem, and I simply don't believe
this can ever be a problem in real code. Any valid example you can construct
will be something completely stupid that I don't care about supporting because
we have far more important things to worry about.

[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken

2019-08-27 Thread frankhb1989 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541

--- Comment #8 from frankhb1989 at gmail dot com ---
(In reply to frankhb1989 from comment #5)
> (In reply to Jonathan Wakely from comment #4)
> > This might strictly conform to the requirements, but it's stupid. Why would
> > you do that?
> > 
> > Allocator equality doesn't care about the value type, as evidenced by the
> > requirement that a==b is equivalent to a==Y::rebind::other(b). So if the
> > result of == doesn't care about the value type, then why would
> > is_always_equal depend on it?
> 
> ..., and it actually throws on
> comparison, then ... .
> 

... My bad. I should have meant that it might throw when the result of the
result of == for node_allocator is `false`. This is even more stupid: `a ==
Y::rebind::other(b)` does not effectively imply that two values of type
`Y::rebind::other` will always be equal, even that there are requirements of
"reflexive, symmetric, and transitive" on "a1 == a2", consistent false negative
results are not prevented because such requirements are not also forced on "a
== b", so such definitions are allowed:

bool operator==(const X&, const X&) noexcept
{
return true;
}

bool operator==(const Y& a1, const Y& a2) noexcept
{
return  == 
}

bool operator==(const X& a, const Y& b) noexcept
{
return a == Y::rebind::other(b);
}

bool operator==(const Y& b, const X& a) noexcept
{
return b == Y::rebind::other(a);
}

where `T` is the container `value_type` equivalent to `value_type` of allocator
type `X` and `U` is the container node type equivalent `value_type` of
allocator type `Y`.

[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken

2019-08-27 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541

--- Comment #7 from Jonathan Wakely  ---
I can't believe that this has ever caused a real problem, or ever will cause a
real problem.

[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken

2019-08-27 Thread frankhb1989 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541

--- Comment #6 from frankhb1989 at gmail dot com ---
(In reply to frankhb1989 from comment #5)
> 
> And the noexcept exceptions provided in the current implementations are
> really inconsistent, for instance, between move operator= of std::list and
> std::map. Whether the fix above is adopted, at least one container
> implementation in libstdc++ is not conforming.
> 

Correction: if the additional requirement is adopted, there will be no need to
modify libstdc++ code for conformance. The inconsistency will remain literally
(`_Node_alloc_traits::_S_nothrow_move()` in the std::list vs. implicit
`_Alloc_traits::_S_nothrow_move() ...` implied by _Rb_tree), though.

[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken

2019-08-27 Thread frankhb1989 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541

--- Comment #5 from frankhb1989 at gmail dot com ---
(In reply to Jonathan Wakely from comment #4)
> This might strictly conform to the requirements, but it's stupid. Why would
> you do that?
> 
> Allocator equality doesn't care about the value type, as evidenced by the
> requirement that a==b is equivalent to a==Y::rebind::other(b). So if the
> result of == doesn't care about the value type, then why would
> is_always_equal depend on it?

Because I find no standard rules to prevent such stupid things. With such
cases, the container implementations are potentially broken: if the node
allocator is not is_always_true nor POCCA, and it actually throws on
comparison, then the noexcept specification will cause the program terminate.
This is quite counterintuitive, and I don't see this is intended anyway.

Probably the easiest resolution is to add one more requirement of invariant on
is_always_equal in the standard to ensure that each rebind result will keep
is_always_equal unchanged. This is likely to be a DR as is_always_equal has
been explicitly used as the part of noexcept specifications of containers'
operator= in the standard, and I don't see the way to fix it merely for
individual node-based container implementations. (Not sure traits like POCCA
need the additional requirement, though.)

And the noexcept exceptions provided in the current implementations are really
inconsistent, for instance, between move operator= of std::list and std::map.
Whether the fix above is adopted, at least one container implementation in
libstdc++ is not conforming.

Allocator-extended move constructors are similarly broken despite the explicit
noexcept specifications required in the standard. However, if it is resolved by
the fix in the standard, the implementation can remain unchanged.

[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken

2019-08-26 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541

--- Comment #4 from Jonathan Wakely  ---
This might strictly conform to the requirements, but it's stupid. Why would you
do that?

Allocator equality doesn't care about the value type, as evidenced by the
requirement that a==b is equivalent to a==Y::rebind::other(b). So if the
result of == doesn't care about the value type, then why would is_always_equal
depend on it?

[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken

2019-08-26 Thread frankhb1989 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541

--- Comment #3 from frankhb1989 at gmail dot com ---
(In reply to Jonathan Wakely from comment #2)
> (In reply to frankhb1989 from comment #0)
> 
> This type does not meet the allocator requirements. For a valid allocator,
> A::rebind::other must be the same type as A, and
> A::rebind::other::rebind::other must also be the same type
> as A.

Oops, I missed those requirements. How about this?

#include 
#include 
#include 

using P = std::pair;

template
struct AT
{
using value_type = T;

template
struct rebind
{
using other = AT;
};

using is_always_equal = std::is_same;

template
AT(const AT&);

T* allocate(std::size_t);

void deallocatoe(T*, std::size_t);
};

using A = AT;

int main()
{
static_assert(std::is_same_v::other,
A>);
// For any U:
using U = int;
static_assert(std::is_same_v::other::template
rebind::other, A>);
using always_equal = std::allocator_traits::is_always_equal;
using C = std::less<>;
constexpr bool std_nothrow = always_equal::value &&
std::is_nothrow_move_assignable_v;
static_assert(std_nothrow);
static_assert(!(std_nothrow &&
!std::is_nothrow_move_assignable>::value));
}

[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken

2019-08-26 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541

--- Comment #2 from Jonathan Wakely  ---
(In reply to frankhb1989 from comment #0)
> Case:
> 
> #include 
> #include 
> #include 
> #include 
> 
> struct A : std::allocator>
> {
>   template
>   struct rebind
>   {
>   using other = std::pmr::polymorphic_allocator;

This type does not meet the allocator requirements. For a valid allocator,
A::rebind::other must be the same type as A, and
A::rebind::other::rebind::other must also be the same type as
A.

[Bug libstdc++/91541] [C++17] Exception specification of operator= of node-based containers may be broken

2019-08-25 Thread frankhb1989 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541

--- Comment #1 from frankhb1989 at gmail dot com ---
Allocator-extended constructors with explicit exception specifications may also
have the value_type/node mismatch problems.