[Bug libstdc++/88466] [C++17] Support std::hardware_destructive_interference_size and std:: hardware_constructive_interference_size

2020-03-18 Thread foom at fuhm dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88466

James Y Knight  changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #7 from James Y Knight  ---
FWIW, the discussion in Clang about this is still ongoing, and the functions
remain unimplemented there.

I personally remain of the opinion that it would be ideal to leave these
permanently unimplemented, despite that the standards committee decided to keep
them in the standard even after objections were raised.

My second-favorite implementation after "unimplemented", would be to just
return constant values of 64 and 128 universally, regardless of architecture.
(If you cannot return an actually-correct answer, and decided that you need to
return something, you might as well just do something really easy and, _shrug_,
oh well.).


Others are arguing for implementing them to return actually valid and correct
values that depend on the exact configuration, and marking them as not being
abi-stable. Users would then need to be aware that they must not use the
constants in ABIs (which means effectively "don't use in a header file"), since
the value might change at any time with a compiler upgrade, or with the use of
different command-line flags (e.g. -mcpu/-march).

(To return correct values, compiler upgrades must be allowed to change the
values if it becomes aware of a new CPU model which changes the
largest/smallest-known cacheline sizes that this code could run on. And
-mcpu/-march flags similarly ought to change the values by restricting the
possible set of CPUs this code might run on.)

Any new thoughts from GCC developers?

[Bug libstdc++/89855] Inconsistent global namespace overload sets from #include

2020-04-29 Thread foom at fuhm dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89855

--- Comment #6 from James Y Knight  ---
Someone has pointed out to me that the standard actually says "name", which I
had internalized as meaning "declaration", but it doesn't. This arguably does
make the GCC implementation non-compliant with the spec.


>From http://eel.is/c++draft/headers#5

> Except as noted in [library] through [thread] and [depr], the contents of 
> each header cname is the same as that of the corresponding header name.h as 
> specified in the C standard library. In the C++ standard library, however, 
> the declarations (except for names which are defined as macros in C) are 
> within namespace scope of the namespace std. It is unspecified whether these 
> names (including any overloads added in [support] through [thread] and 
> [depr]) are first declared within the global namespace scope and are then 
> injected into namespace std by explicit using-declarations.

I think that text implies that all of the overloads of a particular name must
consistently either be defined in the global namespace (and then imported into
std with a using-declaration) or defined in the std namespace.

[Bug libstdc++/89855] Inconsistent global namespace overload sets from #include

2020-04-29 Thread foom at fuhm dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89855

--- Comment #7 from James Y Knight  ---
Ugh, GCC doesn't wrap quoted text? Re-posting the quote from
http://eel.is/c++draft/headers#5 without a quote marker...

"""
Except as noted in [library] through [thread] and [depr], the contents of each
header cname is the same as that of the corresponding header name.h as
specified in the C standard library. In the C++ standard library, however, the
declarations (except for names which are defined as macros in C) are within
namespace scope of the namespace std. It is unspecified whether these names
(including any overloads added in [support] through [thread] and [depr]) are
first declared within the global namespace scope and are then injected into
namespace std by explicit using-declarations.
"""

[Bug target/95722] libatomic crashes on __atomic_load of const object

2020-06-17 Thread foom at fuhm dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95722

James Y Knight  changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #1 from James Y Knight  ---
The fix would be to have libatomic use a lock instead of the lock-free
cmpxchg16b instruction to implement atomic_load. But I think this is impossible
without causing incompatibility with older GCCs.

Older versions of GCC (before GCC 7), and Clang to this day, emitted cmpxchg16b
inline for a 16-byte atomic load when you compile with -mcx16.

And thus, unfortunately, I think if libatomic switched to a lock now, it would
not be compatible with those older programs.

[Bug libstdc++/54172] [4.7/4.8 Regression] __cxa_guard_acquire thread-safety issue

2012-08-29 Thread foom at fuhm dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54172

James Y Knight  changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #3 from James Y Knight  2012-08-30 02:39:31 
UTC ---
Ping; this seems like a serious regression in 4.7 with a patch.

I guess fixing it is blocked on Thiago posting the patch to gcc-patches?


[Bug libstdc++/54075] [4.7.1] unordered_map insert 3x slower than 4.6.2

2012-11-03 Thread foom at fuhm dot net


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54075



James Y Knight  changed:



   What|Removed |Added



 CC||foom at fuhm dot net



--- Comment #34 from James Y Knight  2012-11-04 04:55:30 
UTC ---

Well, I haven't looked into this issue in detail, but, it looks like everyone

is about the same speed if you put a foo.{reserve or rehash}(n) before the

inserts.



Unfortunately, it doesn't look as simple as the new impl calling for a rehash

more often than the old, cause it's not. So, I don't know if the slowness is

because rehash is now a lot slower, or if insert is slower but only if there

aren't a huge number of empty buckets.



I'll also note that libc++'s implementation (seen here:

http://llvm.org/svn/llvm-project/libcxx/trunk/) appears to be getting the same

speed as the old libstdc++ implementation, while appearing to have

approximately the same bucket datastructure as the new libstdc++

implementation. That says to me that it should be *possible* somehow to make

the new version fast.


[Bug c++/41863] New: [4.5 Regression] segfault with sizeof in template parameter

2009-10-28 Thread foom at fuhm dot net
GCC 4.5 appears to fail when using sizeof(member-of-templated-type) inside a
template parameter.

I have tested the Debian gcc-snapshot 20090923-1 amd64 package, 20091010-1
i386, and Ubuntu gcc-snapshot 20091018-1 amd64. All exhibit the same behavior.
g++-4.4 works fine, however.

Changing to "sizeof(m_foo)" to "sizeof(T)" also fixes the problem.

File /tmp/test.cpp:
===CUT===
template struct Bar {
};

template
class Foo {
T m_foo;
void crash() {
Bar bar;
}
};
===CUT===

$ g++ -c /tmp/test.cpp

/tmp/test.cpp: In member function 'void Foo::crash()':
/tmp/test.cpp:8:26: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See  for instructions.


-- 
   Summary: [4.5 Regression] segfault with sizeof in template
parameter
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: foom at fuhm dot net
  GCC host triplet: x86_64-linux-gnu
GCC target triplet: x86_64-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41863



[Bug middle-end/41290] [4.5 regression] C++ - libdirac don't want to compile

2009-10-29 Thread foom at fuhm dot net


--- Comment #5 from foom at fuhm dot net  2009-10-30 02:42 ---
An error very much like this is also causing a bunch of files in my program to
fail to compile with 4.5 with -O1 and above. I was unable to reduce a simple
test case from my (private) code, though: many changes that seem like they
should be unrelated cause the bug to go away. So I really hope my bug is
actually the same thing as this already-somewhat-reduced test case. :)

I'm using the ubuntu gcc-snapshot 20091018 package, on x86-64.

The error message is a little bit different, so I'm including it below, just in
case you might think it indicates a different underlying cause.

error: edge points to wrong declaration:
 >
QI
size 
unit size 
align 8 symtab 0 alias set -1 canonical type 0x2ab09e701240 method
basetype 
arg-types 
chain >>
pointer_to_this >
addressable used nothrow static in_system_header autoinline decl_5 QI
defer-output file
/usr/lib/gcc-snapshot/lib/gcc/x86_64-linux-gnu/4.5.0/../../../../include/c++/4.5.0/istream
line 798 col 7 align 16 context 
initial  abstract_origin 
arguments 
readonly unsigned DI
size 
unit size 
align 64 symtab -1364669056 alias set -1 canonical type
0x2ab09e6fdcc0>
readonly used unsigned DI file
/usr/lib/gcc-snapshot/lib/gcc/x86_64-linux-gnu/4.5.0/../../../../include/c++/4.5.0/istream
line 798 col 23 size  unit size 
align 64 context 
abstract_origin  arg-type >
result 
used ignored VOID file
/usr/lib/gcc-snapshot/lib/gcc/x86_64-linux-gnu/4.5.0/../../../../include/c++/4.5.0/istream
line 798 col 27
align 8 context 
abstract_origin >
full-name "std::basic_iostream<_CharT, _Traits>::~basic_iostream() [with
_CharT = char, _Traits = std::char_traits]"
pending-inline-info 0x2ab0ab72f000 template-info 0x2ab09e6faf90
struct-function 0x2ab0ab58f6e0>
 Instead of: >
