CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
287 lines
9.0 KiB
Fortran
287 lines
9.0 KiB
Fortran
! RUN: %flang_fc1 -fdebug-unparse-no-sema %s 2>&1 | FileCheck %s
|
|
! RUN: %flang_fc1 -fdebug-dump-parse-tree-no-sema %s 2>&1 | FileCheck %s -check-prefix=TREE
|
|
|
|
! Test parsing of conditional expressions (Fortran 2023 R1002)
|
|
|
|
! Simple two-branch conditional
|
|
subroutine simple_conditional(x, y, z)
|
|
integer :: x, y, z
|
|
! CHECK-LABEL: simple_conditional
|
|
! CHECK: z = ( x>5 ? y : 10 )
|
|
! TREE: ConditionalExpr
|
|
! TREE-NEXT: Scalar -> Logical -> Expr
|
|
! TREE: Expr -> Designator -> DataRef -> Name = 'y'
|
|
! TREE: Expr -> LiteralConstant -> IntLiteralConstant = '10'
|
|
z = (x > 5 ? y : 10)
|
|
end subroutine
|
|
|
|
! Three-branch conditional (multiple conditions)
|
|
subroutine multi_branch_conditional(x, y, z)
|
|
integer :: x, y, z
|
|
! CHECK-LABEL: multi_branch_conditional
|
|
! CHECK: z = ( x>10 ? 100 : ( y<5 ? 50 : 0 ) )
|
|
! TREE: ConditionalExpr
|
|
! TREE-NEXT: Scalar -> Logical -> Expr
|
|
! TREE: Expr -> LiteralConstant -> IntLiteralConstant = '100'
|
|
! TREE: Expr -> ConditionalExpr
|
|
! TREE: Scalar -> Logical -> Expr
|
|
! TREE: Expr -> LiteralConstant -> IntLiteralConstant = '50'
|
|
! TREE: Expr -> LiteralConstant -> IntLiteralConstant = '0'
|
|
z = (x > 10 ? 100 : y < 5 ? 50 : 0)
|
|
end subroutine
|
|
|
|
! Nested conditionals
|
|
subroutine nested_conditionals(x, y, w, z, flag1, flag2)
|
|
integer :: x, y, w, z
|
|
logical :: flag1, flag2
|
|
! CHECK-LABEL: nested_conditionals
|
|
! Nested in value position
|
|
! CHECK: z = ( flag1 ? ( x>y ? x : y ) : 0 )
|
|
! TREE: ConditionalExpr
|
|
! TREE-NEXT: Scalar -> Logical -> Expr
|
|
! TREE: Expr -> ConditionalExpr
|
|
! TREE: Scalar -> Logical -> Expr
|
|
! TREE: Expr -> Designator -> DataRef -> Name = 'x'
|
|
! TREE: Expr -> Designator -> DataRef -> Name = 'y'
|
|
! TREE: Expr -> LiteralConstant -> IntLiteralConstant = '0'
|
|
z = (flag1 ? (x > y ? x : y) : 0)
|
|
! Nested in condition
|
|
! CHECK: z = ( ( x>5 ? flag1 : flag2 ) ? y : 10 )
|
|
z = ((x > 5 ? flag1 : flag2) ? y : 10)
|
|
! Multiple nested
|
|
! CHECK: z = ( x>10 ? ( y>20 ? 1 : 2 ) : ( w>30 ? 3 : 4 ) )
|
|
z = (x > 10 ? (y > 20 ? 1 : 2) : (w > 30 ? 3 : 4))
|
|
end subroutine
|
|
|
|
! Basic type conditionals
|
|
subroutine basic_types(x, a, b, c, flag1, str1)
|
|
integer :: x
|
|
real :: a, b, c
|
|
logical :: flag1
|
|
character(len=10) :: str1
|
|
! CHECK-LABEL: basic_types
|
|
! Real type
|
|
! CHECK: c = ( a>b ? a : b )
|
|
c = (a > b ? a : b)
|
|
! Logical type
|
|
! CHECK: flag1 = ( x>5 ? .TRUE. : .FALSE. )
|
|
flag1 = (x > 5 ? .true. : .false.)
|
|
! Character type
|
|
! CHECK: str1 = ( flag1 ? "HELLO" : "WORLD" )
|
|
str1 = (flag1 ? "HELLO" : "WORLD")
|
|
end subroutine
|
|
|
|
! Complex expressions in conditions and branches
|
|
subroutine complex_expressions(x, y, z, flag1)
|
|
integer :: x, y, z
|
|
logical :: flag1
|
|
! CHECK-LABEL: complex_expressions
|
|
! Complex expressions in branches
|
|
! CHECK: z = ( x>y ? x*2+1 : y*3-2 )
|
|
z = (x > y ? x*2+1 : y*3-2)
|
|
! Complex logical condition
|
|
! CHECK: z = ( x>5.AND.y<10 ? x+y : x-y )
|
|
z = (x > 5 .and. y < 10 ? x+y : x-y)
|
|
! Logical NOT
|
|
! CHECK: z = ( .NOT.flag1 ? x : y )
|
|
z = (.not. flag1 ? x : y)
|
|
! Comparison chains
|
|
! CHECK: z = ( x>5.AND.x<10 ? x : 0 )
|
|
z = (x > 5 .and. x < 10 ? x : 0)
|
|
! Parenthesized expressions in branches
|
|
! CHECK: z = ( x>5 ? (y+z) : (y-z) )
|
|
z = (x > 5 ? (y+z) : (y-z))
|
|
end subroutine
|
|
|
|
! Many-branch conditionals
|
|
subroutine many_branches(x, z)
|
|
integer :: x, z
|
|
! CHECK-LABEL: many_branches
|
|
! Four branches
|
|
! CHECK: z = ( x>10 ? 100 : ( x>5 ? 50 : ( x>0 ? 10 : 0 ) ) )
|
|
z = (x > 10 ? 100 : x > 5 ? 50 : x > 0 ? 10 : 0)
|
|
! Five branches
|
|
! CHECK: z = ( x>20 ? 1 : ( x>15 ? 2 : ( x>10 ? 3 : ( x>5 ? 4 : 5 ) ) ) )
|
|
z = (x > 20 ? 1 : x > 15 ? 2 : x > 10 ? 3 : x > 5 ? 4 : 5)
|
|
end subroutine
|
|
|
|
! Conditionals with arrays and functions
|
|
subroutine arrays_and_functions(x, y, z, arr, flag1)
|
|
integer :: x, y, z, arr(5)
|
|
logical :: flag1
|
|
! CHECK-LABEL: arrays_and_functions
|
|
! Array element in conditional
|
|
! CHECK: z = ( arr(1)>arr(2) ? arr(1) : arr(2) )
|
|
z = (arr(1) > arr(2) ? arr(1) : arr(2))
|
|
! Function calls in conditional
|
|
! CHECK: x = ( abs(y)>10 ? abs(y) : y )
|
|
x = (abs(y) > 10 ? abs(y) : y)
|
|
! Array constructor elements
|
|
! CHECK: arr(1:3) = [( flag1 ? x : y ), ( .NOT.flag1 ? x : y ), ( x>y ? x : y )]
|
|
arr(1:3) = [(flag1 ? x : y), (.not. flag1 ? x : y), (x > y ? x : y)]
|
|
end subroutine
|
|
|
|
! Literals in conditionals
|
|
subroutine literals(x, z, a, c)
|
|
integer :: x, z
|
|
real :: a, c
|
|
! CHECK-LABEL: literals
|
|
! Real literals
|
|
! CHECK: c = ( a>0.0 ? 1.5 : 2.5 )
|
|
c = (a > 0.0 ? 1.5 : 2.5)
|
|
! Negative values
|
|
! CHECK: z = ( x<0 ? -1 : 1 )
|
|
z = (x < 0 ? -1 : 1)
|
|
end subroutine
|
|
|
|
! Conditional in specification expression context
|
|
function spec_expr_conditional(n, flag) result(res)
|
|
integer, intent(in) :: n
|
|
logical, intent(in) :: flag
|
|
integer :: res
|
|
! CHECK-LABEL: spec_expr_conditional
|
|
! CHECK: res = ( flag ? n*2 : n )
|
|
res = (flag ? n*2 : n)
|
|
end function
|
|
|
|
! Conditional with different integer kinds
|
|
subroutine integer_kinds(cond)
|
|
integer(kind=4) :: i4a, i4b, i4c
|
|
integer(kind=8) :: i8a, i8b, i8c
|
|
logical :: cond
|
|
! CHECK-LABEL: integer_kinds
|
|
! CHECK: i4c = ( cond ? i4a : i4b )
|
|
i4c = (cond ? i4a : i4b)
|
|
! CHECK: i8c = ( cond ? i8a : i8b )
|
|
i8c = (cond ? i8a : i8b)
|
|
end subroutine
|
|
|
|
! Conditional with different real kinds
|
|
subroutine real_kinds(cond)
|
|
real(kind=4) :: r4a, r4b, r4c
|
|
real(kind=8) :: r8a, r8b, r8c
|
|
logical :: cond
|
|
! CHECK-LABEL: real_kinds
|
|
! CHECK: r4c = ( cond ? r4a : r4b )
|
|
r4c = (cond ? r4a : r4b)
|
|
! CHECK: r8c = ( cond ? r8a : r8b )
|
|
r8c = (cond ? r8a : r8b)
|
|
end subroutine
|
|
|
|
! Conditional in various statement contexts
|
|
subroutine statement_contexts(flag)
|
|
integer :: x, y, arr(10)
|
|
logical :: flag
|
|
! CHECK-LABEL: statement_contexts
|
|
! In array constructor
|
|
! CHECK: arr(1:3) = [1, ( flag ? x : y ), 3]
|
|
arr(1:3) = [1, (flag ? x : y), 3]
|
|
! In if statement condition
|
|
! CHECK: IF (( flag ? x : y )>5) THEN
|
|
if ((flag ? x : y) > 5) then
|
|
x = 1
|
|
end if
|
|
! In print statement
|
|
! CHECK: PRINT *, ( flag ? x : y )
|
|
print *, (flag ? x : y)
|
|
! In assignment to array element
|
|
! CHECK: arr(5) = ( flag ? x : y )
|
|
arr(5) = (flag ? x : y)
|
|
end subroutine
|
|
|
|
! Complex type conditionals
|
|
subroutine complex_type(flag)
|
|
complex :: c1, c2, c3
|
|
complex(kind=8) :: c8a, c8b, c8c
|
|
logical :: flag
|
|
! CHECK-LABEL: complex_type
|
|
! CHECK: c3 = ( flag ? c1 : c2 )
|
|
c3 = (flag ? c1 : c2)
|
|
! CHECK: c8c = ( flag ? c8a : c8b )
|
|
c8c = (flag ? c8a : c8b)
|
|
! With complex literals
|
|
! CHECK: c3 = ( flag ? (1.0,2.0) : (3.0,4.0) )
|
|
c3 = (flag ? (1.0, 2.0) : (3.0, 4.0))
|
|
end subroutine
|
|
|
|
! Array-valued conditionals (F2023 10.1.4)
|
|
subroutine array_valued(flag)
|
|
integer :: arr1(5), arr2(5), arr3(5)
|
|
real :: mat1(3,3), mat2(3,3), mat3(3,3)
|
|
logical :: flag
|
|
! CHECK-LABEL: array_valued
|
|
! Whole array conditional
|
|
! CHECK: arr3 = ( flag ? arr1 : arr2 )
|
|
! TREE: ConditionalExpr
|
|
! TREE-NEXT: Scalar -> Logical -> Expr
|
|
! TREE: Expr -> Designator -> DataRef -> Name = 'arr1'
|
|
! TREE: Expr -> Designator -> DataRef -> Name = 'arr2'
|
|
arr3 = (flag ? arr1 : arr2)
|
|
! Multidimensional array conditional
|
|
! CHECK: mat3 = ( flag ? mat1 : mat2 )
|
|
mat3 = (flag ? mat1 : mat2)
|
|
! Array section conditional
|
|
! CHECK: arr3(1:3) = ( flag ? arr1(1:3) : arr2(1:3) )
|
|
arr3(1:3) = (flag ? arr1(1:3) : arr2(1:3))
|
|
end subroutine
|
|
|
|
! Derived type conditionals
|
|
subroutine derived_types(flag)
|
|
type :: point
|
|
real :: x, y
|
|
end type
|
|
type(point) :: p1, p2, p3
|
|
logical :: flag
|
|
! CHECK-LABEL: derived_types
|
|
! CHECK: p3 = ( flag ? p1 : p2 )
|
|
p3 = (flag ? p1 : p2)
|
|
end subroutine
|
|
|
|
! Character with different lengths
|
|
subroutine character_lengths(flag)
|
|
character(len=5) :: short1, short2
|
|
character(len=10) :: medium1, medium2
|
|
character(len=20) :: long_result
|
|
logical :: flag
|
|
! CHECK-LABEL: character_lengths
|
|
! Same length characters
|
|
! CHECK: short1 = ( flag ? "HELLO" : "WORLD" )
|
|
short1 = (flag ? "HELLO" : "WORLD")
|
|
! Different length literals (type conformance rules apply)
|
|
! CHECK: long_result = ( flag ? "SHORT" : "MUCH LONGER STRING" )
|
|
long_result = (flag ? "SHORT" : "MUCH LONGER STRING")
|
|
! Mixed variables and literals
|
|
! CHECK: medium1 = ( flag ? short1 : medium2 )
|
|
medium1 = (flag ? short1 : medium2)
|
|
end subroutine
|
|
|
|
! Verify that '?' inside string literals and comments does not interfere
|
|
! with conditional expression parsing.
|
|
subroutine question_mark_chars(flag, str1, str2, str3)
|
|
logical :: flag
|
|
character(len=20) :: str1, str2, str3
|
|
! CHECK-LABEL: question_mark_chars
|
|
! CHECK: str1 = "HELLO?"
|
|
str1 = "HELLO?"
|
|
! CHECK: str2 = ( flag ? "YES?" : "NO?" )
|
|
str2 = (flag ? "YES?" : "NO?")
|
|
! CHECK: str3 = "WHAT? WHY? HOW?"
|
|
str3 = "WHAT? WHY? HOW?" ! ? in a comment
|
|
! CHECK: str2 = ( flag ? "MAYBE?" : "NOPE" )
|
|
str2 = (flag ? "MAYBE?" : "NOPE") ! ? in a trailing comment
|
|
end subroutine
|
|
|
|
! Verify that '(' and ')' inside character literals are handled correctly by
|
|
! ConditionalExprLookahead.
|
|
subroutine paren_in_char_literal(c, i)
|
|
character(*), intent(in) :: c
|
|
integer, intent(out) :: i
|
|
! CHECK-LABEL: paren_in_char_literal
|
|
! CHECK: i = ( c==")" ? 1 : 2 )
|
|
i = (c == ")" ? 1 : 2)
|
|
! CHECK: i = ( c=="(" ? 1 : 2 )
|
|
i = (c == "(" ? 1 : 2)
|
|
! CHECK: i = ( c=="()" ? 1 : 2 )
|
|
i = (c == "()" ? 1 : 2)
|
|
end subroutine
|