[llvm-bugs] [Bug 51024] New: [llvm-cov] a goto statement leads to incorrect coverage of the next statement

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Jul 8 06:19:13 PDT 2021


https://bugs.llvm.org/show_bug.cgi?id=51024

            Bug ID: 51024
           Summary: [llvm-cov] a goto statement leads to incorrect
                    coverage of the next statement
           Product: Runtime Libraries
           Version: 12.0
          Hardware: PC
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: libprofile library
          Assignee: unassignedbugs at nondot.org
          Reporter: byone.heng at gmail.com
                CC: llvm-bugs at lists.llvm.org

$./clang -v                                                                     
clang version 12.0.0 (https://github.com/llvm/llvm-project.git
b6c8feb29fce39121884f7e08ec6eb0f58da3fb7)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/x/project/llvm-project/build/install/bin/.
Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.5.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8
Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.5.0
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Candidate multilib: x32;@mx32
Selected multilib: .;@m64

$cat test.c
———————————————————
const signed char true_var = 1;
volatile unsigned char false_var = 0;

extern void abort (void);

struct S
{
  int n1, n2, n3, n4;
};

__attribute__((noinline)) struct S
foo (int x, int y, int z)
{
  if (x != 10 || y != 9 || z != 8)
    abort ();
  struct S s = { 1, 2, 3, 4 };
  return s;
}

__attribute__((noinline)) void **
bar (void **u, int *v)
{
  void **w = u;
  int *s = v, x, y, z;
  void **p, **q;
  static void *l[] = { &&lab1, &&lab1, &&lab2, &&lab3, &&lab4 };

  if (!u)
    return l;

  q = *w++;
  goto *q;
lab2:
  p = q;
  q = *w++;
  x = s[2];
  y = s[1];
  z = s[0];
  s -= 1;
  struct S r = foo (x, y, z);
  s[3] = r.n1;
  s[2] = r.n2;
  s[1] = r.n3;
  s[0] = r.n4;
  goto *q;
if( true_var > 0 )
  {
  lab3:
  p = q;
  q = *w++;
  s += 1;
  }
  s[0] = 23;
lab1:
  goto *q;
lab4:
  return 0;
}

int
main (void)
{
  void **u = bar ((void **) 0, (int *) 0);
  void *t[] = { u[2], u[4] };
  int s[] = { 7, 8, 9, 10, 11, 12 };
  if (bar (t, &s[1]) != (void **) 0
      || s[0] != 4 || s[1] != 3 || s[2] != 2 || s[3] != 1
      || s[4] != 11 || s[5] != 12)
    abort ();
  return 0;
}

——————————————————

$clang -O0 -g -fcoverage-mapping -fprofile-instr-generate=test.profraw test.c;
./a.out; llvm-profdata merge test.profraw -o test.profdata; llvm-cov show a.out
-instr-profile=test.profdata test.c > test.lcov; cat test.lcov

    5|       |const signed char true_var = 1;
    6|       |volatile unsigned char false_var = 0;
    7|       |
    8|       |extern void abort (void);
    9|       |
   10|       |struct S
   11|       |{
   12|       |  int n1, n2, n3, n4;
   13|       |};
   14|       |
   15|       |__attribute__((noinline)) struct S
   16|       |foo (int x, int y, int z)
   17|      1|{
   18|      1|  if (x != 10 || y != 9 || z != 8)
   19|      0|    abort ();
   20|      1|  struct S s = { 1, 2, 3, 4 };
   21|      1|  return s;
   22|      1|}
   23|       |
   24|       |__attribute__((noinline)) void **
   25|       |bar (void **u, int *v)
   26|      2|{
   27|      2|  void **w = u;
   28|      2|  int *s = v, x, y, z;
   29|      2|  void **p, **q;
   30|      2|  static void *l[] = { &&lab1, &&lab1, &&lab2, &&lab3, &&lab4 };
   31|       |
   32|      2|  if (!u)
   33|      1|    return l;
   34|       |
   35|      1|  q = *w++;
   36|      1|  goto *q;
   37|      1|lab2:
   38|      1|  p = q;
   39|      1|  q = *w++;
   40|      1|  x = s[2];
   41|      1|  y = s[1];
   42|      1|  z = s[0];
   43|      1|  s -= 1;
   44|      1|  struct S r = foo (x, y, z);
   45|      1|  s[3] = r.n1;
   46|      1|  s[2] = r.n2;
   47|      1|  s[1] = r.n3;
   48|      1|  s[0] = r.n4;
   49|      1|  goto *q;
   50|      1|  if( true_var > 0 )
   51|      0|  {
   52|      0|      lab3:
   53|      0|      p = q;
   54|      0|      q = *w++;
   55|      0|      s += 1;
   56|      0|  }
   57|      1|  s[0] = 23;
   58|      0|lab1:
   59|      0|  goto *q;
   60|      1|lab4:
   61|      1|  return 0;
   62|      0|}
   63|       |
   64|       |int
   65|       |main (void)
   66|      1|{
   67|      1|  void **u = bar ((void **) 0, (int *) 0);
   68|      1|  void *t[] = { u[2], u[4] };
   69|      1|  int s[] = { 7, 8, 9, 10, 11, 12 };
   70|      1|  if (bar (t, &s[1]) != (void **) 0
   71|      1|      || s[0] != 4 || s[1] != 3 || s[2] != 2 || s[3] != 1
   72|      1|      || s[4] != 11 || s[5] != 12)
   73|      0|    abort ();
   74|      1|  return 0;
   75|      1|}

Line 50 and 57 should not be executed.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20210708/d684d093/attachment.html>


More information about the llvm-bugs mailing list