Hi Yuao, this relates to conditional expressions/arguments, but not directly to your patch(es).
* * * Short version: I wonder whether resolve_conditional should - if gfc_init_expr_flag is false - optimize expressions like: (one < 0 ? x_min > 0 : one /= 1) to .false. instead of '(.false. ? xmin > 0 : .false.)' As the original expression is not a const expression according to the spec, we cannot always optimize it - as for, e.g., logical, parameter :: cond = ... Here, permitting the expression would be invalid as not being constant according to the spec (not all primaries are constant)¹, even though the expression will always be .false. [¹ cf. '10.1.12 Constant expression' in F2023] * * * I think relying on gfc_init_expr_flag should be sufficient. However, the possible trickier part is to ensure that we don't optimize too early, i.e. we still want to have all diagnostic like .NIL. in arguments etc. * * * Background: Some diagnostic checks and optimizations are done relatively early during the resolution phase, i.e., having a constant instead of an expression helps. However, as most code probably has either all constant or all non-constant expressions, this case should be relatively rare; thus: → This is not of high priority. * * * Background: The issue came up when I was constructing some odder testcases for the patch in the thread [PATCH] OpenMP: Handle 'nothing' with collapse as intervening code [PR120180] https://gcc.gnu.org/pipermail/gcc-patches/2025-October/697868.html Here, the problem is for code like: !$omp ... collapse(2) do i = ... !$omp metadirective when(cond : simd ) do j = ... the loops collapses fine is there is no 'omp simd' and it is invalid if there is. - That hinges on the value of 'cond' and if not known at compile time, GCC errs on the safe side and outputs an error. - Thus, if we know that 'cond' is false, the code can be permitted. The linked-to patch is just about this case - albeit not for conditional expressions but for constants. * * * Test case showing the "issue": SUBROUTINE test4(x_min, x_max, y_min, y_max, vol_flux_x) IMPLICIT NONE INTEGER, INTENT(IN) :: x_min, x_max, y_min, y_max REAL(KIND=8), DIMENSION(x_min:x_max,y_min:y_max) :: vol_flux_x INTEGER :: j,k integer, parameter :: one = 1 !$omp do collapse(2) DO k=y_min,y_max !$omp metadirective & !$omp& when(user={condition((one < 0 ? x_min > 0 : one /= 1))}: simd) DO j=x_min,x_max vol_flux_x(j,k)=0.25_8 ENDDO ENDDO END SUBROUTINE test4 → Yielding the error: 8 | !$omp do collapse(2) | 1 Error: not enough DO loops for collapsed !$OMP DO (level 1) at (1) * * * For completeness, the simplification happens in gfc_match_omp_context_selector as follows: if (!gfc_resolve_expr (otp->expr) || (property_kind == OMP_TRAIT_PROPERTY_BOOL_EXPR && otp->expr->ts.type != BT_LOGICAL) as mentioned, that works fine - but yields the non-const expression '(.false. ? x_min > 0 : .false.)'. NOTE: The code above is actually bad in the sense that it simplifies to early - during parsing - instead during resolution. It shouldn't matter for the case being discussed, but there are cases where it fails - hence, it will eventually have to be moved to the resolution stage → https://gcc.gnu.org/PR122306 * * * Thanks, Tobias
