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>
This commit is contained in:
David Malcolm 2022-01-14 15:22:18 -05:00
parent 8931adfa05
commit cc3b67e401
2 changed files with 66 additions and 5 deletions

View file

@ -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

View file

@ -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'" } */
}