aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2022-01-14 15:22:18 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2022-01-14 17:51:26 -0500
commitcc3b67e40140ec79f86e79a96d7fdd169b84faaf (patch)
tree3e295a2eeaa649f550777fcdb44509923b6f515e
parent8931adfa0530590d21e74e5c7a1f8d26df575775 (diff)
downloadgcc-cc3b67e40140ec79f86e79a96d7fdd169b84faaf.zip
gcc-cc3b67e40140ec79f86e79a96d7fdd169b84faaf.tar.gz
gcc-cc3b67e40140ec79f86e79a96d7fdd169b84faaf.tar.bz2
analyzer: fix ICE when combining taint states has_ub and has_lb
gcc/analyzer/ChangeLog: * sm-taint.cc (taint_state_machine::combine_states): Handle combination of has_ub and has_lb. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/taint-merger.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
-rw-r--r--gcc/analyzer/sm-taint.cc14
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/taint-merger.c57
2 files changed, 66 insertions, 5 deletions
diff --git a/gcc/analyzer/sm-taint.cc b/gcc/analyzer/sm-taint.cc
index 3a46256b..3574565 100644
--- a/gcc/analyzer/sm-taint.cc
+++ b/gcc/analyzer/sm-taint.cc
@@ -860,15 +860,19 @@ taint_state_machine::combine_states (state_t s0, state_t s1) const
return s0;
if (s0 == m_tainted || s1 == m_tainted)
return m_tainted;
- if (s0 == m_stop)
- return s1;
- if (s1 == m_stop)
- return s0;
if (s0 == m_start)
return s1;
if (s1 == m_start)
return s0;
- gcc_unreachable ();
+ if (s0 == m_stop)
+ return s1;
+ if (s1 == m_stop)
+ return s0;
+ /* The only remaining combinations are one of has_ub and has_lb
+ (in either order). */
+ gcc_assert ((s0 == m_has_lb && s1 == m_has_ub)
+ || (s0 == m_has_ub && s1 == m_has_lb));
+ return m_tainted;
}
/* Check for calls to external functions marked with
diff --git a/gcc/testsuite/gcc.dg/analyzer/taint-merger.c b/gcc/testsuite/gcc.dg/analyzer/taint-merger.c
new file mode 100644
index 0000000..e4e48f3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/taint-merger.c
@@ -0,0 +1,57 @@
+/* { dg-additional-options "-fanalyzer-checker=taint" } */
+// TODO: remove need for this option
+
+#include "analyzer-decls.h"
+
+int v_start;
+
+__attribute__((tainted_args))
+void test (int v_tainted, int v_has_lb, int v_has_ub, int v_stop)
+{
+ /* Get each var into the 5 different taintedness states. */
+ if (v_has_lb < 10)
+ return;
+ if (v_has_ub > 100)
+ return;
+ if (v_stop < 0 || v_stop > 100)
+ return;
+
+ /* Verify that we have the taintedness states we expect. */
+
+ __analyzer_dump_state ("taint", v_start); /* { dg-warning "state: 'start'" } */
+ __analyzer_dump_state ("taint", v_tainted); /* { dg-warning "state: 'tainted'" } */
+ __analyzer_dump_state ("taint", v_has_lb); /* { dg-warning "state: 'has_lb'" } */
+ __analyzer_dump_state ("taint", v_has_ub); /* { dg-warning "state: 'has_ub'" } */
+ __analyzer_dump_state ("taint", v_stop); /* { dg-warning "state: 'stop'" } */
+
+ /* Check all combinations of taintedness state. */
+ __analyzer_dump_state ("taint", v_start + v_start); /* { dg-warning "state: 'start'" } */
+ __analyzer_dump_state ("taint", v_start + v_tainted); /* { dg-warning "state: 'tainted'" } */
+ __analyzer_dump_state ("taint", v_start + v_has_lb); /* { dg-warning "state: 'has_lb'" } */
+ __analyzer_dump_state ("taint", v_start + v_has_ub); /* { dg-warning "state: 'has_ub'" } */
+ __analyzer_dump_state ("taint", v_start + v_stop); /* { dg-warning "state: 'stop'" } */
+
+ __analyzer_dump_state ("taint", v_tainted + v_start); /* { dg-warning "state: 'tainted'" } */
+ __analyzer_dump_state ("taint", v_tainted + v_tainted); /* { dg-warning "state: 'tainted'" } */
+ __analyzer_dump_state ("taint", v_tainted + v_has_lb); /* { dg-warning "state: 'tainted'" } */
+ __analyzer_dump_state ("taint", v_tainted + v_has_ub); /* { dg-warning "state: 'tainted'" } */
+ __analyzer_dump_state ("taint", v_tainted + v_stop); /* { dg-warning "state: 'tainted'" } */
+
+ __analyzer_dump_state ("taint", v_has_lb + v_start); /* { dg-warning "state: 'has_lb'" } */
+ __analyzer_dump_state ("taint", v_has_lb + v_tainted); /* { dg-warning "state: 'tainted'" } */
+ __analyzer_dump_state ("taint", v_has_lb + v_has_lb); /* { dg-warning "state: 'has_lb'" } */
+ __analyzer_dump_state ("taint", v_has_lb + v_has_ub); /* { dg-warning "state: 'tainted'" } */
+ __analyzer_dump_state ("taint", v_has_lb + v_stop); /* { dg-warning "state: 'has_lb'" } */
+
+ __analyzer_dump_state ("taint", v_has_ub + v_start); /* { dg-warning "state: 'has_ub'" } */
+ __analyzer_dump_state ("taint", v_has_ub + v_tainted); /* { dg-warning "state: 'tainted'" } */
+ __analyzer_dump_state ("taint", v_has_ub + v_has_lb); /* { dg-warning "state: 'tainted'" } */
+ __analyzer_dump_state ("taint", v_has_ub + v_has_ub); /* { dg-warning "state: 'has_ub'" } */
+ __analyzer_dump_state ("taint", v_has_ub + v_stop); /* { dg-warning "state: 'has_ub'" } */
+
+ __analyzer_dump_state ("taint", v_stop + v_start); /* { dg-warning "state: 'stop'" } */
+ __analyzer_dump_state ("taint", v_stop + v_tainted); /* { dg-warning "state: 'tainted'" } */
+ __analyzer_dump_state ("taint", v_stop + v_has_lb); /* { dg-warning "state: 'has_lb'" } */
+ __analyzer_dump_state ("taint", v_stop + v_has_ub); /* { dg-warning "state: 'has_ub'" } */
+ __analyzer_dump_state ("taint", v_stop + v_stop); /* { dg-warning "state: 'stop'" } */
+}