@@ -58,7 +58,7 @@ module fluff_dead_code_detection
5858 integer :: end_line = 0
5959 integer :: start_column = 0
6060 integer :: end_column = 0
61- character (len= :), allocatable :: reason ! "after_return" , "impossible_condition", etc.
61+ character (len= :), allocatable :: reason ! e.g. , "after_return"
6262 character (len= :), allocatable :: code_snippet
6363 contains
6464 procedure :: to_diagnostic = > unreachable_code_to_diagnostic
@@ -101,7 +101,8 @@ module fluff_dead_code_detection
101101 procedure :: analyze_source_code = > detector_analyze_source_ast
102102 procedure :: process_node = > detector_process_node
103103 procedure :: process_indices = > detector_process_indices
104- procedure :: process_parameter_declarations = > detector_process_parameter_declarations
104+ procedure :: process_parameter_declarations = > &
105+ detector_process_parameter_declarations
105106 procedure :: process_node_enhanced = > detector_process_node_enhanced
106107 procedure :: detect_unreachable_code = > detector_detect_unreachable_code
107108 procedure :: mark_subsequent_unreachable = > detector_mark_subsequent_unreachable
@@ -118,7 +119,8 @@ module fluff_dead_code_detection
118119 procedure :: is_unconditional_terminator = > detector_is_unconditional_terminator
119120 procedure :: detect_goto_unreachable_code = > detector_detect_goto_unreachable_code
120121 procedure :: detect_validation_patterns = > detector_detect_validation_patterns
121- procedure :: remove_false_positive_unreachable = > detector_remove_false_positive_unreachable
122+ procedure :: remove_false_positive_unreachable = > &
123+ detector_remove_false_positive_unreachable
122124 procedure :: is_validation_pattern = > detector_is_validation_pattern
123125 procedure :: has_statements_after_return = > detector_has_statements_after_return
124126 end type dead_code_detector_t
@@ -141,8 +143,6 @@ function detector_analyze_source_ast(this, source_code, file_path) result(found_
141143 integer , allocatable :: unreachable_nodes(:)
142144 integer :: i, prog_index
143145
144- print * , source_code
145-
146146 found_dead_code = .false.
147147
148148 ! Clear previous results
@@ -198,9 +198,7 @@ function detector_analyze_source_ast(this, source_code, file_path) result(found_
198198 call this% detect_validation_patterns(source_code)
199199
200200 ! 2. Build call graph for unused procedure detection
201- ! Debug: print *, "Attempting to build call graph for prog_index:", prog_index
202201 this% call_graph = build_call_graph_from_arena(this% arena, prog_index)
203- ! Debug: print *, "Call graph built successfully"
204202 call this% analyze_unused_procedures()
205203
206204 ! 3. Analyze variable usage for unused variables
@@ -273,14 +271,6 @@ subroutine detector_detect_unreachable_code(this)
273271 ! Get the node type using proper fortfront API
274272 node_type = get_node_type_id_from_arena(this% arena, i)
275273
276- ! Debug output disabled
277- ! if (i <= 20) then
278- ! if (this%arena%entries(i)%node_type == "return" .or. &
279- ! this%arena%entries(i)%node_type == "stop" .or. &
280- ! node_type == NODE_RETURN .or. node_type == NODE_STOP) then
281- ! print *, " *** FOUND RETURN/STOP NODE! ***"
282- ! end if
283- ! end if
284274
285275 ! Check if this node is a terminating statement
286276 select case (node_type)
@@ -308,9 +298,6 @@ subroutine detector_detect_unreachable_code(this)
308298 end if
309299 end select
310300
311- ! TODO: Additional check for goto statements
312- ! Temporarily disabled to avoid "Unknown node type" errors
313- ! Will implement when fortfront provides proper goto node constants
314301
315302 ! Also check for impossible conditions (if_node with literal false)
316303 select type (node = > this% arena% entries(i)% node)
@@ -338,20 +325,13 @@ subroutine detector_mark_subsequent_unreachable(this, terminator_idx)
338325 parent_idx = this% arena% entries(terminator_idx)% parent_index
339326 in_same_block = .true.
340327
341- ! Debug: Let's see what we're working with
342- ! print *, "Terminator at index:", terminator_idx, "depth:", terminator_depth, "parent:", parent_idx
343-
344328 ! Look for sibling nodes after the terminator
345329 do i = terminator_idx + 1 , this% arena% size
346330 if (.not. allocated (this% arena% entries(i)% node)) cycle
347331
348- ! Debug: Check each node we examine
349- ! print *, "Examining node", i, "depth:", this%arena%entries(i)%depth, "vs terminator depth:", terminator_depth
350-
351- ! CRITICAL FIX: Stop marking as unreachable if we've left the terminator's immediate block
332+ ! Stop marking as unreachable if we've left the terminator's immediate block
352333 ! If depth is less than terminator, we've exited to a parent scope
353334 if (this% arena% entries(i)% depth < terminator_depth) then
354- ! print *, "Exiting - depth decreased from", terminator_depth, "to", this%arena%entries(i)%depth
355335 exit ! Exited the conditional block - stop marking as unreachable
356336 end if
357337
@@ -471,12 +451,8 @@ subroutine detector_process_node(this, node_index)
471451
472452 ! Get node type for analysis
473453 node_type_id = get_node_type_id_from_arena(this% arena, node_index)
474- ! Convert to string (TODO: use proper type string function when available)
475454 node_type = " unknown"
476455
477- ! TODO: Implement proper node type checking when type string conversion is available
478- ! For now, just do basic processing without type-specific handling
479-
480456 end subroutine detector_process_node
481457
482458 ! Process an array of node indices
@@ -607,23 +583,19 @@ recursive subroutine detector_process_node_enhanced(this, node_index)
607583
608584 type is (subroutine_call_node)
609585 ! Track subroutine calls - simplified due to field access limitations
610- ! TODO: Process name_index and arg_indices when fortfront provides access
611586
612587 type is (print_statement_node)
613588 ! Process print arguments - simplified due to field access limitations
614- ! TODO: Process expr_indices when fortfront provides access
615589
616590 type is (if_node)
617591 ! Process condition and body - limited due to field access limitations
618592 ! We can still check for impossible conditions
619593 if (node% condition_index > 0 ) then
620594 call this% process_node_enhanced(node% condition_index)
621595 end if
622- ! TODO: Process then_body_indices and else_body_indices when fortfront provides access
623596
624597 type is (do_loop_node)
625598 ! Process loop variable and body - simplified due to field access limitations
626- ! TODO: Process var_index, start_index, end_index, step_index, body_indices when fortfront provides access
627599
628600 type is (literal_node)
629601 ! Literals don't contain identifiers to process
@@ -646,26 +618,22 @@ recursive subroutine detector_process_node_enhanced(this, node_index)
646618 if (allocated (node% name)) then
647619 ! Track that this is a defined subroutine
648620 end if
649- ! TODO: Process param_indices and body_indices when fortfront provides access
650621
651622 type is (function_def_node)
652623 ! Process function parameters and body - simplified due to field access limitations
653624 ! Mark the function name if available
654625 if (allocated (node% name)) then
655626 ! Track that this is a defined function
656627 end if
657- ! TODO: Process param_indices and body_indices when fortfront provides access
658628
659629 type is (module_node)
660630 ! Process module body - simplified due to field access limitations
661- ! TODO: Process body_indices when fortfront provides access
662631
663632 type is (return_node)
664633 ! Return statements don't have identifiers but mark control flow
665634
666635 type is (stop_node)
667636 ! Stop statements may have error codes - simplified due to field access limitations
668- ! TODO: Process code_index when fortfront provides access
669637
670638 type is (parameter_declaration_node)
671639 ! Parameter declarations need special handling
@@ -732,14 +700,11 @@ function detector_is_procedure_called(this, proc_name) result(is_called)
732700 do i = 1 , this% arena% size
733701 if (.not. allocated (this% arena% entries(i)% node)) cycle
734702
735- ! TODO: Check for procedure calls when fortfront provides field access
736- ! For now, we can't detect procedure calls due to missing API
703+ ! Check for procedure calls
737704 select type (node = > this% arena% entries(i)% node)
738705 type is (subroutine_call_node)
739- ! Would check node%name_index but can't access fields
740706 is_called = .false. ! Conservative: assume not called
741707 type is (call_or_subscript_node)
742- ! Would check node%base_index but can't access fields
743708 is_called = .false. ! Conservative: assume not called
744709 end select
745710 end do
@@ -755,11 +720,7 @@ subroutine detector_analyze_unused_procedures(this)
755720 ! Get unused procedures from call graph
756721 unused_procedures = get_unused_procedures(this% call_graph)
757722
758- ! Debug: print what we found
759- if (allocated (unused_procedures)) then
760- ! Debug: print *, "Found", size(unused_procedures), "unused procedures"
761- else
762- ! Debug: print *, "No unused procedures array returned"
723+ if (.not. allocated (unused_procedures)) then
763724 return
764725 end if
765726
@@ -771,11 +732,8 @@ subroutine detector_analyze_unused_procedures(this)
771732 is_internal_proc = this% is_internal_procedure(trim (unused_procedures(i)))
772733 is_module_proc = this% is_module_procedure(trim (unused_procedures(i)))
773734
774- ! Debug: print *, "Procedure:", trim(unused_procedures(i)), "Internal:", is_internal_proc, "Module:", is_module_proc
775-
776735 ! Only mark as unused if it's truly an internal or module procedure
777736 if (is_internal_proc .or. is_module_proc) then
778- ! Debug: print *, "Marking unused procedure:", trim(unused_procedures(i))
779737 ! Find the procedure node to get proper location info
780738 node_idx = this% find_procedure_node(trim (unused_procedures(i)))
781739 if (node_idx > 0 ) then
@@ -793,8 +751,6 @@ subroutine detector_analyze_unused_procedures(this)
793751 " unused_procedure" , &
794752 " Unused procedure '" // trim (unused_procedures(i)) // " '" )
795753 end if
796- else
797- ! Debug: print *, "Skipping main/standalone procedure:", trim(unused_procedures(i))
798754 end if
799755 end if
800756 end do
@@ -817,8 +773,6 @@ function detector_is_internal_procedure(this, proc_name) result(is_internal)
817773 return
818774 end if
819775
820- ! TODO: Implement proper AST traversal when fortfront provides better parent-child relationships
821-
822776 end function detector_is_internal_procedure
823777
824778 ! Check if a procedure is a module procedure
@@ -836,8 +790,6 @@ function detector_is_module_procedure(this, proc_name) result(is_module_proc)
836790 return
837791 end if
838792
839- ! TODO: Implement proper AST traversal when fortfront provides better parent-child relationships
840-
841793 end function detector_is_module_procedure
842794
843795 ! Find the AST node index for a procedure by name
@@ -883,17 +835,12 @@ function detector_is_unconditional_terminator(this, terminator_idx) result(is_un
883835 ! Traverse up the parent chain looking for conditional constructs
884836 current_idx = this% arena% entries(terminator_idx)% parent_index
885837
886- ! print *, "Checking if terminator", terminator_idx, "is conditional, first parent:", current_idx
887-
888838 do while (current_idx > 0 .and. current_idx <= this% arena% size)
889839 if (allocated (this% arena% entries(current_idx)% node)) then
890- ! print *, "Parent", current_idx, "exists, type field:", this%arena%entries(current_idx)%node_type
891840 select type (ancestor = > this% arena% entries(current_idx)% node)
892841 type is (if_node)
893842 ! Found an if statement ancestor - this return is conditional
894- ! However, we need to check if this terminates all paths or just this branch
895843 ! For validation functions with early returns, the return is conditional
896- ! print *, "Found if_node ancestor - return is conditional"
897844 is_unconditional = .false.
898845 return
899846 type is (do_loop_node)
@@ -1469,84 +1416,6 @@ subroutine dc_clear(this)
14691416
14701417 end subroutine dc_clear
14711418
1472- ! Handler procedures for different node types using fortfront API
1473- subroutine handle_declaration_node (this , node_index )
1474- class(dead_code_detector_t), intent (inout ) :: this
1475- integer , intent (in ) :: node_index
1476-
1477- ! TODO: Use fortfront API to get declaration details
1478- ! For now, just mark as handled
1479- end subroutine handle_declaration_node
1480-
1481- subroutine handle_identifier_node (this , node_index )
1482- class(dead_code_detector_t), intent (inout ) :: this
1483- integer , intent (in ) :: node_index
1484-
1485- ! TODO: Use fortfront API to get identifier name and mark as used
1486- end subroutine handle_identifier_node
1487-
1488- subroutine handle_assignment_node (this , node_index )
1489- class(dead_code_detector_t), intent (inout ) :: this
1490- integer , intent (in ) :: node_index
1491-
1492- ! TODO: Use fortfront API to get assignment LHS and RHS
1493- end subroutine handle_assignment_node
1494-
1495- subroutine handle_binary_op_node (this , node_index )
1496- class(dead_code_detector_t), intent (inout ) :: this
1497- integer , intent (in ) :: node_index
1498-
1499- ! TODO: Use fortfront API to get operands
1500- end subroutine handle_binary_op_node
1501-
1502- subroutine handle_do_loop_node (this , node_index )
1503- class(dead_code_detector_t), intent (inout ) :: this
1504- integer , intent (in ) :: node_index
1505-
1506- ! TODO: Use fortfront API to get loop variable and bounds
1507- end subroutine handle_do_loop_node
1508-
1509- subroutine handle_call_or_subscript_node (this , node_index )
1510- class(dead_code_detector_t), intent (inout ) :: this
1511- integer , intent (in ) :: node_index
1512-
1513- ! TODO: Use fortfront API to get function name and arguments
1514- end subroutine handle_call_or_subscript_node
1515-
1516- subroutine handle_subroutine_call_node (this , node_index )
1517- class(dead_code_detector_t), intent (inout ) :: this
1518- integer , intent (in ) :: node_index
1519-
1520- ! TODO: Use fortfront API to get subroutine name and arguments
1521- end subroutine handle_subroutine_call_node
1522-
1523- subroutine handle_function_def_node (this , node_index )
1524- class(dead_code_detector_t), intent (inout ) :: this
1525- integer , intent (in ) :: node_index
1526-
1527- ! TODO: Use fortfront API to get function parameters
1528- end subroutine handle_function_def_node
1529-
1530- subroutine handle_subroutine_def_node (this , node_index )
1531- class(dead_code_detector_t), intent (inout ) :: this
1532- integer , intent (in ) :: node_index
1533-
1534- ! TODO: Use fortfront API to get subroutine parameters
1535- end subroutine handle_subroutine_def_node
1536-
1537- subroutine handle_print_statement_node (this , node_index )
1538- class(dead_code_detector_t), intent (inout ) :: this
1539- integer , intent (in ) :: node_index
1540-
1541- ! TODO: Use fortfront API to get print expressions
1542- end subroutine handle_print_statement_node
1543-
1544- subroutine handle_if_node (this , node_index )
1545- class(dead_code_detector_t), intent (inout ) :: this
1546- integer , intent (in ) :: node_index
1547-
1548- ! TODO: Use fortfront API to get condition
1549- end subroutine handle_if_node
15501419
15511420 ! Helper functions for text-based workaround
15521421
0 commit comments