[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[creduce-bugs] c-reduce does not remove unused template arguments when reducing



I initially reported the bug as a `cvise` bug
    https://github.com/marxin/cvise/issues/29
but observed exactly the same behaviour on creduce in the recent past.

Tl;DR:
  clang_delta doe not seem to attempt to remove unused template
  arguments and does not inline some simple forms of 'using foo = bar;'

Recent example is a https://gcc.gnu.org/PR95768 case reducer. I'll
provide slightly different example here:

Input where `cvise` stopped and was not able to progress further:

```c
extern "C" void *malloc(unsigned long);
__attribute__((__noreturn__)) void a(const char *, const char *, int);
class c {
public:
  enum e { d };
};
class f {
public:
  int aa;
  f operator=(int) {
    int g, h, j, a, k, c = aa;
    k = c;
    h = k;
    int i = h &= j;
    a = i;
    int d = a;
    g = d;
    aa = g;
    return *this;
  }
};
template <typename, int, int> using af = f;
template <int ae, int ag> using l = af<int, ae, ag>;
class m {
public:
  l<1, 1> ai;
};
class C {
public:
  m *o() { return (m *)this + 1; }
};
class n {
public:
  int ak;
  C *al;
  n(c::e p1) {
    p1 ? void() : a("", "", 0);
    al = (C *)malloc(ak);
    m *b = al->o();
    b->ai = 0;
  }
};
bool an() {
  n(c::d);
  return true;
}
```

Test for `cvise`:

```bash
#!/bin/bash

args=(
/usr/bin/x86_64-pc-linux-gnu-g++

-march=sandybridge
-O2
-Wall

-c bug.cc
-o bug.o
)
#"${args[@]}"

LANG=C "${args[@]}" -fsyntax-only -Werror || exit 1

LANG=C "${args[@]}" 2>&1 | grep 'Segmentation fault'
```

`cvise ./test_cvise.sh bug.cc` can't reduce example further.

It's not very hard to shrink it further manually by removing unused
template arguments of `template <typename, int, int> using af = f;`.

I did it as:

```diff
--- bug.cc__	2020-06-19 18:56:41.000000000 +0100
+++ bug.cc___	2020-06-20 10:27:24.000000000 +0100
@@ -19,8 +19,8 @@
     return *this;
   }
 };
-template <typename, int, int> using af = f;
-template <int ae, int ag> using l = af<int, ae, ag>;
+using af = f;
+template <int ae, int ag> using l = af;
 class m {
 public:
   l<1, 1> ai;
--- bug.cc___	2020-06-20 10:27:24.000000000 +0100
+++ bug.cc____	2020-06-20 10:39:18.000000000 +0100
@@ -20,10 +20,10 @@
   }
 };
 using af = f;
-template <int ae, int ag> using l = af;
+using l = af;
 class m {
 public:
-  l<1, 1> ai;
+  l ai;
 };
 class C {
 public:
```

After that `cvise ./test_cvise.sh bug.cc` was able to get it down to:

```c
extern "C" void *malloc(unsigned long);
__attribute__((__noreturn__)) void a(const char *, const char *, int);
class c {
public:
  enum e { d };
};
class f {
public:
  int aa;
  f operator=(int) {
    int g, h, j, a, k, c = aa;
    k = c;
    h = k;
    int i = h &= j;
    a = i;
    int d = a;
    g = d;
    aa = g;
    return *this;
  }
};
using l = f;
class m {
public:
  l ai;
};
class C {
public:
  m *o() { return (m *)this + 1; }
};
class n {
public:
  int ak;
  C *al;
  n(c::e p1) {
    p1 ? void() : a("", "", 0);
    al = (C *)malloc(ak);
    m *b = al->o();
    b->ai = 0;
  }
};
bool an() {
  n(c::d);
  return true;
}
```

Note: yet unsquashed `using l = f;`.

Is it something that `clang_delta` could perform perform automatically?
Or it's something up to clang's libraries to get better at?

Thank you!

-- 

  Sergei