QI
size 
unit size 
align 8 symtab 0 alias set -1 canonical type 0x2ab09e701240 method
basetype 
arg-types 
chain 
chain >>>
pointer_to_this >
addressable used nothrow public static external in_system_header autoinline
decl_5 QI defer-output file
/usr/lib/gcc-snapshot/lib/gcc/x86_64-linux-gnu/4.5.0/../../../../include/c++/4.5.0/istream
line 798 col 7 align 16 context 
initial  abstract_origin 
arguments 
readonly unsigned DI
size 
unit size 
align 64 symtab -1364669056 alias set -1 canonical type
0x2ab09e6fdcc0>
readonly unsigned DI file
/usr/lib/gcc-snapshot/lib/gcc/x86_64-linux-gnu/4.5.0/../../../../include/c++/4.5.0/istream
line 798 col 23 size  unit size 
align 64 context 
abstract_origin  arg-type 
chain 
readonly unsigned DI file
/usr/lib/gcc-snapshot/lib/gcc/x86_64-linux-gnu/4.5.0/../../../../include/c++/4.5.0/istream
line 798 col 7 size  unit size 
align 64 context 
abstract_origin  arg-type >>
result 
ignored VOID file
/usr/lib/gcc-snapshot/lib/gcc/x86_64-linux-gnu/4.5.0/../../../../include/c++/4.5.0/istream
line 798 col 27
align 8 context >
full-name "std::basic_iostream<_CharT, _Traits>::~basic_iostream() [with
_CharT = char, _Traits = std::char_traits]"
pending-inline-info 0x2ab0ab72f000 template-info 0x2ab09e6faf90
struct-function 0x2ab0ab71ed20 chain >


-- 

foom at fuhm dot net changed:

   What|Removed |Added
----------------
 CC||foom at fuhm dot net


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41290



[Bug c++/54170] Call to lambda elided

2013-07-09 Thread foom at fuhm dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54170

James Y Knight  changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #13 from James Y Knight  ---
Possibly should be backported to 4.7 branch?


[Bug libstdc++/49561] [C++0x] std::list::size complexity

2011-10-06 Thread foom at fuhm dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49561

foom at fuhm dot net changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #8 from foom at fuhm dot net 2011-10-07 01:26:28 UTC ---
This change seems like it might be the first major incompatibility added to
gcc's c++0x mode (at least, things appeared to work before, maybe that was just
luck).

I guess it will now be dangerous to even load a shared lib compiled with
--std=c++0x into the same executable as C++ code compiled in the default c++03
mode, because of the potential for the exported weak symbols from out-of-line
std::list functions compiled for one layout to be used on a structure defined
with the other layout in the other shared object. Even when no c++ objects are
ever passed from one shared lib to the other.

This seems like a particularly bad failure mode to have, especially considering
also bug 36022 (invalid), since it's by design difficult to *not* export the
symbols even if you try.

I understand that the versioned namespaces feature is supposed to help with
this sort of issue; is there any plan to use it to give the c++0x std::list
object a different mangled name than the c++03 std::list object?


[Bug c++/53356] New: ICE in verify_gimple_stmt, at tree-cfg.c:4258

2012-05-14 Thread foom at fuhm dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53356

 Bug #: 53356
   Summary: ICE in verify_gimple_stmt, at tree-cfg.c:4258
Classification: Unclassified
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: f...@fuhm.net


On the code:
test.cpp:
===
class A {};

struct B {
operator const A &() const;
};

A* cause_ICE() {
return new A(B());
}
===

