Simple check for self-assignments.
This is just a heuristic check that adds warnings if it sees assignments where some bit is on both the left- and right-hand sides. For instance, it would warn about something like this:
assign foo = a ? b : foo;
Such assignments might be combinational loops. Of course, most combinational loops are not so simple, and this is just an extremely stupid check that will only catch the most obvious problems.
I started by just seeing how bad it would be if I just gathered names on both side of the expression using vl-expr-names to gather up the names. But that produced too much noise about assignments like
foo[1] = foo[0].
So I now essentially collect up the bits of expressions, fudging for bit/part selects that aren't resolved. If this is done only after ranges are resolved, it is still pretty good. But it needs to be done before expressions are split, etc.
This found only two things at Centaur, one of which was an assignment of an otherwise-unused wire to itself, and one which was not actually a problem because essentially it had the form:
assign {foo, bar} = {baz, foo};