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"
11 #include "flang/Runtime/descriptor.h"
13 namespace Fortran::runtime
{
14 const char *StatErrorString(int stat
) {
20 return "Base address is null";
22 return "Base address is not null";
23 case StatInvalidElemLen
:
24 return "Invalid element length";
26 return "Invalid rank";
28 return "Invalid type";
29 case StatInvalidAttribute
:
30 return "Invalid attribute";
31 case StatInvalidExtent
:
32 return "Invalid extent";
33 case StatInvalidDescriptor
:
34 return "Invalid descriptor";
35 case StatMemAllocation
:
36 return "Memory allocation failed";
38 return "Out of bounds";
41 return "Failed image";
44 case StatLockedOtherImage
:
45 return "Other image locked";
46 case StatStoppedImage
:
47 return "Image stopped";
50 case StatUnlockedFailedImage
:
51 return "Failed image unlocked";
53 case StatInvalidArgumentNumber
:
54 return "Invalid argument number";
55 case StatMissingArgument
:
56 return "Missing argument";
57 case StatValueTooShort
:
58 return "Value too short";
60 case StatMissingEnvVariable
:
61 return "Missing environment variable";
63 case StatMoveAllocSameAllocatable
:
64 return "MOVE_ALLOC passed the same address as to and from";
71 int ToErrmsg(const Descriptor
*errmsg
, int stat
) {
72 if (stat
!= StatOk
&& errmsg
&& errmsg
->raw().base_addr
&&
73 errmsg
->type() == TypeCode(TypeCategory::Character
, 1) &&
74 errmsg
->rank() == 0) {
75 if (const char *msg
{StatErrorString(stat
)}) {
76 char *buffer
{errmsg
->OffsetElement()};
77 std::size_t bufferLength
{errmsg
->ElementBytes()};
78 std::size_t msgLength
{std::strlen(msg
)};
79 if (msgLength
>= bufferLength
) {
80 std::memcpy(buffer
, msg
, bufferLength
);
82 std::memcpy(buffer
, msg
, msgLength
);
83 std::memset(buffer
+ msgLength
, ' ', bufferLength
- msgLength
);
91 Terminator
&terminator
, int stat
, const Descriptor
*errmsg
, bool hasStat
) {
92 if (stat
== StatOk
|| hasStat
) {
93 return ToErrmsg(errmsg
, stat
);
94 } else if (const char *msg
{StatErrorString(stat
)}) {
95 terminator
.Crash(msg
);
97 terminator
.Crash("Invalid Fortran runtime STAT= code %d", stat
);
101 } // namespace Fortran::runtime