[Bug c++/114986] New: Seemingly incorrect "ignoring packed attribute" warning

2024-05-08 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114986

Bug ID: 114986
   Summary: Seemingly incorrect "ignoring packed attribute"
warning
   Product: gcc
   Version: 14.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pdimov at gmail dot com
  Target Milestone: ---

The following program
```
#include 
#include 

struct uuid
{
std::uint8_t data[ 16 ] = {};
};

struct __attribute__((packed)) X
{
uuid a;
unsigned char b;
unsigned c;
unsigned char d;
};

static_assert( offsetof(X, c) == 17 );
static_assert( sizeof(X) == 22 );
```
(https://godbolt.org/z/WvxjM3eqn)

gives
```
:11:10: warning: ignoring packed attribute because of unpacked non-POD
field 'uuid X::a'
```

However, the attribute is applied, because the static assertions pass.

If `__attribute__((packed))` is removed, the assertions (correctly) fail
(https://godbolt.org/z/hP4oG98fq).

Therefore, the warning seems wrong.

GCC 14, 13, 12 warn; 11 and earlier do not.

[Bug libstdc++/114865] [13/14/15 Regression] std::atomic::compare_exchange_strong seems to hang under GCC 13 for C++11

2024-05-02 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114865

--- Comment #19 from Peter Dimov  ---
This should work.

I still don't understand why JF so insisted on all these padding shenanigans.

[Bug libstdc++/114865] [13/14/15 Regression] std::atomic::compare_exchange_strong seems to hang under GCC 13 for C++11

2024-04-26 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114865

--- Comment #13 from Peter Dimov  ---
(In reply to Andrew Pinski from comment #10)
> #if __cplusplus >= 201402L && __has_builtin(__builtin_clear_padding)
> if _GLIBCXX17_CONSTEXPR (__atomic_impl::__maybe_has_padding<_Tp>())
>   __builtin_clear_padding(std::__addressof(_M_i));
> #endif
> 
> So yes it is definitely dependent on C++ level ...
> That is for C++14+ it is working correctly.

Oh, that's the constructor of `atomic`. I thought it was the compiler
initializing the padding in C++14 and above.

I wonder why `__cplusplus >= 201402L` is here.

[Bug libstdc++/114865] [13/14/15 Regression] std::atomic::compare_exchange_strong seems to hang under GCC 13 for C++11

2024-04-26 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114865

--- Comment #11 from Peter Dimov  ---
So, basically, C++14 and above initialize the padding of

```
std::atomic state{{ 0, 0x }};
```

in `main` to zero, which masks the problem in `generate`. (The problem in
`generate` still exists because the assembly is identical - it just doesn't
trigger because the padding is zero. If we manually poke something nonzero into
the padding, it would (ought to) still break.)

Static variables work for the same reason - the padding is guaranteed zero.

[Bug libstdc++/114865] [13/14/15 Regression] std::atomic::compare_exchange_strong seems to hang under GCC 13 on Ubuntu 23.04

2024-04-26 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114865

--- Comment #9 from Peter Dimov  ---
Oh, my mistake. C++14 does mov QWORD, and C++11 does mov WORD.

[Bug libstdc++/114865] [13/14/15 Regression] std::atomic::compare_exchange_strong seems to hang under GCC 13 on Ubuntu 23.04

2024-04-26 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114865

--- Comment #8 from Peter Dimov  ---
(In reply to Andrew Pinski from comment #6)
> No it is dependent on the standard level. C++11 fails but C++14, C++17 and
> C++20 all pass.

That's interesting because I see basically no difference in the generated code
on CE between 11 and 14:

--- "C++-x86-64 gcc 13.2-1 (1).asm" 2024-04-27 03:25:11.149385400 +0300
+++ "C++-x86-64 gcc 13.2-1.asm" 2024-04-27 03:24:59.207244400 +0300
@@ -76,10 +76,11 @@
 jmp .L8
 main:
 pushrbx
+mov eax, 8738
 mov ebx, 1024
 sub rsp, 16
 mov QWORD PTR [rsp], 0
-mov QWORD PTR [rsp+8], 8738
+mov WORD PTR [rsp+8], ax
 .L14:
 mov rdi, rsp
 callgenerate(std::atomic*)

(https://godbolt.org/z/nexn5W4Ph)

[Bug libstdc++/114865] [13/14/15 Regression] std::atomic::compare_exchange_strong seems to hang under GCC 13 on Ubuntu 23.04

2024-04-26 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114865

--- Comment #4 from Peter Dimov  ---
This

https://raw.githubusercontent.com/boostorg/uuid/feature/gcc_pr_114865/test/test_gcc_pr114865.cpp

exhibits the problem for me on GCC 13/14. I'm only seeing the hang with
-std=c++11 -m32 in the CI run because this combination is tested first, but I
believe it's independent of standard level and address model.

[Bug libstdc++/114865] std::atomic::compare_exchange_strong seems to hang under GCC 13 on Ubuntu 23.04

2024-04-26 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114865

--- Comment #2 from Peter Dimov  ---
The issue is also present for GCC 14 on Ubuntu 24.04:

https://github.com/boostorg/uuid/actions/runs/8853249656/job/24313667955

[Bug libstdc++/114865] std::atomic::compare_exchange_strong seems to hang under GCC 13 on Ubuntu 23.04

2024-04-26 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114865

--- Comment #1 from Peter Dimov  ---
> The problem may well be inside libatomic, of course; I have no way to tell.

Narrator: but he did, in fact, have a way to tell.

This is a GHA run with GCC 9 to 13 tested on both Ubuntu 23.04 and Ubuntu
23.10, and only GCC 13 hangs.

https://github.com/boostorg/uuid/actions/runs/8852038822/job/24309866206

And indeed, the codegen from GCC 12 (https://godbolt.org/z/xc7oT76fn) is
radically different from (and much simpler than) the GCC 13 one
(https://godbolt.org/z/eP48xv3Mr).

I think that the problem has been introduced with this commit:

https://github.com/gcc-mirror/gcc/commit/157236dbd621644b3cec50b6cf38811959f3e78c

which, ironically enough, was supposed to improve the handling of types with
padding bits, but broke them entirely.

(I told the committee there was nothing wrong with compare_exchange as
specified, but did they listen to me? To ask the question is to answer it.)

[Bug libstdc++/114865] New: std::atomic::compare_exchange_strong seems to hang under GCC 13 on Ubuntu 23.04

2024-04-26 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114865

Bug ID: 114865
   Summary: std::atomic::compare_exchange_strong seems to hang
under GCC 13 on Ubuntu 23.04
   Product: gcc
   Version: 13.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pdimov at gmail dot com
  Target Milestone: ---

I'm getting weird hangs on Github Actions when using
`std::atomic::compare_exchange_strong` under GCC 13 on Ubuntu 23.04
(only; GCC 12 and earlier on Ubuntu 22.04 and earlier work). `state_type` is
defined as

```
struct state_type
{
std::uint64_t timestamp;
std::uint16_t clock_seq;
};
```

and the code doing the CAS is

```
auto oldst = ps_->load( std::memory_order_relaxed );

for( ;; )
{
auto newst = get_new_state( oldst );

if( ps_->compare_exchange_strong( oldst, newst, std::memory_order_relaxed,
std::memory_order_relaxed ) )
{
state_ = newst;
break;
}
}
```

where `ps` is of type `std::atomic*`.

At a glance, I see nothing immediately wrong with the generated code
(https://godbolt.org/z/8Ee3hrTz8).

However, when I change `state_type` to

```
struct state_type
{
std::uint64_t timestamp;
std::uint16_t clock_seq;
std::uint16_t padding[ 3 ];
};
```
the hangs disappear. This leads me to think that the problem is caused by the
original struct having padding, which isn't being handled correctly for some
reason.

As we know, `std::atomic::compare_exchange_strong` is carefully specified to
take and return `expected` by reference, such that it can both compare the
entire object as if via `memcmp` (including the padding), and return it as if
by `memcpy`, again including the padding. Even though the padding bits of the
initial value returned by the atomic load are unspecified, at most one
iteration of the loop would be required for the padding bits to converge and
for the CAS to succeed.

However, going by the symptoms alone, this doesn't seem to be the case here.

The problem may well be inside libatomic, of course; I have no way to tell.

One GHA run showing the issue is
https://github.com/boostorg/uuid/actions/runs/8821753835, where only the GCC 13
job times out.

[Bug c++/113256] New: False -Wdangling-reference positive

2024-01-06 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113256

Bug ID: 113256
   Summary: False -Wdangling-reference positive
   Product: gcc
   Version: 13.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pdimov at gmail dot com
  Target Milestone: ---

The following code
```
#include 
#include 

template auto bind( M T::* pm, A a )
{
return [=]( auto&& x ) -> M const& { return x.*pm; };
}

template struct arg {};

arg<1> _1;

int main()
{
std::pair pair;
int const& x = bind( &std::pair::first, _1 )( pair );
assert( &x == &pair.first );
}
```
(https://godbolt.org/z/a555MMTqo)

(reduced from a Boost.Bind test case)

causes

```
:16:16: warning: possibly dangling reference to a temporary
[-Wdangling-reference]
   16 | int const& x = bind( &std::pair::first, _1 )( pair );
  |^
```

with GCC 13.2 (but not trunk).

There are indeed two temporaries created in that full expression, but `int
const&` can't possibly bind to any of them.

[Bug libstdc++/113200] std::char_traits::move is not constexpr when the argument is a string literal

2024-01-02 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113200

--- Comment #4 from Peter Dimov  ---
I didn't notice your subsequent comment, sorry. :-)

[Bug libstdc++/113200] std::char_traits::move is not constexpr when the argument is a string literal

2024-01-02 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113200

--- Comment #3 from Peter Dimov  ---
I think that the compiler is correct; string literal address comparisons aren't
constant expressions. Clang gives the same error:
https://godbolt.org/z/xPWEf4z63.

[Bug libstdc++/113200] New: std::char_traits::move is not constexpr when the argument is a string literal

2024-01-02 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113200

Bug ID: 113200
   Summary: std::char_traits::move is not constexpr when the
argument is a string literal
   Product: gcc
   Version: 13.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pdimov at gmail dot com
  Target Milestone: ---

```
#include 
#include 

template struct S
{
char data_[ N ];

using traits_type = std::char_traits;

constexpr S( char const* p ): data_{}
{
std::size_t n = traits_type::length( p );

assert( n < N );

traits_type::move( data_, p, n + 1 );
}
};

template S( char const(&)[N] ) -> S;

constexpr S s( "test" );
```
(https://godbolt.org/z/PofY8MP6G)

fails with

```
In file included from
/opt/compiler-explorer/gcc-trunk-20240102/include/c++/14.0.0/string:42,
 from :1:
:22:23:   in 'constexpr' expansion of 'S<5>(((const char*)"test"))'
:16:26:   in 'constexpr' expansion of
'std::char_traits::move(((char*)(&((S<5>*)this)->S<5>::data_)), p, (n +
1))'
/opt/compiler-explorer/gcc-trunk-20240102/include/c++/14.0.0/bits/char_traits.h:423:50:
  in 'constexpr' expansion of '__gnu_cxx::char_traits::move(__s1, __s2,
__n)'
/opt/compiler-explorer/gcc-trunk-20240102/include/c++/14.0.0/bits/char_traits.h:230:20:
error: '(((const __gnu_cxx::char_traits::char_type*)(& s.S<5>::data_)) ==
((const char*)"test"))' is not a constant expression
  230 |   if (__s1 == __s2) // unlikely, but saves a lot of work
  |   ~^~~
```

(Reduced from a similar failure in Boost.StaticString.)

[Bug libstdc++/113099] locale without RTTI uses dynamic_cast before gcc 13.2 or has ODR violation since gcc 13.2

2023-12-24 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113099

--- Comment #10 from Peter Dimov  ---
Maybe the right thing to do is to use dynamic_cast only for virtual inheritance
(either have a trait or check whether static_cast isn't a valid expression),
otherwise static_cast, in both cases (standard and user-defined Facet.)

[Bug libstdc++/113099] locale without RTTI uses dynamic_cast before gcc 13.2 or has ODR violation since gcc 13.2

2023-12-24 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113099

--- Comment #7 from Peter Dimov  ---
You don't necessarily need dynamic_cast because facets are always installed and
obtained by their exact type, not via a reference to base. You can store the
Facet* as given (like shared_ptr does), and return it.

The only reason dynamic_cast is needed here is because you can't static_cast
from facet* to Facet* when virtual inheritance. But you are not required to
store facet* in the actual container; you can store the original Facet* as
void*.

[Bug c++/86355] [10 Regression] Internal compiler error with pack expansion and fold expression

2023-07-07 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86355

--- Comment #14 from Peter Dimov  ---
Should I open another bug for the failure to compile the original example?

[Bug c++/110476] constexpr floating point regression with -std=c++XX

2023-06-29 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110476

--- Comment #2 from Peter Dimov  ---
Discussion of FLT_EVAL_METHOD notwithstanding, I think that this behavior is
not allowed by https://eel.is/c++draft/lex.fcon#3.

"If the scaled value is not in the range of representable values for its type,
the program is ill-formed. Otherwise, the value of a floating-point-literal is
the scaled value if representable, else the larger or smaller representable
value nearest the scaled value, chosen in an implementation-defined manner."

I don't see any license here for the value of 3.14f to be 3.14L.

[Bug c++/110477] -fexcess-precision=standard not applied consistently

2023-06-29 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110477

--- Comment #8 from Peter Dimov  ---
As I commented on the duplicate bug, I don't think this behavior is allowed by
https://eel.is/c++draft/lex.fcon#3.

"If the scaled value is not in the range of representable values for its type,
the program is ill-formed. Otherwise, the value of a floating-point-literal is
the scaled value if representable, else the larger or smaller representable
value nearest the scaled value, chosen in an implementation-defined manner."

I don't see any license here for the value of 3.14f to be 3.14L.

[Bug target/108742] Incorrect constant folding with (or exposed by) -fexcess-precision=standard

2023-06-29 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108742

--- Comment #13 from Peter Dimov  ---
I think that https://eel.is/c++draft/lex.fcon#3 disagrees.

"If the scaled value is not in the range of representable values for its type,
the program is ill-formed. Otherwise, the value of a floating-point-literal is
the scaled value if representable, else the larger or smaller representable
value nearest the scaled value, chosen in an implementation-defined manner."

I don't see any license here for the value of 3.14f to be 3.14L.

[Bug c++/110477] -fexcess-precision=standard not applied consistently

2023-06-29 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110477

--- Comment #6 from Peter Dimov  ---
I suppose this is unfixable because there's all sorts of code assuming that the
value of (long double)3.14 is 3.14L and not (long double)(double)3.14L.

I doubt that anyone sane expects this from (long double)3.14F, but it's not
feasible to change one but not the other.

Bafflings will continue until morale improves.

[Bug c++/110477] -fexcess-precision=standard not applied consistently

2023-06-29 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110477

--- Comment #3 from Peter Dimov  ---
That's true, but the normal expectation of anyone using
-fexcess-precision=standard would be for it to apply consistently everywhere
(that is, as if FLT_EVAL_METHOD is 0.)

Of course given that FLT_EVAL_METHOD is in a header, so unaffected by -f
options, it's not clear what can be done here.

[Bug c++/110476] constexpr floating point regression with -std=c++XX

2023-06-29 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110476

--- Comment #1 from Peter Dimov  ---
As discussed in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108742, this is a
consequence of applying the FLT_EVAL_METHOD=2 rules, and can be fixed by
casting 3.14f to (float).

That's... incredibly surprising, though. 3.14f is already a float.

For context, I encountered this regression in the Boost.Variant2 test suite
when I added GCC 13 to CI.

[Bug c++/110477] -fexcess-precision=standard not applied consistently

2023-06-29 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110477

--- Comment #1 from Peter Dimov  ---
Looks like a duplicate of https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108742
and is fixed by casting the rhs to (float), but any ordinary programmer would
be baffled.

For context, I encountered this regression in the Boost.Variant2 test suite
when I added GCC 13 to CI.

[Bug c++/110477] New: -fexcess-precision=standard not applied consistently

2023-06-29 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110477

Bug ID: 110477
   Summary: -fexcess-precision=standard not applied consistently
   Product: gcc
   Version: 13.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pdimov at gmail dot com
  Target Milestone: ---

The following program

float f( float x, int y )
{
return x + y;
}

int main()
{
return f( 3.14f, 1 ) == 3.14f + 1;
}

returns different values with -std=c++XX (https://godbolt.org/z/8dK98ondM) and
-std=gnu++XX (https://godbolt.org/z/4Y4qfsKzM) under GCC 13/14 -m32, because
-fexcess-precision=standard is not consistently applied to both sides of the
comparison. Under -fexcess-precision=fast (and hence under previous GCC
versions), the comparison always succeeds because both sides use excess
precision (https://godbolt.org/z/dzdoxdnM9).

This is the runtime equivalent of
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110476.

[Bug c++/110476] New: constexpr floating point regression with -std=c++XX

2023-06-28 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110476

Bug ID: 110476
   Summary: constexpr floating point regression with -std=c++XX
   Product: gcc
   Version: 13.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pdimov at gmail dot com
  Target Milestone: ---

The following program

#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)

struct X
{
float f;
};

int main()
{
constexpr X x{ 3.14f };
STATIC_ASSERT( x.f == 3.14f );
}

fails under GCC 13/14 with

: In function 'int main()':
:11:24: error: static assertion failed: x.f == 3.14f
   11 | STATIC_ASSERT( x.f == 3.14f );
  |^~~~
:1:42: note: in definition of macro 'STATIC_ASSERT'
1 | #define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
  |  ^~~
:11:24: note: the comparison reduces to '(3.1410490417480469e+0l ==
3.141e+0l)'
   11 | STATIC_ASSERT( x.f == 3.14f );
  |^~~~

when compiled with -m32 -std=c++XX under x86 (https://godbolt.org/z/Ghs7j5Teq).
The reason is that -std=c++XX implies -fexcess-precision=standard
(https://godbolt.org/z/zx4rn4j5W).

Previous versions worked fine.

[Bug target/110096] Would be nice if __builtin_ia32_pause had a portable equivalent as it's applicable to ARM

2023-06-02 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110096

--- Comment #13 from Peter Dimov  ---
Even if we assume that WFE on lock (and SEV on unlock) is the correct approach
on ARM instead of YIELD (though this seems very much domain-specific, depending
on the expected amount of contention and who knows what else), isn't the
existence of pause/yield instructions on MIPS, POWER, and apparently RISC-V (*)
enough further evidence in favor of having a portable intrinsic for emitting
such an instruction?

(*) https://doc.rust-lang.org/src/core/hint.rs.html#178-191 (implementation of
https://doc.rust-lang.org/std/hint/fn.spin_loop.html)

[Bug target/110096] Would be nice if __builtin_ia32_pause had a portable equivalent as it's applicable to ARM

2023-06-02 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110096

--- Comment #9 from Peter Dimov  ---
I don't think I want WFE here, based on what I read about it. Putting the core
to sleep seems like something to do in an embedded system where I have full
control of what cores do, not something to do on the application level, in a
portable C++ library.

[Bug target/110096] Would be nice if __builtin_ia32_pause had a portable equivalent as it's applicable to ARM

2023-06-02 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110096

--- Comment #7 from Peter Dimov  ---
These intrinsics are typically used in spinlocks as in
```
while( flag_.test_and_set() )
{
// issue a power-saving NOP here
}
```
(where `flag_` is `std::atomic_flag`) and this use is generic and not
target-dependent.

[Bug target/110096] Would be nice if __builtin_ia32_pause had a portable equivalent as it's applicable to ARM

2023-06-02 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110096

--- Comment #5 from Peter Dimov  ---
This works for the specific case of ARM, even though I don't find it
substantially better than just using `asm("yield")`, but the benefit of having
a portable intrinsic for this functionality is that as such instructions are
added to targets and GCC gains support of them (as has happened with ARM), code
would automatically take advantage of them, without having to acquire new
ifdefs for each supported target.

[Bug target/110096] Would be nice if __builtin_ia32_pause had a portable equivalent as it's applicable to ARM

2023-06-02 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110096

--- Comment #3 from Peter Dimov  ---
How does the user know when to include `arm_acle.h`?

[Bug target/110096] New: Would be nice if __builtin_ia32_pause had a portable equivalent as it's applicable to ARM

2023-06-02 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110096

Bug ID: 110096
   Summary: Would be nice if __builtin_ia32_pause had a portable
equivalent as it's applicable to ARM
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pdimov at gmail dot com
  Target Milestone: ---

This is more of a feature request than a bug.

Currently `__builtin_ia32_pause()` only applies to Intel/AMD CPUs (hence the
`ia32` in the name), but it has a straightforward and equivalent meaning for
ARM (issue a YIELD instruction, which is the exact ARM equivalent to the PAUSE
x86 one.)

This forces us to do things like

```
#if __has_builtin(__builtin_ia32_pause)

__builtin_ia32_pause();

#elif defined(__GNUC__) && ( (defined(__ARM_ARCH) && __ARM_ARCH >= 8) ||
defined(__ARM_ARCH_8A__) || defined(__aarch64__) )

__asm__ __volatile__( "yield" : : : "memory" );

// ...
```

(E.g.
https://github.com/boostorg/core/blob/3b96d237c0e3ada30c9beca0f60062a2576dcafd/include/boost/core/detail/sp_thread_pause.hpp)

This can be solved in one of two ways; one, extend `__builtin_ia32_pause` to do
the right thing for ARM - unprincipled because of ia32 in the name, but will
automagically "fix" all code using `#if __has_builtin(__builtin_ia32_pause)`.

Or two, add a portable spelling for the intrinsic, either `__builtin_pause()`
or `__builtin_yield()`.

(Failing that, an ARM-specific `__builtin_arm_yield()` would still be an
improvement over the above because it at least will allow us to not hardcode
the ARM target detection, which we are probably getting wrong.)

[Bug c++/109985] New: __builtin_prefetch ignored by GCC 12/13

2023-05-26 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109985

Bug ID: 109985
   Summary: __builtin_prefetch ignored by GCC 12/13
   Product: gcc
   Version: 13.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pdimov at gmail dot com
  Target Milestone: ---

We are investigating a Boost.Unordered performance regression with GCC 12,
on the following benchmark:

https://github.com/boostorg/boost_unordered_benchmarks/blob/4c717baac1bff8d3e51cb8485b72bbb63d533265/scattered_lookup.cpp

and it looks like the reason is that GCC 12 (and 13) ignore a call to
`__builtin_prefetch`.

While GCC 11 generates this:

```
.L108:
mov r8, r12
movdqa  xmm0, xmm1
sal r8, 4
lea r14, [r10+r8]
pcmpeqb xmm0, XMMWORD PTR [r14]
pmovmskbedx, xmm0
and edx, 32767
je  .L104
sub r8, r12
sal r8, 4
add r8, QWORD PTR [rbx+32]
prefetcht0  [r8]
.L106:
xor r15d, r15d
rep bsf r15d, edx
movsx   r15, r15d
sal r15, 4
add r15, r8
cmp rsi, QWORD PTR [r15]
jne .L144
add r9, QWORD PTR [r15+8]
mov rax, rdi
cmp r11, rdi
jne .L145
```
(https://godbolt.org/z/d663fdM16 - prefetcht0 [r8] right before L106)

GCC 12 generates this in the same function:
```
.L108:
mov r8, r10
movdqa  xmm0, xmm1
sal r8, 4
lea r9, [rbp+0+r8]
pcmpeqb xmm0, XMMWORD PTR [r9]
pmovmskbedx, xmm0
and edx, 32767
je  .L104
mov rdi, QWORD PTR [rsp+16]
sub r8, r10
mov QWORD PTR [rsp+24], rax
sal r8, 4
mov rdi, QWORD PTR [rdi+32]
mov QWORD PTR [rsp+8], rdi
mov rax, rdi
.L106:
xor edi, edi
rep bsf edi, edx
movsx   rdi, edi
sal rdi, 4
add rdi, r8
add rdi, rax
cmp r11, QWORD PTR [rdi]
jne .L143
add rsi, 8
add rbx, QWORD PTR [rdi+8]
cmp r12, rsi
jne .L109
```
(https://godbolt.org/z/T7csq7TPz - no prefetcht0 instruction before L106)

Simplifying this code unfortunately leads to the prefetcht0 being generated.

[Bug libstdc++/108952] Regression in uses_allocator_construction_args for pair of rvalue references

2023-02-27 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108952

Peter Dimov  changed:

   What|Removed |Added

 CC||pdimov at gmail dot com

--- Comment #4 from Peter Dimov  ---
An easy fix is to use `std::get<0>` instead of `.first`.

[Bug libstdc++/108836] std::mutex disappears in single-threaded libstdc++ builds

2023-02-17 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108836

--- Comment #4 from Peter Dimov  ---
A compromise between no mutex at all, and a mutex that is silently a no-op,
could be a no-op mutex with [[deprecated]] members, although the atomic_flag is
probably better.

[Bug libstdc++/108836] std::mutex disappears in single-threaded libstdc++ builds

2023-02-17 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108836

--- Comment #2 from Peter Dimov  ---
That's good to hear, but I don't think the issue is specific to mingw32. The
other report, https://github.com/boostorg/system/issues/92, was about "B&R
PLC", whatever this means. :-)

[Bug libstdc++/108836] New: std::mutex disappears in single-threaded libstdc++ builds

2023-02-17 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108836

Bug ID: 108836
   Summary: std::mutex disappears in single-threaded libstdc++
builds
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pdimov at gmail dot com
  Target Milestone: ---

We've been getting reports in Boost that our uses of  and std::mutex
don't work in a single-threaded build of libstdc++, so we had to add
configuration macros to avoid these issues. One example is
https://github.com/boostorg/system/commit/53c00841fc0d892bf43cda60e3ea2f05c4362b32,
another https://github.com/boostorg/url/issues/684.

Is there a reason not to make std::mutex available in single threaded builds,
with its operations being no-ops?

[Bug c++/100157] Support `__type_pack_element` like Clang

2022-11-29 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100157

Peter Dimov  changed:

   What|Removed |Added

 CC||pdimov at gmail dot com

--- Comment #11 from Peter Dimov  ---
Just import mp11 wholesale and use mp_at_c and mp_find :-)

[Bug target/107590] __atomic_test_and_set broken on PowerPC

2022-11-10 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107590

--- Comment #9 from Peter Dimov  ---
The easiest way to reproduce the issue is with the following test:

https://github.com/boostorg/smart_ptr/blob/c577d68b0272fd0bddc88ea60a8db07219391589/test/spinlock_test.cpp

This crashes because - presumably - sp2 is on an odd address.

The definition of the spinlock class is here:

https://github.com/boostorg/smart_ptr/blob/c577d68b0272fd0bddc88ea60a8db07219391589/include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp

[Bug target/107590] __atomic_test_and_set broken on PowerPC

2022-11-10 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107590

Peter Dimov  changed:

   What|Removed |Added

 CC||pdimov at gmail dot com

--- Comment #7 from Peter Dimov  ---
The spinlock is indeed using an `unsigned char`:

https://github.com/boostorg/smart_ptr/blob/c577d68b0272fd0bddc88ea60a8db07219391589/include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp#L33

That's because `__atomic_test_and_set` is documented to work on either `bool`
or `char`:

https://gcc.gnu.org/onlinedocs/gcc/extensions-to-the-c-language-family/built-in-functions-for-memory-model-aware-atomic-operations.html#_CPPv421__atomic_test_and_setPvi

"bool __atomic_test_and_set(void *ptr, int memorder)

This built-in function performs an atomic test-and-set operation on the byte at
*ptr. The byte is set to some implementation defined nonzero ‘set’ value and
the return value is true if and only if the previous contents were ‘set’. It
should be only used for operands of type bool or char. For other types only
part of the value may be set."

I don't see an alignment requirement being mentioned here.

[Bug tree-optimization/105545] [12/13 Regression] Warning for string assignment with _GLIBCXX_ASSERTIONS since r12-3347-g8af8abfbbace49e6

2022-11-03 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105545

--- Comment #9 from Peter Dimov  ---
My Godbolt link above no longer reproduces the warning because of
https://github.com/boostorg/describe/commit/c8c46bfdf78022a8a7e9e06983d8b04ccb921991,
but this one does: https://godbolt.org/z/oT1M31osa.

Looks like trunk has fixed the issue, though: https://godbolt.org/z/1GGvYWxKG.

[Bug tree-optimization/105545] [12/13 Regression] Warning for string assignment with _GLIBCXX_ASSERTIONS since r12-3347-g8af8abfbbace49e6

2022-06-21 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105545

Peter Dimov  changed:

   What|Removed |Added

 CC||pdimov at gmail dot com

--- Comment #7 from Peter Dimov  ---
FWIW, I'm getting this warning in one of the Boost.Describe examples
(https://godbolt.org/z/WKMjeTdne) from innocent-looking code that concatenates
std::strings with op+.

[Bug target/105992] New: memcmp(p, q, 7) == 0 can be optimized better on x86

2022-06-15 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105992

Bug ID: 105992
   Summary: memcmp(p, q, 7) == 0 can be optimized better on x86
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pdimov at gmail dot com
  Target Milestone: ---

bool eq( char const* p )
{
return __builtin_memcmp( p, "literal", 7 ) == 0;
}

generates

eq(char const*):
cmp DWORD PTR [rdi], 1702127980
je  .L6
.L2:
mov eax, 1
testeax, eax
seteal
ret
.L6:
xor eax, eax
cmp DWORD PTR [rdi+3], 1818325605
jne .L2
testeax, eax
seteal
ret

(https://godbolt.org/z/68MKqGz9T)

but LLVM does

eq(char const*):   # @eq(char const*)
mov eax, 1702127980
xor eax, dword ptr [rdi]
mov ecx, 1818325605
xor ecx, dword ptr [rdi + 3]
or  ecx, eax
seteal
ret

(https://godbolt.org/z/jxcb85Ysa)

There are similar bugs for ARM
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104611) and AVX512
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104610) but I haven't found one
for vanilla x86.

Recent changes to std::string::operator== make it use the above pattern:
https://godbolt.org/z/8KxqqG9cx

[Bug c++/102168] -Wnon-virtual-dtor shouldn't fire for protected dtor in a class with a friend declaration

2022-06-06 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102168

--- Comment #6 from Peter Dimov  ---
Yes, I suppose you're right. The warning warns that Derived _can be_ deleted
via Base*, and that's correct - if not very useful in practice in this specific
case.

In fact the private destructor case is even less useful. ~Derived won't compile
unless it's Derived that is Base's friend, in which case everything is actually
fine.

I suppose we'll have to live with it. The annoying part is that there's no
warning, and then you add an unrelated friend declaration while refactoring,
and the warning appears.

[Bug c++/102168] -Wnon-virtual-dtor shouldn't fire for protected dtor in a class with a friend declaration

2022-06-06 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102168

--- Comment #4 from Peter Dimov  ---
Warning on a private destructor + a friend declaration makes sense, because a
private destructor implies that the type is not intended to be derived from.
But warning on a protected destructor + a friend does not.

[Bug c++/102168] -Wnon-virtual-dtor shouldn't fire for protected dtor in a class with a friend declaration

2022-06-02 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102168

Peter Dimov  changed:

   What|Removed |Added

 CC||pdimov at gmail dot com

--- Comment #1 from Peter Dimov  ---
An issue against Boost.System has just been filed as a result of this warning:
https://github.com/boostorg/system/issues/83

It took me a while to figure out why the warning fires: because of the `friend
class error_code` declaration in `error_category`
(https://godbolt.org/z/z6x14P7M4).

Please reconsider issuing the warning when the destructor is protected and a
friend declaration exists. A protected destructor is a clear indication that
the type is intended as a base class.

[Bug c++/105482] New: Regression with `>=` in a template argument

2022-05-04 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105482

Bug ID: 105482
   Summary: Regression with `>=` in a template argument
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pdimov at gmail dot com
  Target Milestone: ---

The current GCC trunk in C++11 or C++14 mode gives an error when including
boost/mp11/algorithm.hpp (from Boost 1.79):

opt/compiler-explorer/libs/boost_1_79_0/boost/mp11/algorithm.hpp:445:102:
error: '>=' should be '> =' to terminate a template argument list
  445 | struct mp_take_c_impl, typename std::enable_if= 10>::type>
  |
 ^~
  |
 > =
/opt/compiler-explorer/libs/boost_1_79_0/boost/mp11/algorithm.hpp:445:107:
error: template argument 3 is invalid
  445 | struct mp_take_c_impl, typename std::enable_if= 10>::type>
  |
  ^
/opt/compiler-explorer/libs/boost_1_79_0/boost/mp11/algorithm.hpp:445:114:
error: expected unqualified-id before '>' token
  445 | struct mp_take_c_impl, typename std::enable_if= 10>::type>
  |
 ^

See e.g. https://godbolt.org/z/nE9754and and
https://github.com/boostorg/mp11/issues/73.

GCC 11 works, as does trunk in C++17 mode or later.

[Bug libstdc++/104945] New: std::hash ignores the top 32 bits when size_t is 32 bit

2022-03-15 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104945

Bug ID: 104945
   Summary: std::hash ignores the top 32 bits when
size_t is 32 bit
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pdimov at gmail dot com
  Target Milestone: ---

A benchmark in Boost.Unordered uses uint64_t keys of the form `i << 40`:

https://github.com/boostorg/unordered/blob/33f81fd49039bccd1aa3dfd5a29ef6073b93009c/benchmark/uint64.cpp#L65

which leads to pathological behavior with std::unordered_map in 32 bit mode,
because std::hash ignores the top 32 bits:

https://godbolt.org/z/PncKbT7aq

I'm not entirely sure whether this would be considered a bug, but decided that
it's worth reporting. Ideally, std::hash ought to take into account all bits of
the integral input, instead of truncating it to size_t.

[Bug c++/104867] New: Base class matching ignores type of `auto` template parameter

2022-03-10 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104867

Bug ID: 104867
   Summary: Base class matching ignores type of `auto` template
parameter
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pdimov at gmail dot com
  Target Milestone: ---

The following program

```
enum class Foo
{
A1
};

enum class Bar
{
B1
};

template  struct enum_
{
};

template struct list {};

struct enum_type_map: list, int>, list, double>
{};

template V f( list, V> const& )
{
return {};
}

int main()
{
f( enum_type_map() );
}
```

yields

```
: In function 'int main()':
:26:6: error: no matching function for call to 'f(enum_type_map)'
   26 | f( enum_type_map() );
  | ~^~~
:19:21: note: candidate: 'template V f(const
list, V>&)'
   19 | template V f( list, V> const& )
  | ^
:19:21: note:   template argument deduction/substitution failed:
:26:6: note:   'const list, V>' is an ambiguous base
class of 'enum_type_map'
   26 | f( enum_type_map() );
  | ~^~~
```

which is caused by `A1` and `B1` having the same value 0, even though their
types differ. (https://godbolt.org/z/3854zrY7x)

Clang successfully compiles the code (https://godbolt.org/z/eKEdf1zdo).

This is a distilled version of a bug report against `mp_map_find` from Mp11:
https://github.com/boostorg/mp11/issues/72

[Bug c++/104426] -fsanitize=undefined causes constexpr failures

2022-02-07 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104426

--- Comment #4 from Peter Dimov  ---
FWIW, I agree with everything Martin Sebor says in PR71962.
-fallow-address-zero is an entirely separate feature, and shouldn't be implied
by -fsanitize=undefined.

[Bug c++/104426] New: -fsanitize=undefined causes constexpr failures

2022-02-07 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104426

Bug ID: 104426
   Summary: -fsanitize=undefined causes constexpr failures
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pdimov at gmail dot com
  Target Milestone: ---

The following program

```
struct category
{
constexpr bool failed() const noexcept
{
return true;
}
};

inline constexpr category s_cat;

struct condition
{
category const* cat_;

constexpr bool failed() const noexcept
{
if( cat_ )
{
return cat_->failed();
}
else
{
return false;
}
}
};

int main()
{
constexpr condition cond{ &s_cat };
static_assert( cond.failed() );
}
```

compiles without -fsanitize=undefined (https://godbolt.org/z/Pn9M5ocfz), but
fails with it (https://godbolt.org/z/KKc8Tb9qe) with

```
: In function 'int main()':
:31:31: error: non-constant condition for static assertion
   31 | static_assert( cond.failed() );
  |~~~^~
:31:31:   in 'constexpr' expansion of 'cond.condition::failed()'
:17:13: error: '((& s_cat) != 0)' is not a constant expression
   17 | if( cat_ )
  | ^~~~
```

This happens under all GCC versions starting from 7.

(The above is an extract from the test suite for
boost::system::error_condition.)

[Bug c++/102651] New: typeid(X**) instantiates X

2021-10-08 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102651

Bug ID: 102651
   Summary: typeid(X**) instantiates X
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pdimov at gmail dot com
  Target Milestone: ---

Using f.ex. `typeid(std:pair**)` tries to instantiate
`std::pair` and fails: https://godbolt.org/z/GhbYe3P8j

(One asterisk should be enough, but doesn't work either.)

The example without pair is

```
#include 

template 
struct S{
T x;
};

void foo()
{
typeid( S** );
}
```

https://godbolt.org/z/nG3Kr3Te7

Interestingly, if `S` is incomplete, it works:

```
#include 

template 
struct S;

void foo()
{
typeid( S** );
}
```

https://godbolt.org/z/nK8b5n1qn

[Bug libstdc++/102425] New: std::error_code() does not compare equal to std::error_condition()

2021-09-21 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102425

Bug ID: 102425
   Summary: std::error_code() does not compare equal to
std::error_condition()
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pdimov at gmail dot com
  Target Milestone: ---

As the title says. https://godbolt.org/z/er7qsjvoo.

[Bug c++/102350] __builtin_source_location not available in earlier language modes

2021-09-16 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102350

--- Comment #18 from Peter Dimov  ---
I would use it like this: https://godbolt.org/z/1eqEx6678

#include 

struct error_category
{
};

error_category const& system_category();

struct error_code
{
error_code( int v, error_category const& cat, void const* loc =
__builtin_source_location() );
};

int main()
{
error_code ec( 5, system_category() );
}

provided, of course, I have some not-undefined way to interpret its result.

[Bug c++/102350] __builtin_source_location not available in earlier language modes

2021-09-16 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102350

--- Comment #16 from Peter Dimov  ---
(In reply to Jakub Jelinek from comment #14)
> But we haven't done that that way and how would headers know if the
> __builtin_source_location that is available is the old or new one?

The header could do

namespace std {

  struct __source_location_impl { ... };

  class source_location {

using __impl = __source_location_impl;

// ...

  };
}

unless the compiler looks specifically for a nested struct, in which case

  class source_location {

struct __impl: __source_location_impl {};

// ...

  };

[Bug c++/102350] __builtin_source_location not available in earlier language modes

2021-09-16 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102350

--- Comment #15 from Peter Dimov  ---
(In reply to Jonathan Wakely from comment #13)
> It wouldn't work correctly in all cases, as Jakub points out, because
> std::source_location::current() is part of the magic.
> 
> And I'm not convinced we want/need to support those uses.

I think that users of __builtin_source_location will be content with the subset
of uses it supports. :-)

[Bug c++/102350] __builtin_source_location not available in earlier language modes

2021-09-16 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102350

--- Comment #10 from Peter Dimov  ---
(In reply to Jakub Jelinek from comment #9)
> That would be an aliasing violation.
> The artificial vars created by __builtin_source_location have the
> std::source_location::__impl type, so accessing those using some other
> dynamic type is invalid.

In that case, the only valid way to use the result of __builtin_source_location
would just be std::source_location itself. :-/

I wonder whether there's a conformance problem in making it available. It's
true that the identifier `source_location` isn't reserved, but only programs
that include `` can tell the difference, and these programs
(assuming they existed and worked) will probably be broken anyway because now
they'll be including the standard header instead of their own.

[Bug c++/102350] __builtin_source_location not available in earlier language modes

2021-09-16 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102350

--- Comment #8 from Peter Dimov  ---
(In reply to Jakub Jelinek from comment #6)
> Note, having the struct somewhere else isn't that useful unless you know
> exactly how its non-static data members are named and what they mean, so
> ideally a class with accessor methods, which is what std::source_location
> provides currently.

I was going to undefined-behavior my way to victory by making
boost::source_location layout-compatible with the internal struct, and just
casting the result of __builtin_source_location to boost::source_location
const*. I think this works under the GCC object model?

[Bug c++/102350] __builtin_source_location not available in earlier language modes

2021-09-16 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102350

--- Comment #7 from Peter Dimov  ---
(In reply to Jonathan Wakely from comment #5)
> Sure. It's just a question of whether we're trying to provide a general
> purpose extension available for users, or an internal helper for the
> std::lib. IIRC we explicitly decided we only cared about supporting the
> latter.

Yes, of course. It's just that __builtin_source_location is so painfully close
to exactly what I want - it gives a single pointer representing the location -
that it would be a pity not being able to use it without -std=c++20.

[Bug c++/102350] __builtin_source_location not available in earlier language modes

2021-09-15 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102350

--- Comment #4 from Peter Dimov  ---
On the surface this looks not hard to fix - use ::__source_location_impl (or
std::__source_location_impl) instead of std::source_location:__impl as the
layout struct - but I'm not sure whether this would pose some further problems.

[Bug c++/102350] __builtin_source_location not available in earlier language modes

2021-09-15 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102350

--- Comment #2 from Peter Dimov  ---
(In reply to Jakub Jelinek from comment #1)
> __builtin_source_location doesn't require -std=c++20, but indeed does
> require  or some compatible definition of
> std::source_location::__impl class, and as it doesn't have hardcoded layout
> of that structure but instead matches whatever the source header provides
> (looks up fields it needs in there and uses whatever types and layout they
> have), there is no way around that.

That was my guess. I suppose that's inevitable then, and there's nothing to ask
for on the compiler side,  just needs to not disable itself
completely for pre-C++20 as it does now. (It's not going to work, but it can
still provide __impl so that the builtin can see it.)

[Bug c++/102350] New: __builtin_source_location not available in earlier language modes

2021-09-15 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102350

Bug ID: 102350
   Summary: __builtin_source_location not available in earlier
language modes
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pdimov at gmail dot com
  Target Milestone: ---

Currently, `__builtin_source_location` requires (a) `` to be
included and (b) -std=c++20. Are there good reasons for these restrictions? The
builtin would still be extremely valuable in earlier language modes.

Libraries that still support 03/11/14/17 (Boost.System, for instance) could
transparently supply source locations by using a default `void const* loc =
__builtin_source_location()` argument.

[Bug c++/100827] Compiler crash with Boost.Bimap and Boost.Xpressive

2021-05-29 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100827

--- Comment #1 from Peter Dimov  ---
Update: GCC 10.2 doesn't have the issue, but 10.1 and 10.3 do. :-)

[Bug c++/100827] New: Compiler crash with Boost.Bimap and Boost.Xpressive

2021-05-29 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100827

Bug ID: 100827
   Summary: Compiler crash with Boost.Bimap and Boost.Xpressive
   Product: gcc
   Version: 11.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pdimov at gmail dot com
  Target Milestone: ---

I'm seeing a compiler crash with g++ 10/11 in -std=c++03 mode

https://godbolt.org/z/h4dY9oKGc
https://godbolt.org/z/o1P6nrhqG

when compiling one file from the Boost.Bimap test suite:

```
#include 

#include 

#include 

#include 
#include 

using namespace boost::bimaps;
using namespace boost::xpressive;
namespace xp = boost::xpressive;

int main()
{
//[ code_bimap_and_boost_xpressive

typedef bimap< std::string, int > bm_type;
bm_type bm;

std::string rel_str("one <--> 1 two <--> 2  three <--> 3");

sregex rel = ( (s1= +_w) >> " <--> " >> (s2= +_d) )
[
xp::ref(bm)->*insert( xp::construct(s1,
as(s2)) )
];

sregex relations = rel >> *(+_s >> rel);

regex_match(rel_str, relations);

assert( bm.size() == 3 );
//]

return 0;
}
```
(https://github.com/boostorg/bimap/blob/03bf1d222914d0c15563414f2e51b6a4ce0e0f69/example/bimap_and_boost/xpressive.cpp)

Trunk no longer has the issue, and neither do earlier versions or language
modes.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94938 looks related, but is
considered fixed in GCC 10.

[Bug c++/99495] constexpr virtual destructor is used before its definition

2021-04-23 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99495

Peter Dimov  changed:

   What|Removed |Added

 CC||pdimov at gmail dot com

--- Comment #1 from Peter Dimov  ---
Simplified:

```
struct Base
{
constexpr virtual ~Base() = default;
};

constexpr Base b;
```

https://godbolt.org/z/qGn1nx9ET

[Bug tree-optimization/14721] jump optimization involving a sibling call within a jump table

2021-01-12 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=14721

Peter Dimov  changed:

   What|Removed |Added

 CC||pdimov at gmail dot com

--- Comment #5 from Peter Dimov  ---
It's becoming more common with the use of std::variant and compatible libraries
(such as Boost.Variant2.) https://godbolt.org/z/414e6j shows a reduced example.

[Bug c++/98649] New: Trivial jump table not eliminated

2021-01-12 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98649

Bug ID: 98649
   Summary: Trivial jump table not eliminated
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pdimov at gmail dot com
  Target Milestone: ---

Trivial jump tables where all entries are the same are sometimes not
eliminated. E.g. the following example

```
struct Base { virtual void run( float f ) = 0; };
struct T0: Base { void run( float f ); };
struct T1: Base { void run( float f ); };
struct T2: Base { void run( float f ); };
struct T3: Base { void run( float f ); };
struct T4: Base { void run( float f ); };

template struct mp_int {};

struct variant
{
unsigned index_;

union
{
T0 t0_;
T1 t1_;
T2 t2_;
T3 t3_;
T4 t4_;
};

T0& get( mp_int<0> ) { return t0_; }
T1& get( mp_int<1> ) { return t1_; }
T2& get( mp_int<2> ) { return t2_; }
T3& get( mp_int<3> ) { return t3_; }
T4& get( mp_int<4> ) { return t4_; }
};

template decltype(auto) get( variant& v )
{
return v.get( mp_int() );
}

void f1( variant& v, float f )
{
switch( v.index_ )
{
case 0: get<0>(v).run( f ); break;
case 1: get<1>(v).run( f ); break;
case 2: get<2>(v).run( f ); break;
case 3: get<3>(v).run( f ); break;
case 4: get<4>(v).run( f ); break;
default: __builtin_unreachable();
}
}

```

(https://godbolt.org/z/MxzGh8)

results in

```
f1(variant&, float):
mov eax, DWORD PTR [rdi]
lea r8, [rdi+8]
jmp [QWORD PTR .L4[0+rax*8]]
.L4:
.quad   .L3
.quad   .L3
.quad   .L3
.quad   .L3
.quad   .L3
.L3:
mov rax, QWORD PTR [rdi+8]
mov rdi, r8
mov rax, QWORD PTR [rax]
jmp rax
```

This case may seem contrived, but it's not that rare in practice, because code
using std::variant or equivalent (such as Boost.Variant2, from which the
example has been reduced) is becoming more and more common nowadays.

[Bug c++/63707] Brace initialization of array sometimes fails if no copy constructor

2021-01-12 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63707

Peter Dimov  changed:

   What|Removed |Added

 CC||pdimov at gmail dot com

--- Comment #14 from Peter Dimov  ---
FWIW, I just hit this problem as well when trying to make changes to
Boost.Variant2. My reduced test case is https://godbolt.org/z/zG6ddP; I was
going to submit that as a bug but found this one.

I support the petition to have this fixed.

[Bug c++/97464] New: Missed redundant store optimization opportunity

2020-10-16 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97464

Bug ID: 97464
   Summary: Missed redundant store optimization opportunity
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: pdimov at gmail dot com
  Target Milestone: ---

The code

void f( int& x, float& y )
{
++x;
y = 1;
--x;
}

compiles to

f(int&, float&):
mov eax, DWORD PTR [rdi]
mov DWORD PTR [rsi], 0x3f80
mov DWORD PTR [rdi], eax
ret

(https://godbolt.org/z/so4h3v)

but the load from, and the store to, [rdi] are redundant. It's obvious that
TBAA is active, but it for some reason doesn't go far enough.

This is a simplified example from "realer" code where x is a reference count
whose unnecessary manipulations could have been optimized out entirely.