Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28945 Discussions

ICE with bounds violation in constant expression

Harald1
New Contributor II
1,402 Views

Hello,

this snippet of invalid Fortran crashes current ifort/ifx:

program p
  implicit none
  integer :: i
  integer, parameter :: a(0) = 0
  integer, parameter :: b(*) = [(a(i:i), i=0,0)]  ! ICE-on-invalid
end

 I get:

% ifort ifort-bounds.f90
ifort-bounds.f90(1): catastrophic error: **Internal compiler error: internal abort** Please report this error along with the circumstances in which it occurred in a Software Problem Report.  Note: File and line given may not be explicit cause of this error.
compilation aborted for ifort-bounds.f90 (code 1)

and a more extended traceback with ifx.

Thanks,

Harald

 

 

1 Solution
Shiquan_Su
Moderator
348 Views

The first statement

 integer, parameter :: a(0) = 0

is legal, contrary to what the person on the forum said. Here are some quotes from the standard to say why:

8.4 Initialization

...

If initialization is = constant-expr, the variable is initially defined with the value specified by the constant-expr; if necessary, the value is converted according to the rules of intrinsic assignment (10.2.1.3) to a value that agrees in type, type parameters, and shape with the variable.

...

10.2.1.3 Interpretation of intrinsic assignments

...

If expr is a scalar and the variable is an array, the expr is treated as if it were an array of the same shape as the variable with every element of the array equal to the scalar value of expr.

So the 0 value here is converted to an array of size 0. I.e., the effective initialization is  [ integer :: ] .

The problem is the second statement

 integer, parameter :: b( * ){{ = [(a(i:i), i=0,0)]}}

the only illegal thing here is that this implied-do, which has one iteration of i=0, gets a size-1 section of "a" at index 0, which is illegal because "a" is size 0. The text from the standard, 9.5.3.3.1 Section subscript lists, applies:

Each subscript in a [section-subscript-list] shall be within the bounds for its dimension unless the sequence is empty.

If the statement were instead

 integer, parameter :: b( * ) = [(a(i:i), i=1,0)]

then this would be legal, because the implied-do now has a zero iteration count, and so a(i:i) is not evaluated, and so "a" doesn't get accessed at an invalid index.


View solution in original post

0 Kudos
9 Replies
Barbara_P_Intel
Employee
1,373 Views

@Harald1, thank you for reporting this. I know I say this often; thank you, too, for the simple reproducer.

I filed a bug report, CMPLRLLVM-47855. I'll let you know when there's a fix.

Glad this is not a show-stopper for you!



0 Kudos
jimdempseyatthecove
Honored Contributor III
1,367 Views

Harald, Barbara,

While ICE shouldn't happen, isn't

    integer, parameter :: a(0) = 0

also an erroneous statement?

While a zero sized array is supported, wouldn't the initializer (=0) be in error. I suppose they may be considered valid as array=scalar sets the initializer into the size of the array, and size being zero would result in nothing done. However, this presents a paradox in that the array does not contain all 0's.

In the first parameter the (0) is the size of the array.

An error should have been reported on the a(i) in the next statement, when i=0 as this would be an index out of bounds.

Jim Dempsey

Harald1
New Contributor II
1,348 Views

In Fortran, you can assign a scalar to an array of any rank and shape, even if its size is zero.

Similarly, you can have a "named constant" (e.g. F2023, 8.5.13 PARAMETER attribute) with a value defined by a constant expression which is a scalar for any rank and shape.

Sometimes one just needs such a constant object of the right type, kind, rank (and value) in a program...

(Fortran even allows loops with zero trip counts...)

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,327 Views

I wasn't objecting to a zero sized array.

I wasn't objecting to indexing a zero sized array with the expectation that an out of bounds error can be raised (in this case at compile time)

I was objecting to:

you>>value defined...

me>this presents a paradox in that the array does not contain all 0's

IOW the value is not defined.

The ICE shouldn't happen, and thanks for bringing this up for Intel to address.

Jim Dempsey

 

0 Kudos
Harald1
New Contributor II
1,302 Views

There is no paradox.  If the lhs has size zero, then there is nothing to do, and the initializer is effectively empty.

 

Of course one can write the declaration using an array constructor on the rhs, like:

 

integer, parameter :: a(0) = [ integer :: ]

 

Things may get cumbersome for arrays of higher rank.  So one could either write

 

  integer, parameter :: b(0,42) = 0

 

or

 

integer, parameter :: b(0,42) = reshape ([ integer :: ], shape=shape (b))

 

The scalar initializer is even plain Fortran 90, while the array constructor with type-spec is Fortran 2003.  I find the versions with a scalar initializer much more readable.

(For experts in code obfuscation, there are other funny initializers possible for rank > 1, using e.g. spread).

 

0 Kudos
Shiquan_Su
Moderator
349 Views

The first statement

 integer, parameter :: a(0) = 0

is legal, contrary to what the person on the forum said. Here are some quotes from the standard to say why:

8.4 Initialization

...

If initialization is = constant-expr, the variable is initially defined with the value specified by the constant-expr; if necessary, the value is converted according to the rules of intrinsic assignment (10.2.1.3) to a value that agrees in type, type parameters, and shape with the variable.

