c++/3639: gcov .bb info incorrect for C++ static initialization

Janis Johnson janis@us.ibm.com
Tue Jul 10 16:36:00 GMT 2001

>Number:         3639
>Category:       c++
>Synopsis:       gcov .bb info incorrect for C++ static initialization
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Jul 10 16:36:00 PDT 2001
>Originator:     Janis Johnson
>Release:        3.1 20010707 (experimental)
System: Linux unknown.host 2.2.14 #5 SMP Sat Jun 24 15:44:37 PDT 2000 i686 unknown
Architecture: i686

host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: i686-pc-linux-gnu
configured with: ../gcc-mainline/configure --prefix=/home/janis/gnu/tools/gcc-mainline --enable-languages=c,c++

This provides further information about a problem reported in
http://gcc.gnu.org/ml/gcc-bugs/2001-04/msg00034.html by Michelle Lorenz
(limitations with gcov and STL).

This problem occurs with GCC 3.0 and the mainline (gcc version 3.1
20010707 (experimental)) but not with 2.95.3.

A C++ module that has a static object that needs a call to a constructor
or destructor generates code for
__static_initialization_and_destruction_0(int, int).  When an included
C++ file defines such a static object (as happens in libstdc++), the
information that branch_prob() puts into the sourcename.bb file for this
module confuses gcov.  The function is noted as being in the including
source file, with a line number for each file that contains a static
object definition.  If the number of lines in the original source file
is less than the line number of one of these definitions in an included
file then gcov aborts, as in the referenced message to gcc-bugs.  If the
including file is large enough then gcov reports counts for a call to
__static_initialization_and_destruction_0() at the line number for the
included file but in the report for the including file.

The file bb_bug1.C.gcov produced by the example is:
		extern int foo();
		#ifndef NOINCL
		#include "bb_bug2.C"
		struct S {
		  int i;
           4      S() { i = 0; }
           1    S s;
branch 0 taken = 0%
branch 1 taken = 0%
branch 2 taken = 0%
		main ()
           1    {
           1      return foo();
           1    }
branch 0 taken = 0%
branch 1 taken = 0%
branch 2 taken = 0%

The set of numbers near the bottom should be in bb_bug2.C.gcov.  If
bb_bug1.C were shorter then gcov would abort.

(This was done using a compiler with my patch to profile.c submitted
on July 2, 2001.)

There are other problems here as well, but I'll try to describe (or fix)
them separately.


To reproduce the problem, extract the souce files below and do:

  gcc -ftest-coverage -fprofile-arcs -o bb_bug1 bb_bug1.c
  gcov -b bb_bug1

-- bb_bug1.C -----------------------------------------------------------
extern int foo();

#ifndef NOINCL
#include "bb_bug2.C"

struct S {
  int i;
  S() { i = 0; }

S s;

main ()
  return foo();

-- bb_bug2.C -----------------------------------------------------------

struct T {
  int i;
  T() { i = 0; }

T t;

int foo()
  return t.i; 

More information about the Gcc-bugs mailing list