Hello.
I'm new to this list, but I've been using Clang for a while (and C++ for
many years).
I've encountered a problem when compiling with -O1 on FreeBSD/amd64 11.1
(with bundled Clang, i.e. 4.0.0, as well as with 5.0.1 and 6.0.0 from
ports).
I asked on comp.lang.c++ and the code was also confirmed to misbehave on
Linux, so they suggested I post it here.
What follows is the minimal code which should produce the error; notice
something more convoluted is needed at -O3 (the original software still
crashes, but in this example, probably too much is optimized away).
// ------------ a.cpp ------------------
#include <iostream>
#include <numeric>
#include <limits>
#include <cfenv>
double f(double A,double B) {
if (A<B) return std::numeric_limits<double>::max();
return A-B;
}
int main(int , char**) {
feenableexcept(FE_OVERFLOW); //**** NOTE 1
double A=f(.0001002773902563,1.);
std::cout<<A<<std::endl;
double B;
if (A==std::numeric_limits<double>::max()) {
// std::cout<<"Good"<<std::endl; //**** NOTE 2
B=A;
} else {
// std::cout<<"Bad"<<std::endl; //**** NOTE 2
B=A*2.;
}
std::cout<<B<<std::endl;
}
// ---------------------------------------
The command:
$ clang++ -O1 a.cpp
$ ./a.out
1.79769e+308
Floating point exception (core dumped)
NOTE 1: enabling overflow exceptions on FP math will render the
instruction "B=A*2" illegal.
That instruction shouldn't be executed, if following the proper program
flow; probably the compiler still has the CPU compute this value
speculatively.
NOTE 2: inserting the commented statement makes the program behave
correctly again, evidently avoiding the execution of the second branch.
Please let me know if you think this is a bug in the compiler, if using
feenableexcept along with optimizations is considered bad practive or if
you need further info.
bye & Thanks
av.