[Bug c++/88086] gcc only allows valid expressions as unknown C++ attribute argument clause
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88086 Gábor Buella changed: What|Removed |Added CC||gbuella at gmail dot com --- Comment #1 from Gábor Buella --- This did come up for me as well, when trying to compile: enum [[clang::enum_extensibility(closed)]] dummy { a, b }; $ g++-8 dummy.cc y.cc:2:34: error: ‘closed’ was not declared in this scope enum [[clang::enum_extensibility(closed)]] dummy { a, b }; ^~ y.cc:2:34: note: suggested alternative: ‘class’ enum [[clang::enum_extensibility(closed)]] dummy { a, b }; ^~ class y.cc:2:44: warning: ‘clang::enum_extensibility’ scoped attribute directive ignored [-Wattributes] enum [[clang::enum_extensibility(closed)]] dummy { a, b }; ^ It is rather annoying, the attribute is ignored, but there is a compile error.
[Bug c++/93674] New: GCC eliminates conditions it should not, when strict-enums is on
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93674 Bug ID: 93674 Summary: GCC eliminates conditions it should not, when strict-enums is on Product: gcc Version: 8.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: gbuella at gmail dot com Target Milestone: --- $ cat code.cc enum some_enum { x = 1000 }; void sink(some_enum); void func() { for (int i = 0; i < 3; ++i) { for (int j = 3; j >= 0; --j) { sink((some_enum)(i + j)); } } } $ g++-8 -Wall -Wextra -pedantic -std=c++14 code.cc -fstrict-enums -S -o /dev/stdout -fno-dwarf2-cfi-asm -O3 | head -20 .file "code.cc" .text .p2align 4,,15 .globl _Z4funcv .type _Z4funcv, @function _Z4funcv: .LFB0: pushq %rbx .LCFI0: movl$3, %ebx .p2align 4,,10 .p2align 3 .L2: movl%ebx, %edi subl$1, %ebx call_Z4sink9some_enum@PLT jmp .L2 .LFE0: .size _Z4funcv, .-_Z4funcv .section.eh_frame,"a",@progbits $ g++-8 --version g++-8 (Ubuntu 8.3.0-6ubuntu1~18.04.1) 8.3.0 Copyright (C) 2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Notice the infinite loop in generated assembly (unconditional jmp to .L2). This doesn't happen without "-fstruct-enums", doesn't happen without -O2 or -O3. I'v seen this bug with GCC 8, GCC 9 . GCC-7 seems to be OK. I spent hours trying to find more compact code for reproducing it, but I just couldn't... The loop, and the addition (i + j) seems to be needed to trigger this.
[Bug c++/93674] GCC eliminates conditions it should not, when strict-enums is on
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93674 --- Comment #2 from Gábor Buella --- (In reply to Andrew Pinski from comment #1) > -fstrict-enums > Allow the compiler to optimize using the assumption that a value of > enumerated type can only be one of the values of the enumeration (as defined > in the C++ standard; basically, a value that can be represented in the > minimum number of bits needed to represent all the enumerators). This > assumption may not be valid if the program uses a cast to convert an > arbitrary integer value to the enumerated type. > > CUT --- > I assume that means since there is no negative numbers in the enum, that > means you might get undefined behavior if j is negative ... Look at the code, j is never negative when the cast is applied. You can easily verify it by printing the e.g. values.
[Bug c++/93674] GCC eliminates conditions it should not, when strict-enums is on
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93674 --- Comment #3 from Gábor Buella --- In case anyone would still get confused about the what values get casted to enum, here is another way to write that example: enum some_enum { x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, xa, xb, xc, xd, xe, xf, x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x0a, x0b, x0c, x0d, x0e, x0f }; void sink(some_enum); void func() { for (int i = 0; i < 3; ++i) { int j = 3; while (j >= 0) { // Note: (i + j) is always non-negative here // Actually, (i + j) is always of the values // given when defining the type above. sink((some_enum)(i + j)); --j; } } }
[Bug c++/93674] GCC eliminates conditions it should not, when strict-enums is on
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93674 --- Comment #6 from Gábor Buella --- (In reply to Jonathan Wakely from comment #4) > I can't reproduce this with GCC 9, only 8. $ cat code.cc enum some_enum { x = 1000 }; void sink(some_enum); void func() { for (int i = 0; i < 3; ++i) { int j = 3; while (j >= 0) { // turned into an uncoditional jmp by GCC // Note: (i + j) is always non-negative here // Actually, (i + j) is always of the values // given when defining the type above. sink((some_enum)(i + j)); --j; } } } $ g++-9 -Wall -Wextra -pedantic -std=c++14 code.cc -fstrict-enums -S -o /dev/stdout -fno-dwarf2-cfi-asm -O3 | head -20 .file "code.cc" .text .p2align 4 .globl _Z4funcv .type _Z4funcv, @function _Z4funcv: .LFB0: endbr64 pushq %rbx .LCFI0: movl$3, %ebx .p2align 4,,10 .p2align 3 .L2: movl%ebx, %edi subl$1, %ebx call_Z4sink9some_enum@PLT jmp .L2 .LFE0: .size _Z4funcv, .-_Z4funcv $ g++-9 --version g++-9 (Ubuntu 9.2.1-9ubuntu2) 9.2.1 20191008 Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.