...

10.2.1.3 Interpretation of intrinsic assignments

...

If expr is a scalar and the variable is an array, the expr is treated as if it were an array of the same shape as the variable with every element of the array equal to the scalar value of expr.

So the 0 value here is converted to an array of size 0. I.e., the effective initialization is  [ integer :: ] .

The problem is the second statement

 integer, parameter :: b( * ){{ = [(a(i:i), i=0,0)]}}

the only illegal thing here is that this implied-do, which has one iteration of i=0, gets a size-1 section of "a" at index 0, which is illegal because "a" is size 0. The text from the standard, 9.5.3.3.1 Section subscript lists, applies:

Each subscript in a [section-subscript-list] shall be within the bounds for its dimension unless the sequence is empty.

If the statement were instead

 integer, parameter :: b( * ) = [(a(i:i), i=1,0)]

then this would be legal, because the implied-do now has a zero iteration count, and so a(i:i) is not evaluated, and so "a" doesn't get accessed at an invalid index.


0 Kudos
Harald1
New Contributor II
325 Views

I am afraid that I have to pour some water into the wine: the issue may be fixed for rank-1, but the following still crashes ifx 2025.0:

program p
  implicit none
  integer :: i
  integer, parameter :: b(0,42) = 0
  integer, parameter :: d(*) = [(b(i:i,1), i=1,1)]  ! ICE-on-invalid
end

I get:

% ifx ifx-bounds.f90
 #0 0x00000000031715d7 (/opt/intel/oneapi/compiler/2025.0/bin/compiler/xfortcom+0x31715d7)
 #1 0x0000000003171705 (/opt/intel/oneapi/compiler/2025.0/bin/compiler/xfortcom+0x3171705)
 #2 0x00007fda9ec2ddc0 __restore_rt (/lib64/libc.so.6+0x4adc0)
 #3 0x00000000031883d8 (/opt/intel/oneapi/compiler/2025.0/bin/compiler/xfortcom+0x31883d8)
 #4 0x000000000318807a (/opt/intel/oneapi/compiler/2025.0/bin/compiler/xfortcom+0x318807a)
 #5 0x00000000030e5fd1 (/opt/intel/oneapi/compiler/2025.0/bin/compiler/xfortcom+0x30e5fd1)
 #6 0x00000000030e35ab (/opt/intel/oneapi/compiler/2025.0/bin/compiler/xfortcom+0x30e35ab)
 #7 0x00000000030f35d4 (/opt/intel/oneapi/compiler/2025.0/bin/compiler/xfortcom+0x30f35d4)
 #8 0x0000000003142b28 (/opt/intel/oneapi/compiler/2025.0/bin/compiler/xfortcom+0x3142b28)
 #9 0x0000000003141867 (/opt/intel/oneapi/compiler/2025.0/bin/compiler/xfortcom+0x3141867)
#10 0x0000000003140c43 (/opt/intel/oneapi/compiler/2025.0/bin/compiler/xfortcom+0x3140c43)
#11 0x0000000003053970 (/opt/intel/oneapi/compiler/2025.0/bin/compiler/xfortcom+0x3053970)
#12 0x0000000003053317 (/opt/intel/oneapi/compiler/2025.0/bin/compiler/xfortcom+0x3053317)
#13 0x000000000322f884 (/opt/intel/oneapi/compiler/2025.0/bin/compiler/xfortcom+0x322f884)
#14 0x00007fda9ec1824d __libc_start_main (/lib64/libc.so.6+0x3524d)
#15 0x0000000002e8a34e (/opt/intel/oneapi/compiler/2025.0/bin/compiler/xfortcom+0x2e8a34e)

ifx-bounds.f90: error #5633: **Internal compiler error: segmentation violation signal raised** Please report this error along with the circumstances in which it occurred in a Software Problem Report.  Note: File and line given may not be explicit cause of this error.
compilation aborted for ifx-bounds.f90 (code 3)

So it is not really fully fixed.

 Harald

 

0 Kudos
andrew_4619
Honored Contributor III
320 Views
I actually don't see anyone saying it is fixed.
0 Kudos
JohnNichols
Valued Contributor III
269 Views

Screenshot 2024-12-14 100611.png

a does not exist as an integer, it has a memory location but is not initialized, you cannot use a(0,0) or any array size combination to work.  

As soon as you start to use a in the next line, you are way outside Fortran's IFX or IFORT ability. 

Screenshot 2024-12-14 100620.png

Fortran arrays appear to start at 1 is you do this. 

Screenshot 2024-12-14 095208.png

If I change the b to b(1,42) I end up with a constant array of 42 elements that are 42. 

 

Screenshot 2024-12-14 093010.png

B does not legally exist in Fortran in a form that can be used. 

 

a(0) is legal but it is the same as ~ squiggle in the numbers 0 to 9, there are no rules.  

Screenshot 2024-12-14 101713.png

if you go with a(0) it is missing the stride, and the implicit 1 does not work in Intel Fortran



 

 

0 Kudos
Reply