[flang-commits] [flang] [flang] Implement conditional expressions parser/semantics (F2023) (PR #186489)

Caroline Newcombe via flang-commits flang-commits at lists.llvm.org
Mon Apr 6 08:27:50 PDT 2026


================
@@ -0,0 +1,408 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+! Test semantic analysis of conditional expressions (Fortran 2023)
+
+! Valid cases with basic types
+subroutine valid_basic_types(flag)
+  logical :: flag
+  integer :: i1, i2, i3
+  real :: r1, r2, r3
+  complex :: c1, c2, c3
+  logical :: l1, l2, l3
+  character(len=5) :: ch1, ch2, ch3
+
+  ! INTEGER conditionals
+  i3 = (flag ? i1 : i2)
+
+  ! REAL conditionals
+  r3 = (flag ? r1 : r2)
+
+  ! COMPLEX conditionals
+  c3 = (flag ? c1 : c2)
+
+  ! LOGICAL conditionals
+  l3 = (flag ? l1 : l2)
+
+  ! CHARACTER conditionals
+  ch3 = (flag ? ch1 : ch2)
+end subroutine
+
+! Valid cases with same kind
+subroutine valid_same_kind(flag)
+  logical :: flag
+  integer(kind=4) :: i4a, i4b, i4c
+  integer(kind=8) :: i8a, i8b, i8c
+  real(kind=4) :: r4a, r4b, r4c
+  real(kind=8) :: r8a, r8b, r8c
+
+  ! Same kind - valid
+  i4c = (flag ? i4a : i4b)
+  i8c = (flag ? i8a : i8b)
+  r4c = (flag ? r4a : r4b)
+  r8c = (flag ? r8a : r8b)
+end subroutine
+
+! Valid cases with literals
+subroutine valid_literals(flag)
+  logical :: flag
+  integer :: i
+  real :: r
+  character(len=10) :: ch
+
+  i = (flag ? 10 : 20)
+  r = (flag ? 1.0 : 2.0)
+  ch = (flag ? "HELLO" : "WORLD")
+end subroutine
+
+! Valid cases with nested conditionals
+subroutine valid_nested(flag1, flag2, x, y, z, w)
+  logical :: flag1, flag2
+  integer :: x, y, z, w, result
+
+  ! Nested in value position
+  result = (flag1 ? (flag2 ? x : y) : z)
+
+  ! Nested in condition (condition is logical)
+  result = ((x > y ? flag1 : flag2) ? w : z)
+
+  ! Multi-branch
+  result = (x > 10 ? 100 : x > 5 ? 50 : 0)
+end subroutine
+
+! Valid cases with arrays
+subroutine valid_arrays(flag)
+  logical :: flag
+  integer :: arr1(10), arr2(10), arr3(10)
+  real :: mat1(3,3), mat2(3,3), mat3(3,3)
+
+  ! Whole array conditional
+  arr3 = (flag ? arr1 : arr2)
+
+  ! Multidimensional arrays
+  mat3 = (flag ? mat1 : mat2)
+
+  ! Array sections
+  arr3(1:5) = (flag ? arr1(1:5) : arr2(1:5))
+end subroutine
+
+! Valid cases with derived types
+subroutine valid_derived_types(flag)
+  type :: point
+    real :: x, y
+  end type
+
+  logical :: flag
+  type(point) :: p1, p2, p3
+
+  p3 = (flag ? p1 : p2)
+end subroutine
+
+! Valid cases with character lengths
+subroutine valid_character_lengths(flag)
+  logical :: flag
+  character(len=5) :: short1, short2, short3
+  character(len=10) :: medium
+  character(len=20) :: long
+
+  ! Same length
+  short3 = (flag ? short1 : short2)
+
+  ! Different lengths - padding/truncation applies
+  medium = (flag ? short1 : medium)
+  long = (flag ? short1 : "A LONGER STRING")
+end subroutine
+
+! Valid: deferred-length character scalars
+subroutine valid_deferred_length_character(flag)
+  logical :: flag
+  character(len=:), allocatable :: str1, str2, result
+
+  str1 = "SHORT"
+  str2 = "A MUCH LONGER STRING"
+  ! Result length is determined by selected branch
+  result = (flag ? str1 : str2)
+end subroutine
+
+! Valid: assumed-length character arguments
+subroutine valid_assumed_length_character(flag, str1, str2)
+  logical :: flag
+  character(len=*) :: str1, str2
+  character(len=100) :: result
+
+  result = (flag ? str1 : str2)
+end subroutine
+
+! Error: condition must be logical
+subroutine error_non_logical_condition()
+  integer :: i, x, y
+  real :: r
+  character :: ch
+
+  !ERROR: Must have LOGICAL type, but is INTEGER(4)
+  i = (i ? x : y)
+
+  !ERROR: Must have LOGICAL type, but is REAL(4)
+  i = (r ? x : y)
+
+  !ERROR: Must have LOGICAL type, but is CHARACTER(KIND=1,LEN=1_8)
+  i = (ch ? x : y)
+end subroutine
+
+! Error: type mismatch between branches
+subroutine error_type_mismatch(flag)
+  logical :: flag
+  integer :: i1, i2
+  real :: r
+  character :: ch
+  complex :: c
+
+  !ERROR: All values in conditional expression must have the same type and kind; have INTEGER(4) and REAL(4)
+  i1 = (flag ? i2 : r)
+
+  !ERROR: All values in conditional expression must have the same type and kind; have INTEGER(4) and CHARACTER(KIND=1,LEN=1_8)
+  i1 = (flag ? i2 : ch)
+
+  !ERROR: All values in conditional expression must have the same type and kind; have REAL(4) and COMPLEX(4)
+  r = (flag ? r : c)
+
+  !ERROR: All values in conditional expression must have the same type and kind; have LOGICAL(4) and INTEGER(4)
+  flag = (flag ? flag : i1)
+end subroutine
+
+! Error: kind mismatch (F2023 C1004)
+subroutine error_kind_mismatch(flag)
+  logical :: flag
+  integer(kind=4) :: i4
+  integer(kind=8) :: i8
+  real(kind=4) :: r4
+  real(kind=8) :: r8
+  complex(kind=4) :: c4
+  complex(kind=8) :: c8
+
+  !ERROR: All values in conditional expression must have the same type and kind; have INTEGER(4) and INTEGER(8)
+  i4 = (flag ? i4 : i8)
+
+  !ERROR: All values in conditional expression must have the same type and kind; have REAL(4) and REAL(8)
+  r4 = (flag ? r4 : r8)
+
+  !ERROR: All values in conditional expression must have the same type and kind; have COMPLEX(4) and COMPLEX(8)
+  c4 = (flag ? c4 : c8)
+end subroutine
+
+! Error: derived type mismatch
+subroutine error_derived_type_mismatch(flag)
+  type :: type1
+    integer :: i
+  end type
+
+  type :: type2
+    integer :: i
+  end type
+
+  logical :: flag
+  type(type1) :: t1
+  type(type2) :: t2
+
+  !ERROR: All values in conditional expression must be the same derived type; have type1 and type2
+  t1 = (flag ? t1 : t2)
----------------
cenewcombe wrote:

These test cases have been added.

https://github.com/llvm/llvm-project/pull/186489


More information about the flang-commits mailing list