Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Flang] Using BOZ constant as the SOURCE= argument of intrinsic TRANSFER triggered a compile time error. #125769

Open
DanielCChen opened this issue Feb 4, 2025 · 9 comments

Comments

@DanielCChen
Copy link
Contributor

Consider the following code

real(4), parameter :: r4_ep = transfer (Z'34000000', 1.0_4)
end

This seems to be a reasonable extension to use BOZ constant.

Flang is currently disallowing it as

error: Semantic errors in t.f
./t.f:1:41: error: Typeless (BOZ) not allowed for 'source=' argument
  real(4), parameter :: r4_ep = transfer (Z'34000000', 1.0_4)
                                          ^^^^^^^^^^^

Both ifort and XLF compile the code successfully.

@llvmbot
Copy link
Member

llvmbot commented Feb 4, 2025

@llvm/issue-subscribers-flang-frontend

Author: Daniel Chen (DanielCChen)

Consider the following code ``` real(4), parameter :: r4_ep = transfer (Z'34000000', 1.0_4) end

This seems to be a reasonable extension to use BOZ constant.

Flang is currently disallowing it as

error: Semantic errors in t.f
./t.f:1:41: error: Typeless (BOZ) not allowed for 'source=' argument
real(4), parameter :: r4_ep = transfer (Z'34000000', 1.0_4)
^^^^^^^^^^^


Both ifort and XLF compile the code successfully.
</details>

@klausler
Copy link
Contributor

klausler commented Feb 4, 2025

Use the INT or REAL intrinsic function, probably with a KIND= argument, around the BOZ literal, so that it is clear what the size of the BOZ literal is. Without that information the TRANSFER is ambiguous.

@DanielCChen
Copy link
Contributor Author

Use the INT or REAL intrinsic function, probably with a KIND= argument, around the BOZ literal, so that it is clear what the size of the BOZ literal is. Without that information the TRANSFER is ambiguous.

The result type of TRANSFER is based on the MOLD argument, which is real*4 in this case.
Should the compiler be able to figure out the physical representation of the BOZ constant, then compare with the MOLD?

@klausler
Copy link
Contributor

klausler commented Feb 5, 2025

Use the INT or REAL intrinsic function, probably with a KIND= argument, around the BOZ literal, so that it is clear what the size of the BOZ literal is. Without that information the TRANSFER is ambiguous.

The result type of TRANSFER is based on the MOLD argument, which is real*4 in this case. Should the compiler be able to figure out the physical representation of the BOZ constant, then compare with the MOLD?

My point relates to the source, not the mold. Without knowing the size of the source, the semantics of TRANSFER are not well-defined. And the size of a BOZ literal is not well defined in the standard, which is why it is allowed in only a few specific contexts.

@DanielCChen
Copy link
Contributor Author

Right. XLF assumes the type of SOURCE the same as the MOLD and we generate (after remove the PARAMETER attribute)

@r4_ep = internal global float 0x3E80000000000000, align 4

Is it reasonable?

@klausler
Copy link
Contributor

klausler commented Feb 5, 2025

How is 0x3E80000000000000 a 32-bit F.P. value? How is it a reasonable result from transfer (Z'34000000', 1.0_4)?

@DanielCChen
Copy link
Contributor Author

How is 0x3E80000000000000 a 32-bit F.P. value? How is it a reasonable result from transfer (Z'34000000', 1.0_4)?

We implemented the transfer(REAL(Z'34000000'), 1.0_4) as you suggested as a source code wordaround in the compiler.
I supposed I can change our test cases. Just thought this may be a reasonable compiler extension.

@kargl
Copy link

kargl commented Feb 6, 2025

How is 0x3E80000000000000 a 32-bit F.P. value? How is it a reasonable result from transfer (Z'34000000', 1.0_4)?

We implemented the transfer(REAL(Z'34000000'), 1.0_4) as you suggested as a source code wordaround in the compiler. I supposed I can change our test cases. Just thought this may be a reasonable compiler extension.

Gfortran rejects your code.

% gfcx -c a.f90
a.f90:1:40:

 1 | real(4), parameter :: r4_ep = transfer (Z'34000000', 1.0_4)
    |                                        1
 Error: BOZ literal constant at (1) cannot be an actual argument to 'transfer'

Note, a BOZ is defined in F2023 to be typeless. The requirement on SOURCE in 16.9.212
is SOURCE shall be a scalar or array of any type.

@DanielCChen
Copy link
Contributor Author

How is 0x3E80000000000000 a 32-bit F.P. value? How is it a reasonable result from transfer (Z'34000000', 1.0_4)?

We implemented the transfer(REAL(Z'34000000'), 1.0_4) as you suggested as a source code wordaround in the compiler. I supposed I can change our test cases. Just thought this may be a reasonable compiler extension.

Gfortran rejects your code.

% gfcx -c a.f90
a.f90:1:40:

 1 | real(4), parameter :: r4_ep = transfer (Z'34000000', 1.0_4)
    |                                        1
 Error: BOZ literal constant at (1) cannot be an actual argument to 'transfer'

Note, a BOZ is defined in F2023 to be typeless. The requirement on SOURCE in 16.9.212 is SOURCE shall be a scalar or array of any type.

Right. It is not standard conforming. Flang and some other compilers added the extension to allow BOZ to be interchangeable with REAL or INTEGER type. The code in this issue is another case that I think could be added to the extension list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants