1 //===-- runtime/stat.cpp --------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 #include "terminator.h"
12 #include "flang/Runtime/descriptor.h"
14 namespace Fortran::runtime
{
15 RT_OFFLOAD_API_GROUP_BEGIN
17 RT_API_ATTRS
const char *StatErrorString(int stat
) {
23 return "Base address is null";
25 return "Base address is not null";
26 case StatInvalidElemLen
:
27 return "Invalid element length";
29 return "Invalid rank";
31 return "Invalid type";
32 case StatInvalidAttribute
:
33 return "Invalid attribute";
34 case StatInvalidExtent
:
35 return "Invalid extent";
36 case StatInvalidDescriptor
:
37 return "Invalid descriptor";
38 case StatMemAllocation
:
39 return "Memory allocation failed";
41 return "Out of bounds";
44 return "Failed image";
47 case StatLockedOtherImage
:
48 return "Other image locked";
49 case StatStoppedImage
:
50 return "Image stopped";
53 case StatUnlockedFailedImage
:
54 return "Failed image unlocked";
56 case StatInvalidArgumentNumber
:
57 return "Invalid argument number";
58 case StatMissingArgument
:
59 return "Missing argument";
60 case StatValueTooShort
:
61 return "Value too short";
63 case StatMissingEnvVariable
:
64 return "Missing environment variable";
66 case StatMoveAllocSameAllocatable
:
67 return "MOVE_ALLOC passed the same address as to and from";
74 RT_API_ATTRS
int ToErrmsg(const Descriptor
*errmsg
, int stat
) {
75 if (stat
!= StatOk
&& errmsg
&& errmsg
->raw().base_addr
&&
76 errmsg
->type() == TypeCode(TypeCategory::Character
, 1) &&
77 errmsg
->rank() == 0) {
78 if (const char *msg
{StatErrorString(stat
)}) {
79 char *buffer
{errmsg
->OffsetElement()};
80 std::size_t bufferLength
{errmsg
->ElementBytes()};
81 std::size_t msgLength
{Fortran::runtime::strlen(msg
)};
82 if (msgLength
>= bufferLength
) {
83 std::memcpy(buffer
, msg
, bufferLength
);
85 std::memcpy(buffer
, msg
, msgLength
);
86 std::memset(buffer
+ msgLength
, ' ', bufferLength
- msgLength
);
93 RT_API_ATTRS
int ReturnError(
94 Terminator
&terminator
, int stat
, const Descriptor
*errmsg
, bool hasStat
) {
95 if (stat
== StatOk
|| hasStat
) {
96 return ToErrmsg(errmsg
, stat
);
97 } else if (const char *msg
{StatErrorString(stat
)}) {
98 terminator
.Crash(msg
);
100 terminator
.Crash("Invalid Fortran runtime STAT= code %d", stat
);
105 RT_OFFLOAD_API_GROUP_END
106 } // namespace Fortran::runtime