Hi, When the location for throw() exception specification is not the same as the function it is written against, it leads gcov to give incorrect results. See bug 50055 for details of the the same. The following patch makes sure that the exception specification block (nothrow or otherwise) is always associated with the function definition line number.
I have a test case included with the patch. I ran the c++ test suite and found no regressions due to this patch. -- Siddhesh cp/ChangeLog: PR c++/50055 * except.c (begin_eh_spec_block): Build EH_SPEC block on the same line as the function. testsuite/ChangeLog: PR c++/50055 * g++.dg/gcov/gcov-7.C: New test. Index: gcc/testsuite/g++.dg/gcov/gcov-7.C =================================================================== --- gcc/testsuite/g++.dg/gcov/gcov-7.C (revision 0) +++ gcc/testsuite/g++.dg/gcov/gcov-7.C (revision 0) @@ -0,0 +1,28 @@ +/* Check that Exception handler specification is not + mapped to the curly braces below the function + declaration. */ + +/* { dg-options "-fprofile-arcs -ftest-coverage" } */ +/* { dg-do run { target native } } */ + +struct foo +{ + foo () throw (int) + { /* count (-) */ + throw (1); + } +}; + +int main () +{ + try + { + foo f; + } + catch ( ...) + { + return 0; + } +} + +/* { dg-final { run-gcov gcov-7.C } } */ Index: gcc/cp/except.c =================================================================== --- gcc/cp/except.c (revision 177613) +++ gcc/cp/except.c (working copy) @@ -527,15 +527,17 @@ begin_eh_spec_block (void) { tree r; + location_t spec_location = DECL_SOURCE_LOCATION (current_function_decl); + /* A noexcept specification (or throw() with -fnothrow-opt) is a MUST_NOT_THROW_EXPR. */ if (TYPE_NOEXCEPT_P (TREE_TYPE (current_function_decl))) { - r = build_stmt (input_location, MUST_NOT_THROW_EXPR, NULL_TREE); + r = build_stmt (spec_location, MUST_NOT_THROW_EXPR, NULL_TREE); TREE_SIDE_EFFECTS (r) = 1; } else - r = build_stmt (input_location, EH_SPEC_BLOCK, NULL_TREE, NULL_TREE); + r = build_stmt (spec_location, EH_SPEC_BLOCK, NULL_TREE, NULL_TREE); add_stmt (r); TREE_OPERAND (r, 0) = push_stmt_list (); return r;