[Bug libstdc++/92798] -fshort-enums can break iterators of std::map

2019-12-04 Thread fc9vqetne38 at temp dot mailbox.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92798

--- Comment #2 from Christian N  ---
To be honest, I'm not sure when and why it came to be. The build instructions
are partially from an old project and weren't cleaned properly. The immediate
code base actually only uses scoped enums. The problem just came up and upon
investigating, removing the flag fixed it.

It didn't occur to me that basically everything needs recompilation with
-fshort-enums, but it makes perfect sense.

I suppose this report can be closed as invalid then!?

Thanks!

[Bug libstdc++/92798] New: -fshort-enums can break iterators of std::map

2019-12-04 Thread fc9vqetne38 at temp dot mailbox.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92798

Bug ID: 92798
   Summary: -fshort-enums can break iterators of std::map
   Product: gcc
   Version: 9.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: fc9vqetne38 at temp dot mailbox.org
  Target Milestone: ---

Hi,

I'm having problems with iterators of std::map when -fshort-enums is enabled.
It somehow depends on the combination of compiler, stdlib and optimizations
(tested g++ and clang++, libstdc++ and libc++). The size of key (int vs. long)
and map also seem to matter. My layman guess is, that it's somehow related to
operator--.

Short example that shows the (to me unexpected) behavior, used versions of g++
and clang++ at the end:

#include 
#include 
int main() {
  auto m = std::map{{0,0}, {1,1}, {2,2}};
  std::cout << std::boolalpha;
  std::cout << (&(*m.begin()) == &(*m.rbegin())) << ' ';
  std::cout << (m.begin() == --m.end()) << ' ';
  std::cout << (++m.rbegin() == m.rend()) << ' ';
  std::cout << (++m.begin() == m.end()) << ' ';
  std::cout << (++(--m.end()) == m.end()) << '\n';
}

Compiling with g++ -fshort-enums main.cpp gives

true true true false false

while g++ main.cpp gives

false false false false true

I also tried compiling with clang++, libc++ and optimizations enabled in
various combinations.

1) g++ -nostdinc++ -I/usr/include/c++/v1 main.cpp -nodefaultlibs -lc++ -lc++abi
-lm -lc -lgcc_s -lgcc -fshort-enums

2) g++ -nostdinc++ -I/usr/include/c++/v1 main.cpp -nodefaultlibs -lc++ -lc++abi
-lm -lc -lgcc_s -lgcc -fshort-enums -O

3) clang++ -stdlib=libstdc++ -fshort-enums main.cpp

4) clang++ -O -stdlib=libstdc++ -fshort-enums main.cpp

5) clang++ -stdlib=libc++ -fshort-enums main.cpp

6) clang++ -O -stdlib=libc++ -fshort-enums main.cpp

All 1)-6) give

false false false false true

though 4) sometimes produces

true true true false false

e.g. when doing a range-based loop over the map before the comparisons.

Hope the report is legit and not too messy.

Cheers,
Christian

PS:

opensuse tumbleweed
g++ (SUSE Linux) 9.2.1 20190903 [gcc-9-branch revision 275330]
clang version 9.0.0 (tags/RELEASE_900/final 372316)