- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
We recently upgraded to VS 2022 17.7.7 with the latest OneAPI.
Compiling with Intelr Fortran Compiler Classic 2021.11.0 [Intel(R) 64]...
What used to be spurious warnings about function return values not being defined, are now hard error, here's the diagnostics:
$ cmake --build . -j 8 --target ALL_BUILD --config Release
Microsoft Visual Studio 2022 Version 17.7.7.
Copyright (C) Microsoft Corp. All rights reserved.
Build started...
1>------ Build started: Project: always_check_git, Configuration: Release x64 ------
2>------ Build started: Project: libmelcor, Configuration: Release x64 ------
Compiling with Intelr Fortran Compiler Classic 2021.11.0 [Intel(R) 64]...
graph_sm.f90
src\modernization\graph_sm.f90(357): error #6178: The return value of this FUNCTION has not been defined. [NUM_UNDIRECTED_VERTICES]
src\modernization\graph_sm.f90(363): error #6178: The return value of this FUNCTION has not been defined. [NUM_UNDIRECTED_EDGES]
src\modernization\graph_sm.f90(427): error #6178: The return value of this FUNCTION has not been defined. [FIND_UNDIRECTED_EDGE]
src\modernization\graph_sm.f90(493): error #6178: The return value of this FUNCTION has not been defined. [INSERT_UNDIRECTED_EDGE]
src\modernization\graph_sm.f90(663): error #6178: The return value of this FUNCTION has not been defined. [EDGE_UDG]
src\modernization\graph_sm.f90(677): error #6178: The return value of this FUNCTION has not been defined. [EDGE_DG]
The function for the first error above is declared in a module interface as follow:
interface num_vertices
module function num_undirected_vertices(self) result(n)
type(graph_t), intent(in) :: self
integer(int_kind) :: n
end function
end interface
and the implementation is in a submodule as follows:
module function num_undirected_vertices(self) result(n)
type(graph_t), intent(in) :: self
integer(int_kind) :: n
n = self%num_vertices
end function
It appears to us (and to gfortran) that this is valid code, is the compiler diagnostic wrong or is there something wrong with our code?. Any ideas?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
well I never see such errors something is confusing he compiler. Some thoughts is int_kind a non-default integer? what is the type/kind of self%num_vertices?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
integer, parameter :: int_kind = 4
type :: graph_t
type(multimap_ik_t) :: adjacency
type(vertex_container_t), pointer :: vertices(:) => null()
type(edge_container_t), pointer :: edges(:) => null()
integer(int_kind) :: num_edges = zero_ik
integer(int_kind) :: num_vertices = zero_ik
integer(int_kind) :: size_edges = ten_ik
integer(int_kind) :: size_vertices = ten_ik
contains
procedure :: breadth_first_traversal
final :: destruct_graph
end type
Note that both ifort and ifx used to complain (warn) about this code, now they both give errors with latest OneAPI. Further, we see the exact same behavior with latest OneAPI on Linux (both ifort and ifx give errors). The older ifort on the Mac warns about this code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You give only code fragments, I made a test case maybe it misrepresents your code?? It compiles fine in IFX and IFORT.
Does that give an error? Maybe some specific build options are needed? You need a simple reproducer if there is a bug that needs to be fixed.
ifx /c test.f90
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2024.0.0 Build 20231017
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
ifort /c test.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.11.0 Build 20231010_000000
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
module fred
implicit none
integer, parameter :: int_kind = 4
type :: graph_t
integer(int_kind) :: thing=0
end type graph_t
interface num_vertices
module function num_undirected_vertices(self) result(n)
type(graph_t), intent(in) :: self
integer(int_kind) :: n
end function
end interface
end module
submodule(fred) billy
contains
module function num_undirected_vertices(self) result(n)
type(graph_t), intent(in) :: self
integer(int_kind) :: n
n = self%thing
end function
end submodule billy
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You don't show the compiler options used. Those messages are usually warnings, but you probably have /warn:errors enabled.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here's a very small reproducer, files are attached. This warning is on Mac:
ifort (IFORT) 2021.10.0 20230609
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
but it's the same problems on Linux and Windows.
ifort -c -g vector.f90 vector_sm.f90
vector_sm.f90(26): warning #6178: The return value of this FUNCTION has not been defined. [GET_VECTOR_BK]
module function get_vector_bk(self, n) result(data)
--^
vector_sm.f90(65): warning #6178: The return value of this FUNCTION has not been defined. [SIZE_VECTOR_BK]
module function size_vector_bk(self) result(size)
--^
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK, now these are warnings, not errors. I do agree that they are spurious.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Unfortunately, we have to compile with warnings as errors, high consequence software, so now that the latest (2024.0) ifort and ifx detect and report this spurious diagnostic as an error, we are dead in the water. For us, this is a showstopper since it precludes us from using any OneAPI starting in 2024.0, meaning we can't use the, to be released, llvm-based ifx.
We have tried to find a way to suppress this warning so it doesn't get reported, but have been unsuccessful. Perhaps you know of a way to suppress this warning?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I played with your reproducer and get the same behaviour. I changed various things e.g. removed variable that are fortran words and various other things and I can't see the trigger for the warning. I have many example using result() that compile just fine so I am not sure what it is that triggers this..... Intel need to look at it !
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The trigger is "final :: destruct_vector_ik" in the type, comment out that line and it compiles with no warnings!!!! I have no explanation!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, that's a strange bug, thanks for tracking that down Andrew! Unfortunately that doesn't help me out too much, I can't remove all of our class destructors.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You only get the warning for the _bk type but NOT the _ik type routines and those also have final!!!!!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
We have several hundreds of these warnings across dozens of classes, we use a fair number of functions. The integer kind (ik) types also emit warnings, I just happened to have pruned some of those functions in the course of trying to generate the reproducer.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Noel_B_, thanks for the reproducer. Did your code ever compile without the warning? What Intel compiler version? I experimented with some previous releases and always get the warning.
@andrew_4619, nice sleuthing!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think it also relates to having a generic interface that spans more than one type.....
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
From what I can recall, the warning has always been there.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, @Noel_B_, so this isn't a new warning. I wanted to check if this is a regression.
What's new is that you now need to compile with -warn errors.
I filed a bug report for you, CMPLRLLVM-56908. This impacts both ifx and ifort since they share the front end.
Thank you for reporting this.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Noel_B_ ,
@Barbara_P_Intel has followed up on your issue and filed a compiler bug report. Since that can take a while to resolve, here is a workaround you may want to think through and evaluate whether your actual code can make use of it: this workaround is silly, but it is to avoid names of objects that are the same as intrinsic statements and/or subprograms in the language supported by Intel compiler viz. names such as DATA, SIZE, etc. This is only so you can make it a bit easier on your compiler, ideally you won't need it. See below using IFX 2024.0.2.0:
C:\Temp>ifx /c /standard-semantics /warn:all /warn:errors vector.f90
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2024.0.2 Build 20231213
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
C:\Temp>ifx /c /standard-semantics /warn:all /warn:errors vector_sm.f90
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2024.0.2 Build 20231213
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
C:\Temp>
- Workaround in your file vector.f90
! Author: K. Noel Belcourt
module vector_m
implicit none
type :: vector_bk_t
logical(4), pointer :: data(:) => null()
integer(4) :: allocated_size = 0
integer(4) :: n = 0
contains
procedure :: construct_vector_bk
final :: destruct_vector_bk
end type
type :: vector_ik_t
integer(4), pointer :: data(:) => null()
integer(4) :: allocated_size = 0
integer(4) :: n = 0
contains
procedure :: construct_vector_ik
final :: destruct_vector_ik
end type
interface
module subroutine construct_vector_bk(self)
class(vector_bk_t), intent(inout) :: self
end subroutine
module subroutine construct_vector_ik(self)
class(vector_ik_t), intent(inout) :: self
end subroutine
end interface
interface
module subroutine destruct_vector_bk(self)
type(vector_bk_t), intent(inout) :: self
end subroutine
module subroutine destruct_vector_ik(self)
type(vector_ik_t), intent(inout) :: self
end subroutine
end interface
interface size
module function size_vector_bk(self) result(siz)
type(vector_bk_t), intent(in) :: self
integer(4) :: siz
end function
module function size_vector_ik(self) result(siz)
type(vector_ik_t), intent(in) :: self
integer(4) :: siz
end function
end interface
interface push_back
module subroutine push_back_bk(self, b)
type(vector_bk_t), intent(inout) :: self
logical(4), intent(in) :: b
end subroutine
module subroutine push_back_ik(self, i)
type(vector_ik_t), intent(inout) :: self
integer(4), intent(in) :: i
end subroutine
end interface
interface
module subroutine insert_vector_ik(self, existing, new)
type(vector_ik_t), intent(inout) :: self
integer(4), intent(in) :: existing, new
end subroutine
end interface
interface get
module function get_vector_bk(self, n) result(dat)
type(vector_bk_t), intent(in) :: self
integer(4), intent(in) :: n
logical(4) :: dat
end function
module function get_vector_ik(self, n) result(dat)
type(vector_ik_t), intent(in) :: self
integer(4), intent(in) :: n
integer(4) :: dat
end function
end interface
interface clear
module subroutine clear_vector_bk(self)
type(vector_bk_t), intent(inout) :: self
end subroutine
module subroutine clear_vector_ik(self)
type(vector_ik_t), intent(inout) :: self
end subroutine
end interface
interface set
module subroutine set_vector_bk(self, n, value)
type(vector_bk_t), intent(inout) :: self
integer(4), intent(in) :: n
logical(4), intent(in) :: value
end subroutine
module subroutine set_vector_ik(self, n, value)
type(vector_ik_t), intent(inout) :: self
integer(4), intent(in) :: n
integer(4), intent(in) :: value
end subroutine
end interface
end module
- And in your submodule
! Author: K. Noel Belcourt
submodule (vector_m) vector_sm
implicit none
contains
module subroutine construct_vector_bk(self)
class(vector_bk_t), intent(inout) :: self
integer(4) :: i
self%n = 0
self%allocated_size = 10
allocate(self%data(self%allocated_size))
do i = 1, self%allocated_size
self%data(i) = .false.
enddo
end subroutine
module subroutine destruct_vector_bk(self)
type(vector_bk_t), intent(inout) :: self
if (associated(self%data)) deallocate(self%data)
end subroutine
module function get_vector_bk(self, n) result(dat)
type(vector_bk_t), intent(in) :: self
integer(4), intent(in) :: n
logical(4) :: dat
dat = .false.
dat = self%data(n)
end function
module subroutine push_back_bk(self, b)
type(vector_bk_t), intent(inout) :: self
logical(4), intent(in) :: b
logical(4), pointer, dimension(:) :: tmp
real(8) :: s
integer(4) :: i
if (self%allocated_size == self%n) then
tmp => self%data
s = self%allocated_size
self%allocated_size = s * 1.5
allocate(self%data(self%allocated_size))
do i = 1, self%n
self%data(i) = tmp(i)
enddo
deallocate(tmp)
endif
self%n = self%n + 1
self%data(self%n) = b
end subroutine
module subroutine set_vector_bk(self, n, value)
type(vector_bk_t), intent(inout) :: self
integer(4), intent(in) :: n
logical(4), intent(in) :: value
self%data(n) = value
end subroutine
module function size_vector_bk(self) result(siz)
type(vector_bk_t), intent(in) :: self
integer(4) :: siz
siz = self%n
end function
module subroutine construct_vector_ik(self)
class(vector_ik_t), intent(inout) :: self
self%n = 0
self%allocated_size = 10
allocate(self%data(self%allocated_size))
self%data = 0
end subroutine
module subroutine destruct_vector_ik(self)
type(vector_ik_t), intent(inout) :: self
! if (associated(self%data)) deallocate(self%data)
self%n = 0
self%allocated_size = 0
self%data => null()
end subroutine
module function get_vector_ik(self, n) result(dat)
type(vector_ik_t), intent(in) :: self
integer(4), intent(in) :: n
integer(4) :: dat
dat = 0
dat = self%data(n)
end function
module subroutine push_back_ik(self, i)
type(vector_ik_t), intent(inout) :: self
integer(4), intent(in) :: i
integer(4), pointer, dimension(:) :: tmp
real(8) :: s
integer(4) :: j
if (self%allocated_size == self%n) then
tmp => self%data
s = self%allocated_size
self%allocated_size = s * 1.5
allocate(self%data(self%allocated_size))
do j = 1, self%n
self%data(j) = tmp(j)
enddo
deallocate(tmp)
endif
self%n = self%n + 1
self%data(self%n) = i
end subroutine
module subroutine set_vector_ik(self, n, value)
type(vector_ik_t), intent(inout) :: self
integer(4), intent(in) :: n
integer(4), intent(in) :: value
self%data(n) = value
end subroutine
module function size_vector_ik(self) result(siz)
type(vector_ik_t), intent(in) :: self
integer(4) :: siz
siz = self%n
end function
end submodule
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I could see that this:
avoid names of objects that are the same as intrinsic statements and/or subprograms
could fix some of the issues, but many of our functions have problems and the names, to the best of my knowledge, are not the names of intrinsics. For example, none of these function return values (n, edge, e) are the names of intrinsics or subprograms, as far as I know. So I'm not sure that's the whole explanation, seems like there could be more going on with this.
graph_sm.f90(357): warning #6178: The return value of this FUNCTION has not been defined. [NUM_UNDIRECTED_VERTICES]
module function num_undirected_vertices(self) result(n)
graph_sm.f90(363): warning #6178: The return value of this FUNCTION has not been defined. [NUM_UNDIRECTED_EDGES]
module function num_undirected_edges(self) result(n)
graph_sm.f90(427): warning #6178: The return value of this FUNCTION has not been defined. [FIND_UNDIRECTED_EDGE]
module function find_undirected_edge(self, u_id, v_id) result(edge)
graph_sm.f90(493): warning #6178: The return value of this FUNCTION has not been defined. [INSERT_UNDIRECTED_EDGE]
module function insert_undirected_edge(self, u, v) result(edge)
graph_sm.f90(663): warning #6178: The return value of this FUNCTION has not been defined. [EDGE_UDG]
module function edge_udg(self, i) result(e)
graph_sm.f90(677): warning #6178: The return value of this FUNCTION has not been defined. [EDGE_DG]
module function edge_dg(self, i) result(e)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes it seems the compilers is screwing up its lists of variable names/attributes or something like that and that it could then be become sensitive to more than one thing that exposes the otherwise hidden problem. It is worth intel looking at it as there could be other hidden side effects/possibilities as yet unknown.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well @FortranFan I am right royally confused! What you have done there with data and size was my first guess at a key to the issue. I "proved" to myself the changes like you made didn't 'fix' it. I have just tested your code and it it is OK but having deleted my earlier files I now don't know why my edits failed. Very annoying!!!!!! Anyway chapeau again!
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page