> I'm analyzing some new -Wall failures in the v3 testsuite, and I'm also
> seeing one in your area, 20_util/duration/cons/1.cc, can you have a
> look?
I've looked at this one before, just to provide a reduced testcase:
#include <chrono>
int main() {
using std::chrono::duration;
duration<int> d;
int i = d.count();
return i;
}
compiled with "-std=c++0x -Wall -O1" gives:
'd.std::chrono::duration<int, std::ratio<1l, 1l> >::__r' is used
uninitialized in this function
Note that with -O0, no warning is issued. It appears with -O1,-O2 and -O3.
The duration default constructor is defined as:
duration() = default;
From my readings (8.4p9, 12.6.2p4, 8.5p6) __r is default-initialized
which means, for a non-class, non-array type no initialization is
performed leaving __r with an indeterminate value.
My question is, why doesn't -O0 also emit the warning? But first, is
__r really not being initialized? Checking the return value of the
testcase with -O0, I get random values indicating it is indeed not
being initialized ... but -O0 doesn't emit the warning. Now with -01,
the output is always 0, meaning its being zero-initialized or
equivalent but -O1 does emit the warning which is counter-intuitive.
In conclusion, the check 'd.count() == 0' is invalid for a
non-initialized duration<int> because d.count() should return an
indeterminent value and thus it should be removed (i'll provide a
patch in a separate thread) but I'm wondering if another testcase
should check for the warning (i.e. dg-warning) if its suppose to be
emitted with -Wall at all optimization levels.
Out of curiosity, I punched out the tree dump for both -O0 and -O1.
The final -O0 code looks like (modified for brevity):
duration<int, ratio<1,1>>::duration() { return; }
duration<int, ratio<1,1>>::count() { int i; i = this->__r; return i; }
int main() () {
int i;
struct duration d;
int D.5078;
int i.0;
<bb 2>:
__comp_ctor (&d);
i.0 = count (&d);
i = i.0;
D.5078 = i;
return D.5078;
}
whereas the final -O1 code looks like:
int main() () {
const int d$__r;
<bb 2>:
return d$__r;
}
To me, it looks like __r is uninitialized in both cases. the latter it
seems obvious (although, I don't really know what "d$" means). In the
former case, I don't know what "struct duration d;" does with __r and
from what I understand __comp_ctor(&d) just calls duration<int,
ratio<1,1>>::duration() { return; } which doesn't do anything with
__r.
Cheers,
Chris