Running: g++ -std=c++0x -c test.cpp
With gcc version: g++ (Debian 4.7.0-8) 4.7.0
(which says it's built from r187339 on the gcc 4.7 branch).
On architecture: x86-64

Crashes with error message:
test.cpp: In function ‘Foo* cause_ICE()’:
test.cpp:7:6: internal compiler error: in verify_gimple_stmt, at
tree-cfg.c:4258

Removing -std=c++0x makes it not crash. 4.6.3 does not crash.

This looks similar to bug 49996, (but obviously different, because that one is
still fixed).


[Bug c++/53364] New: [4.7/4.8 Regression] Wrong code generation

2012-05-15 Thread foom at fuhm dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53364

 Bug #: 53364
   Summary: [4.7/4.8 Regression] Wrong code generation
Classification: Unclassified
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: f...@fuhm.net


On the following code, minimized from a much larger program:

test.cpp
=
#include 

struct A
{
int m_x;

explicit A(int x) : m_x(x) {}
operator int() const { return m_x; }
};

struct B : public A
{
 public:
explicit B(int x)
: A(x) {}
};

int data = 1;

int main() {
B b = B(10);
b = std::min(b, B(data));
return int(b);
}
=

Running: g++ -O2 -c test.cpp
With gcc version: g++ (Debian 4.7.0-8) 4.7.0
(which says it's built from r187339 on the gcc 4.7 branch).
On architecture: x86-64

The program ought to return 1, but instead, it returns randomness. Running
valgrind confirms that this program is using uninitialized values.

Testing with the debian gcc-snapshot package (trunk rev 187013) shows the same
bug.
Testing with the debian gcc 4.6.3 package does not show the bug.
Using -O1 does not show the bug.
Using -O1 -fstrict-aliasing shows the bug.


[Bug c++/53364] [4.7/4.8 Regression] Wrong code generation

2012-05-15 Thread foom at fuhm dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53364

--- Comment #1 from foom at fuhm dot net 2012-05-16 04:10:59 UTC ---
Asm generated. Note that at no point is anything ever actually written to the
stack, only read from it:

 :
   0:83 3d 00 00 00 00 09 cmpl   $0x9,0x0(%rip)# 7 
   7:48 8d 44 24 e8   lea-0x18(%rsp),%rax
   c:48 8d 54 24 d8   lea-0x28(%rsp),%rdx
  11:48 0f 4f c2  cmovg  %rdx,%rax
  15:8b 00mov(%rax),%eax
  17:c3   retq   


Making what ought to be a no-op change to the program, using class "A" instead
of "B", thus:
int main() {
A a = A(10);
a = std::min(a, A(data));
return int(a);
}
causes the following, correctly working, asm to be generated. This is the same
output generated by adding "-fno-strict-aliasing" to the compile line for the
original program. See that it now does write values onto the stack locations
being read from.

(It also seems rather crazy to me that gcc doesn't optimize such a simple
program to use purely registers and no stack addresses, but I suppose that's a
different bug.)

 :
   0:8b 15 00 00 00 00mov0x0(%rip),%edx# 6 
   6:48 8d 44 24 e8   lea-0x18(%rsp),%rax
   b:48 8d 4c 24 d8   lea-0x28(%rsp),%rcx
  10:c7 44 24 d8 0a 00 00 movl   $0xa,-0x28(%rsp)
  17:00 
  18:83 fa 09 cmp$0x9,%edx
  1b:89 54 24 e8  mov%edx,-0x18(%rsp)
  1f:48 0f 4f c1  cmovg  %rcx,%rax
  23:8b 00mov(%rax),%eax
  25:c3   retq


[Bug c++/53364] [4.7/4.8 Regression] Wrong code generation

2012-05-15 Thread foom at fuhm dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53364

--- Comment #3 from foom at fuhm dot net 2012-05-16 04:28:21 UTC ---
> Does -fno-tree-vrp fix the issue?

Nope, "g++ -O2 -fno-tree-vrp -c test.cpp" is no different than without.


[Bug tree-optimization/61502] == comparison on "one-past" pointer gives wrong result

2018-05-03 Thread foom at fuhm dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61502

James Y Knight  changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #24 from James Y Knight  ---
FWIW, clang did consider this a bug and fixed it in
https://bugs.llvm.org/show_bug.cgi?id=21327.

[Bug target/86005] [RISCV] Invalid intermixing of __atomic_* libcalls and inline atomic instruction sequences

2018-05-31 Thread foom at fuhm dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86005

James Y Knight  changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #4 from James Y Knight  ---
I think if RISCV wants to use out-of-line lock-free atomic helpers, it should
give those another function name (for example,
__sync_fetch_and_##OP##_##WIDTH), and provide them in libgcc.a, the same as the
other architectures which use such out-of-line helpers.

(But also, why doesn't it implement __atomic_add_fetch inline?)

Since lock-free helper functions can be linked into a process as many times as
you like without correctness issues, it's safe, and preferable, to provide them
in the static runtime lib.

That is quite unlike a potentially-locking __atomic_* function, which must
share the same lock across the whole process, and thus must have only one
implementation in a process, which is why they're provided separately by
libatomic.so.

It's not a good idea to conflate the two different things.

[Bug target/86005] [RISCV] Invalid intermixing of __atomic_* libcalls and inline atomic instruction sequences

2018-06-01 Thread foom at fuhm dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86005

--- Comment #7 from James Y Knight  ---
(In reply to Jim Wilson from comment #6)
> On Thu, 2018-05-31 at 15:07 +0000, foom at fuhm dot net wrote:
> > (But also, why doesn't it implement __atomic_add_fetch inline?)
> 
> If you don't have atomic instructions, then we call an out-of-line
> function that uses locks.

Except as mentioned in the initial message, it doesn't emit calls for atomic
loads and stores too, but it needs to so that they also participate in the
locking.

> If you have atomic instructions, and it is a 32/64-bit operation, then
> we inline it.
> 
> If you have atomic instructions, and it is a 8/16-bit operation, then
> we call a lock free out-of-line function that uses a sequence of
> instructions to implement it using 32/64-bit atomic instructions.  

If you're building for rv32ia, yes, you certainly know that libatomic must
implement __atomic_fetch_add_1 lock-free. So, sure, you shouldn't have a
correctness issue by mixing the calls.

Yet even so, if you actually needed to emit a call to a known-lock-free
out-of-line function, it's better to give it a different name (e.g. __sync_*)
and include that in libgcc.a.

Emitting a call to the __atomic_* function means you require users to link
against libatomic.so, which shouldn't be required here.

> And
> as mentioned previously, I have an unfinished prototype patch to fix
> this by emitting the sequence of instructions inline.

But doing that is fine, too, and likely preferable.

[Bug target/86005] [RISCV] Invalid intermixing of __atomic_* libcalls and inline atomic instruction sequences

2018-06-12 Thread foom at fuhm dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86005

--- Comment #10 from James Y Knight  ---
I suppose since it doesn't affect most common platforms, nobody's noticed the
brokenness yet?

ARM is probably the most common architecture which is missing atomics on common
CPU models, but when targeting common OSes (Linux, FreeBSD), you get to use the
kernel atomic cmpxchg helpers, so the issue doesn't arise there.

I haven't tested, but I don't think MIPS16 would be broken, since MIPS has
native atomics, just not in the MIPS16 ISA. So, it calls out-of-line libgcc
__sync_* routines, implemented in MIPS32 and which use LL/SC instructions.
There's no problem mixing those with native load/store instructions.


Anyways, for why mixing native load/store with __atomic_* functions is wrong,
consider,
int value = 4;

Thread1:
int oldval = __atomic_fetch_add(&value, 1, __ATOMIC_SEQ_CST);

Thread2:
__atomic_store_n(&value, 0, __ATOMIC_SEQ_CST);

The only allowable results after executing both threads should be:
oldval = 0, value = 1 -- if atomic_store executes first.
oldval = 4, value = 0 -- if atomic_fetch_add executes first.

But, if you implement __atomic_fetch_add with a lock, and implement
__atomic_store with a native store instruction, you may get the "impossible"
result,
oldval = 4, value = 5 -- if atomic_store executes *during* atomic_fetch_add,
between the load and store instructions. Oops.

[Bug libstdc++/89855] New: Inconsistent global namespace overload sets from #include

2019-03-27 Thread foom at fuhm dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89855

Bug ID: 89855
   Summary: Inconsistent global namespace overload sets from
#include 
   Product: gcc
   Version: 9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: foom at fuhm dot net
  Target Milestone: ---

In the following, I use the function "log" as an example, but this applies to
effectively everything in cmath, and ::abs in cstdlib.

The C standard library  defines:
  double log(double);

libstdc++  includes libc , and then does:
  namespace std {
using ::log;
float log(float);
long double log(long double);
double log(Any-Integral-Type);
  }

libstdc++  does:
  #include 
  using std::log;


This has the unfortunate effect that code which includes  and uses
global ::log ends up accidentally calling the double overload of log. E.g., a
program like this:
  #include 
  float foo(float f) { return log(f); }

Granted, the above code is non-portable, and may not even compile on some other
standards-conforming implementation. I do not believe this is a
standards-compliance issue in libstdc++ -- the header  is permitted,
but not required to define ::log.

However, IMO, it's a *QoI* bug that libstdc++ doesn't provide consistent
overload sets. The problem is that the behavior of the above code _very subtly_
changes upon adding or removing an #include which transitively has an "#include
" in it. This can cause extremely surprising bugs.

I'd suggest that either #include  ought to define NO global ::log
function at all (thus, the above program fails to compile), or it should define
the entire overload set for ::log. No partial overload sets.

Since not defining ::log from cmath is effectively impossible, given the
current interfaces between libc and libstdc++, I think the latter is what
should be done. Concretely, that simply means moving all of the global
namespace "using std::log" (etc.) statements from libstdc++'s  into
libstdc++'s .


(I would also suggest that it'd be reasonable for a future C++ standard to
require that. E.g., it could say something like: While  may or may not
declare functions in ::std::, and  may or may not declare functions in
::, if they _do_ declare any such name, they must define the complete set of
required overloads, not a subset.)

[Bug c++/87521] [C++][ABI] Tail padding not reused for non POD struct with defaulted/deleted special member function as per Itanium ABI on x86-64

2018-11-15 Thread foom at fuhm dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87521

James Y Knight  changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #5 from James Y Knight  ---
Since it's effectively arbitrary whether to allow tail padding or not, and the
ABI doesn't actually say, it's not actually possible to say that gcc's behavior
is "correct".

The only way to actually resolve this is to fix the ABI to say what to do. It
already has an open issue: https://github.com/itanium-cxx-abi/cxx-abi/issues/66

(The current thinking there is to require GCC's current implementation, AIUI.)


Regarding comment #3: that doesn't prove anything -- it's entirely possible
(not indicative of a bug) for a struct to be both trivially_copyable and not
pod-for-layout.

Your test-case is not valid, per [basic.types] para 3 -- which requires that
the trivially_copyable type not be a base-class subobject in order for
memcpy'ing the bytes to be valid. (The Itanium ABI also notes this.)

And, for example, if you changed the code:
-struct Base {
+struct ReallyBase {};
+struct Base : public ReallyBase {

then GCC also "fails that test" -- Base is now unambiguously not POD-for-layout
since it has a base class, but it is still trivially_copyable.

[Bug c++/88115] New: Incorrect result from alignof in templates, if also using __alignof__.

2018-11-20 Thread foom at fuhm dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88115

Bug ID: 88115
   Summary: Incorrect result from alignof in templates, if also
using __alignof__.
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: foom at fuhm dot net
  Target Milestone: ---

On both GCC 8.2 and "trunk" on godbolt (https://godbolt.org/z/ykszUZ) given the
following program, compiled for x86 -m32, the final GCCAlignOf static assert
unexpectedly fails.

However, if you comment out the three StdAlignOf lines, the assert starts
passing. Or, if you swap the order such that GCCAlignOf comes first, then it
will pass, and the StdAlignOf assert fails, instead. 

It looks like some caching inside GCC is still treating alignof and __alignof
as the same thing, even though they now (since the fix for PR69560) are
supposed to have differing behavior.

Possibly this is due to both alignof and __alignof mangling to the same
character?

===
static_assert(alignof(double) == 4, "");
static_assert(__alignof__(double) == 8, "");

template
struct integral_constant
{
static constexpr _Tp value = __v;
};

template 
using StdAlignOf = integral_constant;

static_assert(StdAlignOf::value == 4, "");

template 
using GCCAlignOf = integral_constant;

static_assert(GCCAlignOf::value == 8, "");
===

[Bug libstdc++/88119] New: std::alignment_of returns wrong value (__alignof instead of alignof).

2018-11-20 Thread foom at fuhm dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88119

Bug ID: 88119
   Summary: std::alignment_of returns wrong value (__alignof
instead of alignof).
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: foom at fuhm dot net
  Target Milestone: ---

std::alignment_of is currently defined based on "__alignof__", but according to
the standard [meta.unary.prop.query], it should return the same result as
"alignof".

And as of PR69560, __alignof and alignof now return different values in some
circumstances.

Test case for x86 with -m32, the static assert fails, but it should pass.


#include 
static_assert(std::alignment_of::value == alignof(double), "");

[Bug c++/69560] x86_64: alignof(uint64_t) produces incorrect results with -m32

2018-11-20 Thread foom at fuhm dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560

James Y Knight  changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #24 from James Y Knight  ---
Note that I've filed PR88115 and PR88119 for some bugs caused by this change.

[Bug middle-end/41290] [4.5 regression] ICE: edge points to wrong declaration

2010-02-10 Thread foom at fuhm dot net


--- Comment #15 from foom at fuhm dot net  2010-02-10 23:24 ---
Nope, adding -fno-indirect-inlining has no effect.

I'm now using:
g++-4.5 (Debian 4.5-20100202-1) 4.5.0 20100202 (experimental) [trunk revision
156452]

Problem still occurs, -fno-ipa-cp still makes it go away.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41290



[Bug middle-end/41290] [4.5 regression] ICE: edge points to wrong declaration

2010-02-12 Thread foom at fuhm dot net


--- Comment #17 from foom at fuhm dot net  2010-02-12 21:46 ---
Thanks, I will try doing that.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41290



[Bug middle-end/41290] [4.5 regression] ICE: edge points to wrong declaration

2010-03-10 Thread foom at fuhm dot net


--- Comment #18 from foom at fuhm dot net  2010-03-10 20:32 ---
Sorry for the extreme delay in responding. I can confirm that applying that
patch on top of:
gcc-4.5 (Debian 4.5-20100227-1) 4.5.0 20100227 (experimental) [trunk revision
157109]
*does* make my issue go away, and my program compile correctly without
requiring the -fno-ipa-cp argument.

Thank you. 
Should this report be reopened for that patch to be applied? I don't have the
reopen option.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41290



[Bug c++/65945] C++ alignment of nullptr_t is 1 and might cause unaligned stores to the frame

2015-05-22 Thread foom at fuhm dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65945

James Y Knight  changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #9 from James Y Knight  ---
This also happens on Sparc. A test-case is really easy to make:

int foo(bool&&, decltype(nullptr)&&, bool&&);

void doit() {
  foo(false, nullptr, false);
}


save%sp, -104, %sp
stb %g0, [%fp-6]
  /* WTF unaligned store */
st  %g0, [%fp-5]
stb %g0, [%fp-1]
add %fp, -6, %g3
add %fp, -5, %g2
add %fp, -1, %g1
mov %g3, %o0
mov %g2, %o1
mov %g1, %o2
call_Z3fooObODnS_, 0
 nop
return  %i7+8
 nop

.ident  "GCC: (Debian 4.9.2-10) 4.9.2"


This breaks building recent versions of clang on Sparc, because it calls
emplace_back with nullptr, which results in an expression like the above.


[Bug target/46942] x86_64 parameter passing unnecessary sign/zero extends

2015-09-16 Thread foom at fuhm dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46942

James Y Knight  changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #10 from James Y Knight  ---
Well, the ABI doc doesn't appear to say anything about this still.

GCC as of 5.1 seems to still do sign/zero extension of 8/16-bit arguments to
32-bit on the callee side. Clang does not. Both do extension of 32-bit
arguments to 64-bit on the callee side.

Both sign/zero-extend 8/16-bit values to 32-bits, and do /not/ truncate 64-bit
values to 32-bit on the caller side.

So it looks like GCC could still generate more optimal code by taking advantage
of the "de-facto" ABI that lets you assume 32-bit sign/zero-extension has
happened on arguments.

But it'd also be real nice for this all to be actually documented, so there's
something to point people to. :)

BTW: This undocumentedness came up recently with an optimizer change in clang:
libjpeg-turbo has some assembly code which was using the full 64-bit value of
an argument register, assuming the upper bits would be zeroed, while on the C
side, the function was declared as taking an "int". The upper bits are thus
left undefined (as is correct, per the unwritten ABI rules), which broke the
asm.

https://github.com/libjpeg-turbo/libjpeg-turbo/pull/20
http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20150907/138253.html


[Bug c++/65945] C++ alignment of nullptr_t is 1 and might cause unaligned stores to the frame

2015-06-04 Thread foom at fuhm dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65945

--- Comment #11 from James Y Knight  ---
As far as I can tell, the C++ ABI discussion,
http://comments.gmane.org/gmane.comp.lang.c++.abi/265
concluded that alignof(nullptr_t) should be alignof(void*) already.

Any chance this change can be made and backported?


[Bug libstdc++/66438] New: libstdc++ 5.1 broke binary compat with old code using std::error_category

2015-06-05 Thread foom at fuhm dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66438

Bug ID: 66438
   Summary: libstdc++ 5.1 broke binary compat with old code using
std::error_category
   Product: gcc
   Version: 5.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: foom at fuhm dot net
  Target Milestone: ---

If you compile this program with GCC 4.9, but you have libstdc++ version 5.1
installed on your system. (E.g., this is the case for me because I'm using
Debian unstable).

#include 

int main() {
  std::error_code x = make_error_code(std::errc::no_such_file_or_directory);
  std::error_condition e = std::errc::no_such_file_or_directory;
  return x == e;
}


Then running it will return 0 instead of 1, like it should, (and did, with
libstdc++ 4.9 installed).

So, the thing to note, is that both "x" and "e" here have a category() of
_ZSt16generic_categoryv() as their category instance -- NOT
_ZNSt3_V216generic_categoryEv(), because it was built against the old headers.
(This seems to be as intended.)

Going through the calls, first we have this from
libstdc++-v3/include/std/system_error:

  inline bool
  operator==(const error_code& __lhs, const error_condition& __rhs) noexcept
  {
return (__lhs.category().equivalent(__lhs.value(), __rhs)
|| __rhs.category().equivalent(__lhs, __rhs.value()));
  }

which calls, from libstdc++-v3/src/c++11/compatibility-c++0x.cc:

  bool
  error_category::equivalent(int __i,
 const error_condition& __cond) const noexcept
  { return default_error_condition(__i) == __cond; }

which calls, from the same file:

  error_condition
  error_category::default_error_condition(int __i) const noexcept
  {
if (*this == system_category())
  return error_condition(__i, _V2::system_category());
return error_condition(__i, _V2::generic_category());
  }

which returns a _V2::generic_category() object. Oops. Now we're in big trouble!

Then, back to error_category::equivalent, where it calls, from
libstdc++-v3/include/std/system_error:

  inline bool
  operator==(const error_condition& __lhs,
 const error_condition& __rhs) noexcept
  {
return (__lhs.category() == __rhs.category()
&& __lhs.value() == __rhs.value());
  }

Which fails, because __lhs.category() is the V2 generic_category, and
__rhs.category() is the "V1" generic_category.


[Bug libstdc++/66438] libstdc++ 5.1 broke binary compat with old code using std::error_category

2015-06-06 Thread foom at fuhm dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66438

James Y Knight  changed:

   What|Removed |Added

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

--- Comment #5 from James Y Knight  ---
Sorry, please try again.

Andreas Schwab: I did compile it with the libstdc++ that came with the compiler
-- and then I upgraded the binary libstdc++.so to the newer one that came with
gcc 5. And it broken. Thus the report of breaking binary compat. (It also
happens with new compiles in Debian because of what Gianfranco says)

Andrew Pinski:

The *one and only purpose* of the file
libstdc++-v3/src/c++11/compatibility-c++0x.cc is to provide binary
compatibility for c++11 binaries compiled against older libstdc++ versions, and
now running against a newer one.

If libstdc++.so.6, version 5.1, is not supposed to work properly with c++
binaries compiled by the 4.9 compiler, it should not be providing these
compatibility symbols at all.

Since it does provide them, there is clearly intent to provide compatibility
so, it ought to work. Or they should be deleted...


[Bug libstdc++/66438] libstdc++ 5.1 broke binary compat with old code using std::error_category

2015-06-06 Thread foom at fuhm dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66438

--- Comment #9 from James Y Knight  ---
What good is having special code to allow linking compatibility, if the program
then can't work anyways? Isn't that anti-useful?

> I didn't realise you were the maintainer and knew what's supposed to work.

No, of course...I'm only a user

> If you can provide a patch

I'm not certain, but it seems like probably the old-ABI
error_category::default_error_condition(int) ought to just return an
error_condition also with the old ABI, instead of the new one?


CC'ing debian's gcc maintainer, because the stated lack of desire for
compatibility between libstdc++ version 5, and g++ 4.9 seems like it's probably
something he wasn't aware of when upgrading.


[Bug libstdc++/66438] libstdc++ 5.1 broke binary compat with old code using std::error_category

2015-06-06 Thread foom at fuhm dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66438

James Y Knight  changed:

   What|Removed |Added

 CC||doko at gcc dot gnu.org

--- Comment #10 from James Y Knight  ---
Oops, actually cc'ing doko this time (hopefully.)


[Bug c++/65945] C++ alignment of nullptr_t is 1 and might cause unaligned stores to the frame

2015-06-19 Thread foom at fuhm dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65945

--- Comment #12 from James Y Knight  ---
Since this would at least theoretically be a c++11 ABI change -- although it
seems likely not to impact the ABI of most actual software -- it seems like
it'd be a really good idea to fix it ASAP, before too many people start
depending on GCC 5.1's C++11 ABI.


[Bug middle-end/41290] [4.5 regression] ICE: edge points to wrong declaration

2010-01-11 Thread foom at fuhm dot net


--- Comment #13 from foom at fuhm dot net  2010-01-12 06:27 ---
The crash is still present for my code. I'm using:
g++ (Debian 20091228-2) 4.5.0 20091228 (experimental) [trunk revision 155486]
on AMD64.

Passing -fno-ipa-cp also makes the bug disappear for me. But apparently r154673
did not fix the underlying issue, only make it unreproducible with the test
case here. I can try again to minimize, but I'm not optimistic: this bug seems
to appear and disappear almost randomly with minor adjustments to the code, and
unfortunately I cannot post my complete code.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41290



[Bug c++/42797] New: call of overloaded 'allocator()' is ambiguous

2010-01-18 Thread foom at fuhm dot net
On Linux x86_64
g++ --version:
g++ (Debian 20100117-1) 4.5.0 20100117 (experimental) [trunk revision 155979]

Compiling with:
g++ -O2 -g -std=c++0x -c test.cpp

The following program:

#include 
#include 
struct Foo {
Foo() {}

template
Foo(Tp *p) {}
};

void foo() {
std::map > the_map;

the_map[1] = std::vector();
}

Produces the below error. However, it *doesn't* produce an error if compiled
without the -g switch (nor with -O1 instead of -O2).


In file included from /usr/include/c++/4.5.0/bits/move.h:38:0,
 from /usr/include/c++/4.5.0/bits/stl_pair.h:60,
 from /usr/include/c++/4.5.0/bits/stl_algobase.h:66,
 from /usr/include/c++/4.5.0/vector:61,
 from test.cpp:1:
/usr/include/c++/4.5.0/type_traits: In constructor 'std::vector<_Tp,
_Alloc>::vector(std::vector::size_type, const value_type&, const
allocator_type&) [with _Tp = Foo, _Alloc = std::allocator,
std::vector::size_type = long unsigned int, value_type = Foo, allocator_type =
std::allocator]':
/usr/include/c++/4.5.0/type_traits:224:67:   instantiated from 'const bool
std::__is_constructible_helper, const int&&>::__value'
/usr/include/c++/4.5.0/type_traits:235:5:   instantiated from
'std::is_constructible, const int&&>'
/usr/include/c++/4.5.0/bits/stl_map.h:451:11:   instantiated from here
/usr/include/c++/4.5.0/type_traits:224:67: error: call of overloaded
'allocator()' is ambiguous
/usr/include/c++/4.5.0/bits/allocator.h:103:7: note: candidates are:
std::allocator<_Tp>::allocator(const std::allocator<_Tp>&) [with _Tp = Foo,
std::allocator<_Tp> = std::allocator]
/usr/include/c++/4.5.0/bits/allocator.h:101:7: note:
std::allocator<_Tp>::allocator() [with _Tp = Foo]
/usr/include/c++/4.5.0/type_traits:224:67: error: call of overloaded
'allocator()' is ambiguous
/usr/include/c++/4.5.0/bits/allocator.h:103:7: note: candidates are:
std::allocator<_Tp>::allocator(const std::allocator<_Tp>&) [with _Tp = Foo,
std::allocator<_Tp> = std::allocator]
/usr/include/c++/4.5.0/bits/allocator.h:101:7: note:
std::allocator<_Tp>::allocator() [with _Tp = Foo]
/usr/include/c++/4.5.0/type_traits:218:2: error: call of overloaded
'allocator()' is ambiguous
/usr/include/c++/4.5.0/bits/allocator.h:103:7: note: candidates are:
std::allocator<_Tp>::allocator(const std::allocator<_Tp>&) [with _Tp = Foo,
std::allocator<_Tp> = std::allocator]
/usr/include/c++/4.5.0/bits/allocator.h:101:7: note:
std::allocator<_Tp>::allocator() [with _Tp = Foo]


-- 
   Summary: call of overloaded 'allocator()' is ambiguous
   Product: gcc
   Version: 4.5.0
    Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: foom at fuhm dot net


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42797



[Bug c++/42797] call of overloaded 'allocator()' is ambiguous

2010-01-18 Thread foom at fuhm dot net


--- Comment #1 from foom at fuhm dot net  2010-01-19 06:15 ---
Error also occurs with:
g++ -O1 -fipa-sra  -g -std=c++0x -c test.cpp


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42797



[Bug libstdc++/45060] New: Wreorder warning in bits/hashtable.h

2010-07-24 Thread foom at fuhm dot net
When compiling with -Wsystem-headers, I noticed:

/usr/include/c++/4.5/bits/hashtable.h:179:30: warning: 'std::_Hashtable, std::_Identity,
..., ..., std::__detail::_Mod_range_hashing,
std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy,
false, true, true>::_M_rehash_policy' will be initialized after [-Wreorder]

/usr/include/c++/4.5/bits/hashtable.h:176:30: warning:   'std::_Hashtable, std::_Identity,
..., ..., std::__detail::_Mod_range_hashing,
std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy,
false, true, true>::_Node** std::_Hashtable, std::_Identity, ..., ...,
std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash,
std::__detail::_Prime_rehash_policy, false, true, true>::_M_buckets'
[-Wreorder]

/usr/include/c++/4.5/bits/hashtable.h:646:5: warning:   when initialized here
[-Wreorder]


Moving the initialization of _M_buckets to before _M_bucket_count should fix
it. This is actually the *only* extra warning I got when compiling a large C++
codebase with -Wsystem-headers, which is great!


-- 
   Summary: Wreorder warning in bits/hashtable.h
   Product: gcc
   Version: 4.5.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: foom at fuhm dot net


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45060



[Bug c++/44487] New: pair of references doesn't work in c++0x mode

2010-06-09 Thread foom at fuhm dot net
This program doesn't compile with g++-4.5 -std=c++0x -c test.cpp

I'm using:
g++-4.5 (Debian 4.5.0-5) 4.5.1 20100602 (prerelease)

I also verified the same behavior on:
 g++ (Debian 20100530-1) 4.6.0 20100530 (experimental) [trunk revision 160047]

#include 

int x, y;
std::pair foo() {
std::pair blah(x, y);
return blah;
}

It says:
In file included from /usr/include/c++/4.5/utility:71:0,
 from /tmp/test.cpp:1:
/usr/include/c++/4.5/bits/stl_pair.h: In constructor ‘std::pair<_T1,
_T2>::pair(std::pair<_T1, _T2>&&) [with _T1 = int&, _T2 = int&, std::pair<_T1,
_T2> = std::pair]’:
/tmp/test.cpp:8:12:   instantiated from here
/usr/include/c++/4.5/bits/stl_pair.h:113:30: error: invalid initialization of
non-const reference of type ‘int&’ from an rvalue of type
‘std::remove_reference::type’
/usr/include/c++/4.5/bits/stl_pair.h:113:30: error: invalid initialization of
non-const reference of type ‘int&’ from an rvalue of type
‘std::remove_reference::type’


It works without -std=c++0x, and it seems like that ought to work in c++0x too.

Furthermore, this slightly modified program, making "blah" const (which I think
shouldn't make a difference, as it's the outermost qualifier of a local
variable) causes it to successfully compile:

#include 

int x, y;
std::pair foo() {
const std::pair blah(x, y);
return blah;
}


-- 
   Summary: pair of references doesn't work in c++0x mode
   Product: gcc
   Version: 4.5.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: foom at fuhm dot net


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44487



[Bug libstdc++/97449] New: libstdc++ cannot be compiled with clang after 3427e31331677ca826c5588c87924214f7e5c54b

2020-10-15 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97449

Bug ID: 97449
   Summary: libstdc++  cannot be compiled with clang
after 3427e31331677ca826c5588c87924214f7e5c54b
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: foom at fuhm dot net
  Target Milestone: ---

After 3427e31331677ca826c5588c87924214f7e5c54b, "clang -std=c++17" (using
libstdc++ headers), on a file that has simply "#include " fails with
this error:

In file included from :1:

/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/11.0.0/../../../../include/c++/11.0.0/variant:1032:10:
error: no matching constructor for initialization of 'std::__nonesuch'
return __nonesuch{};
   ^ ~~

/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/11.0.0/../../../../include/c++/11.0.0/type_traits:2953:5:
note: candidate constructor not viable: requires 1 argument, but 0 were
provided
__nonesuch(__nonesuch const&) = delete;
^

(https://godbolt.org/z/951jYr)

I believe Clang is correct to reject this code, due to
http://eel.is/c++draft/temp.res#general-8.1
"""
The program is ill-formed, no diagnostic required, if:
- no valid specialization can be generated for a template or a substatement of
a constexpr if statement within a template and the template is not instantiated
"""

The invalid return statement probably needs to be made dependent on
__visit_ret_type_mismatch just like the static_assert.

[Bug c++/88115] Incorrect result from alignof in templates, if also using __alignof__.

2020-11-14 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88115

--- Comment #6 from James Y Knight  ---
> c++: Change the mangling of __alignof__ [PR88115]

The new mangling chosen for __alignof__(type) seems problematic, and I think
this commit ought to be reverted until a new mangling scheme has been chosen.

At the very least, both __alignof__(expression) and __alignof__(type) can't
both be encoded as "v111__alignof__", with no indication of whether the
argument is a type or an expression, because that's ambiguous.

Possibly it'd be okay to use v112__alignof__z and v112__alignof__t, similar to
how "az" and "at" are used for standard alignof expression/type. That solves
the ambiguity. But -- this violates the generic grammar, which doesn't allow
for a vendor operator to take type arguments at all.
   ::= v  
   ::=  

Now...possibly it's okay to violate that and pass a type, regardless. But, then
the demangler needs to know what every vendor extension operator's semantics
are in order to demangle -- which seems against the intent of the standardized
"vendor operator" syntax. So, that's not great.

This seems like a problem which may be worth solving properly and generally in
the itanium ABI -- maybe now's the time to actually do this? (Fixing this would
allow __typeof__, __builtin_convertvector, and __builtin_offsetof to be
mangleable too...) See also PR13740 and PR11078, for earlier (MUCH earlier!)
discussion of possible mangling syntax extensions for this sort of thing.
Unfortunately, it never went anywhere...

ISTM that the most promising proposal in those earlier threads was to add a "Y"
to both type and expression expansions.

To support vendor-specific builtins which returns a type, and can take types or
expressions as arguments (e.g. typeof), add:
   ::= Y  + E

To support vendor-specific builtins which return a value, and can take types or
expressions as arguments (e.g. __builtin_offsetof, or __alignof__):
   ::= Y  + E

[Bug c++/88115] Incorrect result from alignof in templates, if also using __alignof__.

2020-11-16 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88115

--- Comment #7 from James Y Knight  ---
I've created an ABI proposal against itanium abi, here:
https://github.com/itanium-cxx-abi/cxx-abi/issues/112

I realized since writing my last comment here that
   ::= u  [] # vendor extended type
has been added a few months ago. Therefore, nothing needs to be added to
support extended expressions as .

And, therefore, since 'u' is also free in expression, I've proposed to simply
add the same 'u' syntax to "expression", rather than using "Y", as per previous
comment.

That is:
   ::= u  [] # vendor extended
expression

[Bug target/98495] New: X86 _mm_extract_pi16 incorrectly sign extends result

2020-12-31 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98495

Bug ID: 98495
   Summary: X86 _mm_extract_pi16 incorrectly sign extends result
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: foom at fuhm dot net
  Target Milestone: ---

#include 
int test(__m64 a) {
return _mm_extract_pi16 (a, 0);
}

Compiles to (x86_64 gcc, -O2):
pextrw  $0, %xmm0, %eax
cwtl
ret

Which results in the value being sign-extended from 16-bits to 32-bits.

The intel docs for PEXTRW state that the upper bits are zeroed, and state that
_mm_extract_pi16 is supposed to implement PEXTRW.

So, the expected result is no sign extension:
pextrw  $0, %xmm0, %eax
ret


I'd note that this is not a regression due to the new MMX with SSE2 changes --
GCC has had this bug as far back as I can see. It is currently present on trunk
both for the MMX and SSE2 implementations.

Both clang and MSVC zero-extend rather than sign-extend. And, for that matter,
GCC's _mm_extract_epi16 function _also_ zero-extends -- it was fixed in PR45336
for GCC 4.6.

[Bug target/98522] New: _mm_cvttps_pi32 and _mm_cvtps_pi32 raise spurious FP exceptions

2021-01-04 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98522

Bug ID: 98522
   Summary: _mm_cvttps_pi32 and _mm_cvtps_pi32 raise spurious FP
exceptions
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: foom at fuhm dot net
  Target Milestone: ---

This is a regression due to the MMX in SSE work in GCC10. As far as I can tell,
it affects only these two functions.

Example test, which should return 0, but instead throws SIGFPE:

#pragma stdc fenv_access

#define _GNU_SOURCE
#include 
#include 

__attribute__((noinline)) __m64 test(__m128 a) {
  return _mm_cvtt_ps2pi(a);
}

int main() {
  feenableexcept(FE_INVALID);
  __m128 x = (__m128)(__m128i){0xLL, 0x7fffLL};
  volatile __m64 y = test(x);
}


In GCC 10 and trunk, the function test is compiled to:
cvttps2dq   xmm0, xmm0
ret
which will convert the upper 64 bits as well as the lower 64 bits -- and
therefore raises FP exceptions accordingly. But, it ought to be ignoring the
upper 64bits.

[Bug c++/88115] Incorrect result from alignof in templates, if also using __alignof__.

2021-01-07 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88115

--- Comment #9 from James Y Knight  ---
Proposed patch posted for the itanium-cxx-abi:
 https://github.com/itanium-cxx-abi/cxx-abi/pull/115/files
using the syntax:
 u  * E

And to Clang, to use that syntax:
 https://reviews.llvm.org/D93922

I hope both GCC and Clang can do the same thing here.

[Bug c++/98804] New: GCC misparses template in pack expansion as comparison

2021-01-23 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98804

Bug ID: 98804
   Summary: GCC misparses template in pack expansion as comparison
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: foom at fuhm dot net
CC: richard-gccbugzilla at metafoo dot co.uk
  Target Milestone: ---

GCC parses the following program (by Richard Smith) as `g` less-than `a`
greater-than `(a)` instead of a call to the function `g` with template-args
`a`, and argument-list `(a)`. And thus, it fails to compile.

(Compile with -std=c++20)

struct X { constexpr X(int&) {} };
template void g(F);
template void g(int);
void g(...);

template auto h(A ...a)->decltype (g (0, g < a > (a) ...)) {
}

void test () {
  h(0);
}
-

I originally noticed this bug with the following test from Clang's test-suite,
while working on a mangling bug in Clang. In this original test-case, GCC does
successfully compile, but the mangling is weird, exposing that the same
misparse occurred.


namespace pr30440 {
template void g(F);

template auto h(A ...a)->decltype (g (0, g < a > (a) ...)) {
}
void pr30440_test () {
  h();
}
}


GCC mangles as:
_ZN7pr304401hIJEEEDTcl1gLi0Espgtlt1gfp_fp_EEDpT_
  
with greater/less operators in the mangling.

But it should've been:
_ZN7pr304401hIJEEEDTcl1gLi0Espcl1gIXfp_EEfp_EEEDpT_
  ^^^
with a template-arg.

[Bug c++/88115] Incorrect result from alignof in templates, if also using __alignof__.

2021-01-29 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88115

--- Comment #10 from James Y Knight  ---
Seeing as GCC is now in Stage 4 before the next release, I'd like to ping this
bug.

Should the priority be upgraded? I think fixing this so that GCC doesn't use
'v111__alignof__' should be considered a release-blocker: either the mangling
change should be reverted to the previous behavior, or fixed.

FWIW, the change to clang has been committed, and is planned to be in the
upcoming Clang 12 release
(https://reviews.llvm.org/rG9c7aeaebb3ac1b94200b59b111742cb6b8f090c2)

[Bug inline-asm/100953] Add memory clobbers just for reads or just for writes

2021-06-22 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100953

James Y Knight  changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #3 from James Y Knight  ---
For the compiler-barrier use-cases, you can use the __atomic_signal_fence
builtin instead of an empty inline-asm statement.

E.g. if you want to make sure that all writes apperaing after a barrier are
actually emitted after all reads/writes appearing before the barrier, use
__atomic_signal_fence(__ATOMIC_RELEASE).

[Bug libstdc++/104602] New: std::source_location::current uses cast from void*

2022-02-18 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104602

Bug ID: 104602
   Summary: std::source_location::current uses cast from void*
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: foom at fuhm dot net
  Target Milestone: ---

I'm working on implementing __builtin_source_location() in Clang
(https://reviews.llvm.org/D120159).

In testing it against the libstdc++  header, I ran into a
minor issue.

"current()" in GNU libstdc++ is defined as so:

static consteval source_location
current(const void* __p = __builtin_source_location()) noexcept
{
  source_location __ret;
  __ret._M_impl = static_cast (__p);
  return __ret;
}

But! A static_cast from a `const void*` parameter to `const __impl*` is not
permitted in constexpr evaluation:
"""
5. An expression E is a core constant expression unless the evaluation of E,
[...] would evaluate one of the following:
[...]
5.15. a conversion from type cv void* to a pointer-to-object type;"
"""
http://eel.is/c++draft/expr.const#5.15

Clang diagnoses this rule, but GCC apparently does not. (it's not really clear
to me why this rule really needs to exist in the standard -- why bother to
police which kinds of pointer casts you're allowed to do, instead of just
raising an error upon _access_ through the wrong type?)

Anyhow, to workaround this issue, I plan to simply hardcode an exception to the
check in Clang for casts which occur in a "std::source_location::current"
method. Yet, although it's perhaps too late to avoid this workaround, it'd be
nice if libstdc++ didn't require the use of an invalid cast.

In clang (in my proposed change), __builtin_source_location already returns the
expected `const __impl*` type, rather than `const void*` as it does in GCC. So,
the issue is only the cast TO `void*` and back again in libstdc++. ISTM this
would be fixed by moving the `static_cast ` into the default
parameter expression. That would then be a no-op cast on clang, and an (invalid
but undiagnosed) cast from void in GCC.

[Bug libstdc++/104602] std::source_location::current uses cast from void*

2022-02-21 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104602

--- Comment #4 from James Y Knight  ---
Yea that should work. Or even just `auto`.

[Bug target/55522] -funsafe-math-optimizations is unexpectedly harmful, especially w/ -shared

2022-09-06 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55522

James Y Knight  changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #12 from James Y Knight  ---
https://github.com/llvm/llvm-project/issues/57589 was just filed, requesting to
fix this behavior in Clang, as well.

Since Clang is effectively only doing it in the first place to match GCC's
behavior, my feeling is that it'd be better not to make such a change in Clang
only.

However, I'd just like to give my support to changing this in GCC (either to
stop automatically linking against crtfastmath.o altogether, or to at least
stop doing so with -shared). And, if there is a change here, would certainly
then propose to match the new behavior in Clang.

[Bug inline-asm/98096] Inconsistent operand numbering for asm goto with in-out operands

2022-01-05 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98096

James Y Knight  changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #7 from James Y Knight  ---
Previously, you never needed to care about the numbering of the extra hidden
input constraints generated for an in-out constraints, because they were
_last_. Their existence previously only mattered in that you needed to count
them as part of the "max 30" constraint limit.

That's why it is sensible to _keep_ these internal constraints last -- after
ALL user-specified constraints, including asm-goto labels. Putting in the
middle, and forcing users to count them just adds extra unnecessary complexity
to the user-facing API.

It appears to me that the GCC decision here was accidental, and that when
pointed out, the bug was simply documented rather than fixed. That's
unfortunate.

[Bug c++/56958] Spurious set but not used variable warning in empty pack expansion

2022-02-01 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56958

James Y Knight  changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #6 from James Y Knight  ---
I agree with the other people noting that it isn't _useful_ to warn about this
construct, and that this ought to be considered a valid bug, not working as
intended.

[Bug tree-optimization/100038] -Warray-bound triggers false positives

2022-02-09 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100038

James Y Knight  changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #8 from James Y Knight  ---
Here's a shorter test-case, reproduces with g++-11 -O2 -Warray-bounds:
```
struct SparseBitVectorElement {
  long Bits[2];
  int find_first() const;
};

int SparseBitVectorElement::find_first() const {
  for (unsigned i = 0; i < 2; ++i)
if (Bits[i])
  return i; // 
  __builtin_unreachable(); // Illegal empty element
}
```

The "__builtin_unreachable" at the end of the function seems to be the trigger
for the issue -- presumably because the compiler decides to omit the loop end
condition as being unnecessary.


Trying the above on godbolt, it appears that it no longer occurs on gcc trunk
for this test-case. But, I don't know if that was intentionally fixed or just
happens not to trigger here. (I haven't tried compiling LLVM with a gcc trunk
snapshot to see if all similar warnings have gone away.)

[Bug c++/55918] Stack partially unwound when noexcept causes call to std::terminate

2021-11-14 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55918

James Y Knight  changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #5 from James Y Knight  ---
The originally-reported program still appears to exhibit the issue.

Just looking at the unwind code -- and without attempting to test anything --
it appears that the solution may be as simple as inserting two lines:
  if (found_type == found_terminate)
return _URC_FATAL_PHASE1_ERROR;

at line 651 of eh_personality.cc
(https://github.com/gcc-mirror/gcc/blob/b85a03ae11b157d60ddf93b71632efe0bde3bafd/libstdc%2B%2B-v3/libsupc%2B%2B/eh_personality.cc#L651)

I believe that would abort the search phase (similarly to what happens if you
run out of unwind frames before finding any catch handler) and cause
_Unwind_RaiseException to return _URC_FATAL_PHASE1_ERROR, which then causes
_cxa_throw to call terminate().

[Bug c++/55918] Stack partially unwound when noexcept causes call to std::terminate

2021-12-04 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55918

--- Comment #6 from James Y Knight  ---
I realize that my suggestion above could only solve _most_ of the problem --
e.g. the original example, where the noexcept function doesn't have a try/catch
in it.

In that original example, there's no entry for the IP of the call in the LSDA
table. The personality fn already knows during phase1 that this indicates
termination -- but it simply fails to actually trigger the terminate in phase1,
even though it easily could (& should!).


However, in the example from comment #4, there _WILL_ be an entry in the
callsite table covering the throw (necessarily, in order to to catch type
"float"), so the "missing callsite => terminate" mechanism isn't applicable in
that case. As the comment mentioned, to handle that, we'd need some alternative
indication for termination which can be put in the action list.

ISTM this could be done most straightforwardly by using an action record with a
ttype pointing to a new ABI-defined special-purpose symbol (e.g.
"__cxxabiv1::__eh_noexcept"). In libsupc++'s impl, that symbol can be an object
whose type is a new std::type_info subclass, whose __do_catch overload calls
terminate. Thus, when the personality fn falls through all the _actual_ catch
action records, and comes to this, last one, it will query whether it can catch
an exception by calling its __do_catch, and immediately trigger termination.

GCC, then, can emit that as the last "catch" action in the chain for a
try/catch in a noexcept function (instead of the cleanup action with code that
calls std::terminate explicitly in the cleanup, that it does now).

[Bug target/98112] Add -f[no-]direct-access-external-data & drop HAVE_LD_PIE_COPYRELOC

2023-01-02 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98112

James Y Knight  changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #8 from James Y Knight  ---
The requested semantics were subsequently implemented by GCC as
`-mno-direct-extern-access` in PR100593, is that right? (Except that it was
done only for x86-64, rather than being arch-independent.)

So maybe this PR should be closed?

[Bug c++/36685] clarify/diagnose use of weak constant

2022-05-25 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36685

James Y Knight  changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #4 from James Y Knight  ---
The interaction of __attribute__((weak)) and const int was recently explored in
Clang in this thread:
https://discourse.llvm.org/t/weak-attribute-semantics-on-const-variables/62311

Strangely, it appears that Clang and GCC have opposite odd behavior currently:
GCC appears to evaluate weak constants _only_ in constant evaluation (so long
as

[Bug c++/36685] clarify/diagnose use of weak constant

2022-05-25 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36685

--- Comment #5 from James Y Knight  ---
(oops submitted commit by mistake, continuing...)

Strangely, it appears that Clang and GCC both have odd behaviors currently, but
somewhat opposites:

- GCC appears to evaluate weak constants _only_ in frontend constant
evaluation. It does not treat them as known during backend optimizations.
(However, GCC does not allow you to use such a variable in a context that is
required to be constant by language rules).

- Clang evaluates weak constants _only_ in backend optimizations, and never in
frontend constant evaluation.


Clang will be changing to stop optimizing based on weak constant value, so that
they are consistently treated as unknown values.

I'd suggest that GCC probably ought to do the same (by no longer constant
evaluating such variables).

[Bug c++/99858] Wrong throw-expression behaviour with reference to pointer

2022-06-10 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99858

James Y Knight  changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #3 from James Y Knight  ---
This is a mess.

Clang gets it "right" only through a really awful hack, which breaks
std::rethrow_exception, and which I'm now proposing to remove.
See https://github.com/llvm/llvm-project/issues/55340#issuecomment-1152755112

I don't believe there's a way to actually get this correct in the Itanium ABI
as it stands.

[Bug middle-end/101836] __builtin_object_size(P->M, 1) where M is an array and the last member of a struct fails

2022-06-24 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101836

James Y Knight  changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #31 from James Y Knight  ---
It doesn't make sense to have a mode in which `int array[0]` is accepted but is
not a flex array.

Either that should be a compilation error (as the standard specifies), or it
should be a flex array. Accepting it as an extension but having it do the wrong
thing is not useful or helpful.

Note that Clang has a dedicated warning flag for zero-length arrays:
-Wzero-length-array, so anyone who wants to prohibit them may use
-Werror=zero-length-array. It would be helpful for GCC could follow suit there.

The other proposed modes:
- Treat all trailing arrays as flexible arrays. the default behavior;
- Only treating [], [0], and [1] as flexible array;
- Only treating [] and [0] as flexible array;
do make sense.

[Bug middle-end/101836] __builtin_object_size(P->M, 1) where M is an array and the last member of a struct fails

2022-07-06 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101836

--- Comment #33 from James Y Knight  ---
(In reply to qinzhao from comment #32)
> there is a Bugzilla that has been filed for GCC to request the same warning
> for GCC:
> https://gcc.gnu.org/bugzilla//show_bug.cgi?id=94428
> 
> -Wzero-length-array

Great. Adding that flag, and eliminating the -fstrict-flex-arrays=3 option from
this proposal would be good.

> As suggested by Siddhesh in comment#23, -Wstrict-flex-arrays might be
> necessary to be added too, and 
> -Wzero-length-array will be an alias to 
> -Wstrict-flex-arrays=3

I don't understand what the -Wstrict-flex-arrays warning and its multiple
levels is proposed to actually do.

Is it supposed to warn on the structs that change behavior in the corresponding
-fstrict-flex-array=LEVEL? But that would mean -Wstrict-flex-arrays=1 would
warn on any array at the end of a struct which has a size other than 0 or 1.
That's clearly not going to be actually practical...so perhaps you had
something else in mind?

[Bug middle-end/101836] __builtin_object_size(P->M, 1) where M is an array and the last member of a struct fails

2022-07-06 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101836

--- Comment #36 from James Y Knight  ---
(In reply to Kees Cook from comment #34)
> > Great. Adding that flag, and eliminating the -fstrict-flex-arrays=3 option
> > from this proposal would be good.
> 
> Hmm? No, -fstrict-flex-arrays=3 is still needed (because it changes compiler
> _behavior_, e.g. for proper FORTIFY coverage or trailing arrays, etc).

There is no purpose served by writing a struct member `int x[0];` other than to
create a FAM. Zero-length arrays are not permitted by the C standard, but are a
GCC compiler extension explicitly for the purpose of creating a FAM. This is
entirely unlike `int x[1];` or `int x[10];` which of course have a primary
meaning as a concrete array size...

If the linux kernel doesn't want to allow `int x[0];` FAMs, then prohibit them
entirely using -Werror=zero-length-array (once it's implemented).

[Bug middle-end/101836] __builtin_object_size(P->M, 1) where M is an array and the last member of a struct fails

2022-07-06 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101836

--- Comment #37 from James Y Knight  ---
(In reply to qinzhao from comment #35)
> I think that -Wstrict-flex-arrays will need to be cooperated with
> -fstrict-flex-arrays=N, i.e, only when -fstrict-flex-arrays=N is presenting,
> -Wstrict-flex-arrays will be valid and report the warnings when see a [0],
> or [1], or any trailing array based on N:

When -fstrict-flex-arrays is used, I'd expect the existing -Warray-bounds
warning to already emit diagnostics in the cases you list, because those cases
should no longer be special-cased to act as a FAM, and thus no longer
explicitly suppress it.

[Bug libstdc++/111351] New: constexpr std::string objects permitted to escape constant evaluation when SSO

2023-09-08 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111351

Bug ID: 111351
   Summary: constexpr std::string objects permitted to escape
constant evaluation when SSO
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: foom at fuhm dot net
  Target Milestone: ---

In C++20, libstdc++ currently allows an std::string instance to escape from
constant evaluation to runtime, as long as the string fit within the SSO
length.

E.g., as a global variable, compiled with -std=c++20:
constexpr std::string s1; // OK
constexpr std::string s1 = ""; // OK
constexpr std::string s1 = "0123456789abcde"; // OK
constexpr std::string s2 = "0123456789abcdef"; // FAIL

I believe all of the above ought to fail to compile.

This will result in user code which can be built or not based on whether their
string happens to fit within the SSO string length. I find that quite
unfortunate, since it is supposed to be an internal implementation
detail/optimization, and this makes it effectively part of the API that code
will grow to depend on.

As comparison, libc++ rejects all the above examples, by forcing the SSO-size
to zero in constant evaluation context, so that a pointer to an external
allocation is always used.

This was brought to my attention from 
https://quuxplusone.github.io/blog/2023/09/08/constexpr-string-firewall/

[Bug libstdc++/111351] constexpr std::string objects permitted to escape constant evaluation when SSO

2023-09-11 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111351

--- Comment #4 from James Y Knight  ---
vector and string are different in one key way: a zero-sized vector has no
accessible storage, while a zero-sized string has 1 byte of readable storage --
the NUL terminator. Because of that, I don't think it's unreasonable for a
zero-length vector to be constinit'able, while a zero-length string is not.

But, certainly the _more_ concerning issue is with non-zero-sized strings where
the validity of the program depends on what exact SSO size was chosen by the
implementation.

> libc++'s choice is confusing even for the experts, who have to maintain its 
> split-brain SSO logic forever because Hyrum's Law

"Hyrum's Law" is exactly why I think it's a mistake to permit SSO-allocated
strings. It makes the SSO length a critical part of the interface. People will
start writing code which assumes that a constexpr global string of size "N"
works, and that will cause problems for other standard libraries which use a
different SSO size "M", if M < N. E.g. if libc++ starts allowing this, then
people who first target libc++ will find that strings up to 22 characters work,
and be surprised/annoyed by libstdc++ failing to build their program.

It is much simpler to say to users "you cannot make a constexpr std::string
unless it lives fully within constant-evaluation-time." then to also add "...OR
unless the size is short enough, where that size depends on your
implementation."

[Bug libstdc++/111351] constexpr std::string objects permitted to escape constant evaluation when SSO

2023-09-12 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111351

--- Comment #5 from James Y Knight  ---
> Does using __builtin_is_constant_p on the union member not work?

I've created a proof-of-concept patch for libc++ to support SSO strings during
constant evaluation. It works.

If everyone disagrees with me and believes that this is a really awesome
foot-gun to give to users, I will go ahead and propose that patch to libc++
maintainers. (As mentioned, that'll cause more code to be compilable under
libc++ than is possible to permit under libstdc++/MSVC implementations).

However, I continue to believe the opposite outcome, prohibiting this
everywhere, would be preferable.

[Bug libstdc++/111351] constexpr std::string objects permitted to escape constant evaluation when SSO

2023-09-26 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111351

--- Comment #7 from James Y Knight  ---
On the libc++ side, a suggestion was given that instead of making this an
_error_, we could instead emit a warning if "a constexpr or constinit object is
a basic_string or contains a basic_string subobject, or the definition of a
constexpr or constinit variable extends the lifetime of a temporary object that
meets the previous condition."

I think that was a really great suggestion -- diagnosing via a warning is a
nicer solution than putting is_constant_evaluated hacks into the library (as
MSVC had, and libc++ currently has but will likely remove).

One could either hardcode std::basic_string for the diagnostic, or add a new
type-attribute to permit any type to opt-in to such a warning. You'd want to
use it if you have a type where you don't _intend_ to support
constant-initialization, but where it may sometimes be possible as an
implementation detail, and you want to tell users not to rely on that
implementation detail.

[Bug c++/118883] New: [C++17] Incorrectly requires initializer for static constexpr class-member

2025-02-14 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118883

Bug ID: 118883
   Summary: [C++17] Incorrectly requires initializer for static
constexpr class-member
   Product: gcc
   Version: 15.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: foom at fuhm dot net
  Target Milestone: ---

The following ought to be accepted in C++17 and later:
```
struct Foo {int* x = 0;};
class Bar {
static constexpr Foo foo;
};
```

But GCC it rejects with `error: 'constexpr' static data member 'foo' must have
an initializer`.

The requirement was removed by P0386r2, which modified class.data.static from
"shall specify a brace­-or-­equal-­initializer" to "may specify a
brace-or-equal-initializer".

[Bug c/119526] standard attributes should be preserved in redeclarations

2025-03-31 Thread foom at fuhm dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119526

James Y Knight  changed:

   What|Removed |Added

 CC||foom at fuhm dot net

--- Comment #2 from James Y Knight  ---
Presumably also in this example, "i" should remain deprecated:

struct S {
  char c;
  [[deprecated]] int i;
};

struct S {
  char c;
  int i;
};