aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/validation
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-07-04 21:40:13 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-07-31 17:25:51 +0200
commitd254b816c4b6b8a692507567ad9127ca9991596d (patch)
treee538b707b12238bf345e8e98ca4c258ce64cc0ff /validation
parentec3f72e981792a86a9e002471a06d61ecd5c6675 (diff)
downloadsparse-dev-d254b816c4b6b8a692507567ad9127ca9991596d.tar.gz
fix ptrlist corruption while killing unreachable BBs
In commit (51cfbc90a5 "fix: kill unreachable BBs after killing a child") kill_unreachable_bbs() was called during simplification in order to avoid creating fake cycles between phis and issuing bogus "crazy programmer" warnings. However, simplification is done via cse.c:clean_up_insns() which is looping over all BBs while kill_unreachable_bbs() loops over all BBs *and* can delete some of them which may corrupt the looping in clean_up_insns(). Fix this by: 1) refuse to emit the "crazy programmer" warning if there is a potential dead BB 2) move kill_unreachable_bbs() in the main cleanup loop which will avoid nested ep->bbs loop. Note: this solution is preferable to some others because the "crazy programmer" condition happens very rarely. It this thus better to delay this check than to call kill_unreachable_bbs() preventively. Note: the reproducer is one with very broken syntax but nothing forbid the same situation to happen with a valid program. Fixes: 51cfbc90a5e1462fcd624a1598ecd985a508a5d6 Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Diffstat (limited to 'validation')
-rw-r--r--validation/crash-ptrlist.c23
-rw-r--r--validation/crazy02-not-so.c18
2 files changed, 41 insertions, 0 deletions
diff --git a/validation/crash-ptrlist.c b/validation/crash-ptrlist.c
new file mode 100644
index 00000000..8e9b5cb5
--- /dev/null
+++ b/validation/crash-ptrlist.c
@@ -0,0 +1,23 @@
+a;
+char b;
+c() {
+ while () {
+ int *d;
+ while () {
+ char *e = &b;
+ if (a ?: (*d = f || *0) || g) {
+ if
+ ;
+ } else {
+ int h = 0;
+ if (j) {
+ char **i = &e;
+ if (0 ? 0 : 0 ?: (**i = 1 || 0 && 0)) h ?: (*e = i && &h
+
+/*
+ * check-name: crash ptrlist
+ * check-command: test-linearize $file
+ *
+ * check-error-ignore
+ * check-output-ignore
+ */
diff --git a/validation/crazy02-not-so.c b/validation/crazy02-not-so.c
index fe713358..19ee2529 100644
--- a/validation/crazy02-not-so.c
+++ b/validation/crazy02-not-so.c
@@ -16,6 +16,24 @@ int foo(int *ptr, int i)
return 1;
}
+int bar(int *ptr, int i)
+{
+ int *p;
+
+ switch (i - i) { // will be optimized to 0
+ case 0:
+ return 0;
+ case 1: // will be optimized away
+ // p is uninitialized
+ do { // will be an unreachable loop
+ *p++ = 123;
+ } while (--i);
+ break;
+ }
+
+ return 1;
+}
+
/*
* check-name: crazy02-not-so.c
* check-command: sparse -Wno-decl $file