I compiled & ran this little program: #include <string> #include <iostream> std::string repeat(const std::string& p_str, unsigned int p_count) { std::string result; for (unsigned int i=0;i<p_count;++i) result+=p_str; return result; } int main(void) { std::cout << repeat("gnu", 20) << std::endl; return 0; } The line containing the return statement is marked as "not run", which cannot be: std::string repeat(const std::string& p_str, unsigned int p_count) 1 { 1 std::string result; 21 for (unsigned int i=0;i<p_count;++i) 20 result+=p_str; ###### return result; }
Confirmed up to present mainline. W.
The problem at -O3, gcc inlines more functions and in this case repeat is inlined so the return is misreported because really is not executed at all (it is a no-op). I going to say this is a non-bug because it really is not executed.
But the problem also occurs when using -O0 (no optimization). Here is how I compiled: [tanis@icotanis new]$ g++ -fprofile-arcs -ftest-coverage -O0 covtest.cc With -O0, the compiler should not inline, should it?
I can confirm this at -O0 but it works correctly at -O1.
Which version did you use? With this version: [tanis@icotanis new]$ g++ --version g++ (GCC) 3.2.3 20030502 (Red Hat Linux 3.2.3-20) -O1 is no different.
The mainline (3.4 20031108).
Very much related to bug 11773.
Actually this has to do with deconstrutors so I do not think this is a bug.
I know what the bug is really, it has to do with NVR optimization in GCC which allows the return value to at the same location as result.
*** Bug 23052 has been marked as a duplicate of this bug. ***
It's OK if NVR uses the same location and emits no code, and if coverage information reflects this. The problem is that part of the coverage machinery appears to "think" that there is unreached code on the line with the return statement, so a "#####" is output rather than a "-". Emitting a "-" rather than a count would also be OK, and arguably correct if there is no real object code corresponding to the source line.
Having code coverage emit a "-" instead of "#####" in this case sounds appropriate and would certainly solve the problem for me. Is there a way to workaround this issue by reorganizing code, or something else, so that I can fool the NVR smarts into not getting invoked in this particular case?
Subject: Re: gcov misreports coverage of return statement [NVR] On Thu, 2005-10-27 at 01:41 +0000, reddy at pixar dot com wrote: > > ------- Comment #12 from reddy at pixar dot com 2005-10-27 01:41 ------- > Having code coverage emit a "-" instead of "#####" in this case sounds > appropriate and would certainly solve the problem for me. > > Is there a way to workaround this issue by reorganizing code, or something > else, so that I can fool the NVR smarts into not getting invoked in this > particular case? The -fno-elide-constructors flag helps; it forces explicit copy constructor calls, and that seems to get rid of most of the bogons -- but apparently not all of them -- I'll look further, but I think sometimes the initializer for a base class gets optimized in a way that results in a false ###### flagging. Still, if you're having this trouble, start with that flag.
*** Bug 31810 has been marked as a duplicate of this bug. ***
The problem with NRV transformation is that it removes the return statement from default path and keeps it in the catch path making GCOV to properly output it as unexecuted. I tried to look into the NRV modify_expr withing return_expr but it is not the place to find the proper locator, looks like NRV itself needs to be updated. Honza
The return statement, before the optimization, does two things; it causes a copy constructor call, and it causes the function to return. NVR eliminates the copy constructor call, but the statement still returns. At -O0, don't we still hit a distinct return statement for the code at the given source line? The fact that there is also unexecuted code present that executes only if exceptions are caught should not matter, because we mark a statement as covered if any part of it executes.
*** Bug 42660 has been marked as a duplicate of this bug. ***
Is this ever going to be looked at? It makes most gcov output incorrect and hence not useful.
I understand this is still an issue. Let's add Jason in CC, IIRC he contributed the NRV optimization on trees.
This is what is produced on the trunk: 1: 4:std::string repeat(const std::string& p_str, unsigned int p_count) -: 5:{ 1: 6: std::string result; 21: 7: for (unsigned int i=0;i<p_count;++i) 20: 8: result+=p_str; 1: 9: return result; =====: 10:} I don't know if it was only fixed on the trunk or was fixed before that.
*** Bug 110561 has been marked as a duplicate of this bug. ***