+
+ my %solid_seen = ();
+ run_nfa $progs, $func->{first_statement}, do { my $state = -1; \$state; },
+ sub
+ {
+ my $state = ${$_[0]};
+ return \$state;
+ },
+ sub
+ {
+ my ($ip, $state) = @_;
+ return $solid_seen{"$ip $$state"}++;
+ },
+ sub
+ {
+ my ($ip, $state, $s, $c) = @_;
+
+ if($s->{op} eq 'ADDRESS')
+ {
+ my $field_ptr_ofs = $s->{b};
+ my $def = $progs->{globaldef_byoffset}->($field_ptr_ofs);
+ use Data::Dumper;
+ if (($def->{globaltype} eq 'read_only' || $def->{globaltype} eq 'const') &&
+ grep { $_ eq 'solid' } @{$progs->{entityfieldnames}[$progs->{globals}[$field_ptr_ofs]{v}{int}]})
+ {
+ # Taking address of 'solid' for subsequent write!
+ # TODO check if this address is then actually used in STOREP.
+ $$state = $ip;
+ }
+ }
+
+ if($c->{iscall})
+ {
+ # TODO check if the entity passed is actually the one on which solid was set.
+ my $func = $s->{a};
+ my $funcid = $progs->{globals}[$func]{v}{int};
+ if ($progs->{builtins}{setmodel}{$funcid} || $progs->{builtins}{setsize}{$funcid})
+ {
+ # All is clean.
+ $$state = -1;
+ }
+ }
+
+ if($c->{isreturn})
+ {
+ if ($$state >= 0) {
+ ++$warned{$$state}{''}{"Changing .solid without setmodel/setsize breaks area grid linking in Quake"};
+ }
+ }
+
+ return 0;
+ };
+