Main entry point for `Function` validation.
(&mut self)
| 826 | |
| 827 | /// Main entry point for `Function` validation. |
| 828 | fn check_function(&mut self) -> Result<()> { |
| 829 | self.check_limits()?; |
| 830 | |
| 831 | // Check blocks and instructions. This also records a `ValueDef` for |
| 832 | // each defined value. |
| 833 | for block in self.func.blocks() { |
| 834 | self.check_block(block)?; |
| 835 | } |
| 836 | |
| 837 | // Check entry points before any CFG traversal uses them. |
| 838 | let entry_points = self.func.entry_points(); |
| 839 | ensure!( |
| 840 | !entry_points.is_empty(), |
| 841 | "Function must have at least one entry point" |
| 842 | ); |
| 843 | for (i, &entry) in entry_points.iter().enumerate() { |
| 844 | ensure!( |
| 845 | !entry_points[..i].contains(&entry), |
| 846 | "Entry points must not contain duplicates" |
| 847 | ); |
| 848 | self.check_entity(Entity::Block(entry))?; |
| 849 | ensure!( |
| 850 | self.func.block_preds(entry).is_empty(), |
| 851 | "{entry}: Entry point cannot have predecessors" |
| 852 | ); |
| 853 | ensure!( |
| 854 | self.func.block_params(entry).is_empty(), |
| 855 | "{entry}: Entry point cannot have block parameters" |
| 856 | ); |
| 857 | } |
| 858 | // Check that all blocks are reachable. |
| 859 | let postorder = PostOrder::for_function(self.func); |
| 860 | if postorder.cfg_postorder().len() != self.func.num_blocks() { |
| 861 | for block in self.func.blocks() { |
| 862 | ensure!( |
| 863 | postorder.is_reachable(block), |
| 864 | "{block} is not reachable from an entry point" |
| 865 | ); |
| 866 | } |
| 867 | |
| 868 | // There must be at least one unreachable block, so we can't get here. |
| 869 | unreachable!(); |
| 870 | } |
| 871 | |
| 872 | // Check that defs dominate uses, as required by SSA. |
| 873 | self.domtree.compute(self.func, &postorder); |
| 874 | for block in self.func.blocks() { |
| 875 | self.check_ssa_dominance(block)?; |
| 876 | } |
| 877 | |
| 878 | // Check values. |
| 879 | for value in self.func.values() { |
| 880 | self.check_value(value)?; |
| 881 | } |
| 882 | |
| 883 | Ok(()) |
| 884 | } |
| 885 | } |
no test coverage detected