@@ -145,45 +145,52 @@ let analyze_function_stack_usage func =
145145(* * Bounds checking analysis *)
146146
147147(* * Check array access bounds *)
148- let check_array_bounds ?( known_maps : Ast.map_declaration list = [] ) expr =
148+ let check_array_bounds expr =
149149 let rec check_expr e errors =
150150 match e.expr_desc with
151151 | ArrayAccess (arr_expr , idx_expr ) ->
152152 (match arr_expr.expr_desc, idx_expr.expr_desc with
153153 | Identifier arr_name , Literal (IntLit (idx , _ )) ->
154- (* First check if this is a known map *)
155- if List. exists (fun (map_decl : Ast.map_declaration ) -> map_decl.name = arr_name) known_maps then
156- (* Map access - inherently safe, skip bounds checking *)
157- errors
158- else
159- (* Check if we can determine array size from type *)
160- (match arr_expr.expr_type with
161- | Some (Ast. Array (_ , size )) ->
162- if idx > = size || idx < 0 then
163- ArrayOutOfBounds (arr_name, idx, size) :: errors
164- else
165- errors
166- | Some (Ast. Map (_ , _ , _ )) ->
167- (* Map access - inherently safe, skip bounds checking *)
154+ (* Use type annotations from the type-annotated AST *)
155+ (match arr_expr.expr_type with
156+ | Some (Ast. Array (_ , size )) ->
157+ if idx > = size || idx < 0 then
158+ ArrayOutOfBounds (arr_name, idx, size) :: errors
159+ else
168160 errors
169- | _ -> UnknownBounds arr_name :: errors)
170- | Identifier arr_name , _ ->
171- (* First check if this is a known map *)
172- if List. exists (fun (map_decl : Ast.map_declaration ) -> map_decl.name = arr_name) known_maps then
173- (* Map access with dynamic key - inherently safe *)
174- errors
175- else
176- (* Check if this is a map access - maps are safe *)
177- (match arr_expr.expr_type with
178- | Some (Ast. Map (_ , _ , _ )) ->
179- (* Map access with dynamic key - inherently safe *)
161+ | Some (Ast. Map (_ , _ , _ )) ->
162+ (* Map access - inherently safe, skip bounds checking *)
163+ errors
164+ | Some (Ast. Str size ) ->
165+ (* String character access - check bounds *)
166+ if idx > = size || idx < 0 then
167+ ArrayOutOfBounds (arr_name, idx, size) :: errors
168+ else
180169 errors
181- | Some (Ast. Array (_ , _ )) ->
182- (* Array access with dynamic index - runtime bounds check needed *)
183- UnknownBounds arr_name :: errors
184- | _ ->
185- (* Unknown type - could be array, so flag for safety *)
186- UnknownBounds arr_name :: errors)
170+ | Some _ ->
171+ (* Other types don't need bounds checking *)
172+ errors
173+ | None ->
174+ (* Type annotation missing - this shouldn't happen with type-annotated AST *)
175+ UnknownBounds arr_name :: errors)
176+ | Identifier arr_name , _ ->
177+ (* Dynamic index access - use type annotations *)
178+ (match arr_expr.expr_type with
179+ | Some (Ast. Map (_ , _ , _ )) ->
180+ (* Map access with dynamic key - inherently safe *)
181+ errors
182+ | Some (Ast. Array (_ , _ )) ->
183+ (* Array access with dynamic index - runtime bounds check needed *)
184+ UnknownBounds arr_name :: errors
185+ | Some (Ast. Str _ ) ->
186+ (* String character access with dynamic index - safe in kernelscript *)
187+ errors
188+ | Some _ ->
189+ (* Other types don't need bounds checking *)
190+ errors
191+ | None ->
192+ (* Type annotation missing - shouldn't happen with type-annotated AST *)
193+ UnknownBounds arr_name :: errors)
187194 | FieldAccess (_ , "data" ), Literal (IntLit (idx , _ )) when idx > = 1500 ->
188195 (* Unsafe packet access - large index into packet data *)
189196 PointerOutOfBounds (" packet_data" ) :: errors
@@ -220,42 +227,42 @@ let check_array_declaration name typ =
220227 | _ -> []
221228
222229(* * Analyze bounds checking in statements *)
223- let analyze_statement_bounds ?( known_maps : Ast.map_declaration list = [] ) stmt =
230+ let analyze_statement_bounds stmt =
224231 let errors = ref [] in
225232
226233 let rec check_stmt s =
227234 match s.stmt_desc with
228235 | Declaration (name , Some typ , expr_opt ) ->
229236 errors := check_array_declaration name typ @ ! errors;
230237 (match expr_opt with
231- | Some expr -> errors := check_array_bounds ~known_maps expr @ ! errors
238+ | Some expr -> errors := check_array_bounds expr @ ! errors
232239 | None -> () )
233240 | ExprStmt expr | Assignment (_ , expr ) ->
234- errors := check_array_bounds ~known_maps expr @ ! errors
241+ errors := check_array_bounds expr @ ! errors
235242 | CompoundAssignment (_ , _ , expr ) ->
236- errors := check_array_bounds ~known_maps expr @ ! errors
243+ errors := check_array_bounds expr @ ! errors
237244 | CompoundIndexAssignment (map_expr , key_expr , _ , value_expr ) ->
238- errors := check_array_bounds ~known_maps map_expr @ ! errors;
239- errors := check_array_bounds ~known_maps key_expr @ ! errors;
240- errors := check_array_bounds ~known_maps value_expr @ ! errors
245+ errors := check_array_bounds map_expr @ ! errors;
246+ errors := check_array_bounds key_expr @ ! errors;
247+ errors := check_array_bounds value_expr @ ! errors
241248 | FieldAssignment (obj_expr , _ , value_expr ) ->
242- errors := check_array_bounds ~known_maps obj_expr @ ! errors;
243- errors := check_array_bounds ~known_maps value_expr @ ! errors
249+ errors := check_array_bounds obj_expr @ ! errors;
250+ errors := check_array_bounds value_expr @ ! errors
244251 | If (cond , then_stmts , else_opt ) ->
245- errors := check_array_bounds ~known_maps cond @ ! errors;
252+ errors := check_array_bounds cond @ ! errors;
246253 List. iter check_stmt then_stmts;
247254 (match else_opt with
248255 | None -> ()
249256 | Some else_stmts -> List. iter check_stmt else_stmts)
250257 | For (_ , start , end_ , body ) ->
251- errors := check_array_bounds ~known_maps start @ ! errors;
252- errors := check_array_bounds ~known_maps end_ @ ! errors;
258+ errors := check_array_bounds start @ ! errors;
259+ errors := check_array_bounds end_ @ ! errors;
253260 List. iter check_stmt body
254261 | While (cond , body ) ->
255- errors := check_array_bounds ~known_maps cond @ ! errors;
262+ errors := check_array_bounds cond @ ! errors;
256263 List. iter check_stmt body
257264 | Return (Some expr ) ->
258- errors := check_array_bounds ~known_maps expr @ ! errors
265+ errors := check_array_bounds expr @ ! errors
259266 | _ -> ()
260267 in
261268
@@ -386,12 +393,10 @@ let analyze_stack_usage program =
386393(* * Perform bounds checking analysis *)
387394let analyze_bounds_safety program =
388395 let all_errors = ref [] in
389- (* Collect map declarations for bounds checking context *)
390- let known_maps = program.prog_maps in
391396
392397 List. iter (fun func ->
393398 List. iter (fun stmt ->
394- let errors = analyze_statement_bounds ~known_maps stmt in
399+ let errors = analyze_statement_bounds stmt in
395400 all_errors := errors @ ! all_errors
396401 ) func.func_body
397402 ) program.prog_functions;
0 commit comments