[Bug c/94142] New: typeof enum member appears to give wrong signedness
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94142 Bug ID: 94142 Summary: typeof enum member appears to give wrong signedness Product: gcc Version: 9.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: matthew.fernandez at gmail dot com Target Milestone: --- Consider the following code: typedef enum { A, B } t; t x; __typeof__(A) y; int foo() { if (x == y) return 0; return 1; } With GCC 9.2.0, compiling with -Wsign-compare has the following to say: $ gcc-9.2.0 -std=gnu11 -c -Wsign-compare goo.c foo.c: In function 'foo': foo.c:6:9: warning: comparison of integer expressions of different sightedness: 't' {aka 'enum '} and 'int' [-Wsign-compare] 6 | if (x == y) | ^~ This seems surprising to me. Shouldn't x and y have the same signedness as they're both the type of the enum? It seems like somehow the type of an enum member differs from the type of the enum itself. Either way, the warning seems spurious here. Maybe #66773 is relevant. Some cursory testing suggests to me this behaviour extends back to at least the GCC 4 series. I could not find a version of Clang that has this behaviour.
[Bug c/94142] typeof enum member appears to give wrong signedness
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94142 Matthew Fernandez changed: What|Removed |Added Resolution|--- |INVALID Status|UNCONFIRMED |RESOLVED --- Comment #2 from Matthew Fernandez --- Ah I see. I had missed the subtlety in the standard there. Thanks for explaining and for the pointer to the docs, Jonathan. I'll close as INVALID.
[Bug c++/82873] New: Generated copy constructor calls constructors for 0-sized array members
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82873 Bug ID: 82873 Summary: Generated copy constructor calls constructors for 0-sized array members Product: gcc Version: 7.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: matthew.fernandez at gmail dot com Target Milestone: --- Hello there, I'm trying to do something a little unorthodox and ran into an undefined reference during linking. It appears that a generated copy constructor calls another copy constructor that itself is not generated. A minimised example is: #include class Foo { std::vector x[0]; }; int main(void) { Foo a; Foo b(a); return 0; } Compiling this yields: $ g++ -std=c++17 -W -Wall -Wextra main.cc /tmp/ccfexx8L.o: In function `Foo::Foo(Foo const&)': main.cc:(.text._ZN3FooC2ERKS_[_ZN3FooC5ERKS_]+0x35): undefined reference to `std::vector >::vector(std::vector > const&)' It seems this is related to the 0-sized array member, which I realise is non-standard (https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html). Making the array member size 1 results in the relevant vector copy constructor being generated, as does inserting the following otherwise-useless code into the translation unit: static inline std::vector dummy(const std::vector &p) { return p; } This behaviour surprised me because I expected GCC to either (1) emit a compile error or (2) generate the relevant constructors. Is this known/expected behaviour? Possibly of relevance PR 42121 and PR 14799.
[Bug c++/82873] Generated copy constructor calls constructors for 0-sized array members
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82873 --- Comment #1 from Matthew Fernandez --- Sorry, that was meant to be PR 14779, not 14799.
[Bug libgcc/67902] New: Undefined negation in __divdi3
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67902 Bug ID: 67902 Summary: Undefined negation in __divdi3 Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: libgcc Assignee: unassigned at gcc dot gnu.org Reporter: matthew.fernandez at gmail dot com CC: joseph at codesourcery dot com Target Milestone: --- As discussed on the GCC list, I believe the function __divdi3 performs a signed negation that may be undefined behaviour. In more detail: AIUI, signed 64-bit division can be emitted as a call to software emulation in libgcc when the current target has no native hardware support. For example, on 32-bit x86 this can mean signed 64-bit division becomes a call to __divdi3. Internally, this function negates its operands if they are negative. I believe this negation, in the case when either of the operands is INT64_MIN is undefined behaviour. This seems to mean that a legal operation like `INT64_MIN / INT64_MIN` inadvertently causes undefined behaviour. Thus I believe __divdi3's implementation doesn't strictly comply with the C standard. There may be some disagreement about this as presumably GCC does the expected thing when compiling this code and, as Joseph Myers has pointed out, the shipped libgcc binaries are probably fine. However, I believe a compiler is within its rights to transform `x = -x` into: if (x == INT64_MIN) { // nasal demons } else { x = -x; } Please let me know if I'm mistaken or if you need more information. If I'm incorrect, apologies for taking up your time. GCC commit: 03ca0c3cbd35930b7e08135e5f2ac069db22f7f7