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;

Reply via email to