1651f58bfSDiana Picus //===-- runtime/stat.cpp --------------------------------------------------===//
28df28f0aSpeter klausler //
38df28f0aSpeter klausler // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
48df28f0aSpeter klausler // See https://llvm.org/LICENSE.txt for license information.
58df28f0aSpeter klausler // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
68df28f0aSpeter klausler //
78df28f0aSpeter klausler //===----------------------------------------------------------------------===//
88df28f0aSpeter klausler
98df28f0aSpeter klausler #include "stat.h"
108df28f0aSpeter klausler #include "terminator.h"
118b953fddSSlava Zakharin #include "tools.h"
12830c0b90SPeter Klausler #include "flang/Runtime/descriptor.h"
138df28f0aSpeter klausler
148df28f0aSpeter klausler namespace Fortran::runtime {
158b953fddSSlava Zakharin RT_OFFLOAD_API_GROUP_BEGIN
168b953fddSSlava Zakharin
StatErrorString(int stat)178b953fddSSlava Zakharin RT_API_ATTRS const char *StatErrorString(int stat) {
188df28f0aSpeter klausler switch (stat) {
198df28f0aSpeter klausler case StatOk:
208df28f0aSpeter klausler return "No error";
218df28f0aSpeter klausler
228df28f0aSpeter klausler case StatBaseNull:
238df28f0aSpeter klausler return "Base address is null";
248df28f0aSpeter klausler case StatBaseNotNull:
258df28f0aSpeter klausler return "Base address is not null";
268df28f0aSpeter klausler case StatInvalidElemLen:
278df28f0aSpeter klausler return "Invalid element length";
288df28f0aSpeter klausler case StatInvalidRank:
298df28f0aSpeter klausler return "Invalid rank";
308df28f0aSpeter klausler case StatInvalidType:
318df28f0aSpeter klausler return "Invalid type";
328df28f0aSpeter klausler case StatInvalidAttribute:
338df28f0aSpeter klausler return "Invalid attribute";
348df28f0aSpeter klausler case StatInvalidExtent:
358df28f0aSpeter klausler return "Invalid extent";
368df28f0aSpeter klausler case StatInvalidDescriptor:
378df28f0aSpeter klausler return "Invalid descriptor";
388df28f0aSpeter klausler case StatMemAllocation:
398df28f0aSpeter klausler return "Memory allocation failed";
408df28f0aSpeter klausler case StatOutOfBounds:
418df28f0aSpeter klausler return "Out of bounds";
428df28f0aSpeter klausler
438df28f0aSpeter klausler case StatFailedImage:
448df28f0aSpeter klausler return "Failed image";
458df28f0aSpeter klausler case StatLocked:
468df28f0aSpeter klausler return "Locked";
478df28f0aSpeter klausler case StatLockedOtherImage:
488df28f0aSpeter klausler return "Other image locked";
498df28f0aSpeter klausler case StatStoppedImage:
508df28f0aSpeter klausler return "Image stopped";
518df28f0aSpeter klausler case StatUnlocked:
528df28f0aSpeter klausler return "Unlocked";
538df28f0aSpeter klausler case StatUnlockedFailedImage:
548df28f0aSpeter klausler return "Failed image unlocked";
558df28f0aSpeter klausler
5637089baeSDiana Picus case StatInvalidArgumentNumber:
5737089baeSDiana Picus return "Invalid argument number";
5837089baeSDiana Picus case StatMissingArgument:
5937089baeSDiana Picus return "Missing argument";
6037089baeSDiana Picus case StatValueTooShort:
6137089baeSDiana Picus return "Value too short";
6237089baeSDiana Picus
639df0ba59SDiana Picus case StatMissingEnvVariable:
649df0ba59SDiana Picus return "Missing environment variable";
659df0ba59SDiana Picus
662526013aSDavid Truby case StatMoveAllocSameAllocatable:
672526013aSDavid Truby return "MOVE_ALLOC passed the same address as to and from";
682526013aSDavid Truby
69*a3bbe627SPeter Klausler case StatBadPointerDeallocation:
70*a3bbe627SPeter Klausler return "DEALLOCATE of a pointer that is not the whole content of a pointer "
71*a3bbe627SPeter Klausler "ALLOCATE";
72*a3bbe627SPeter Klausler
738df28f0aSpeter klausler default:
748df28f0aSpeter klausler return nullptr;
758df28f0aSpeter klausler }
768df28f0aSpeter klausler }
778df28f0aSpeter klausler
ToErrmsg(const Descriptor * errmsg,int stat)788b953fddSSlava Zakharin RT_API_ATTRS int ToErrmsg(const Descriptor *errmsg, int stat) {
798df28f0aSpeter klausler if (stat != StatOk && errmsg && errmsg->raw().base_addr &&
808df28f0aSpeter klausler errmsg->type() == TypeCode(TypeCategory::Character, 1) &&
818df28f0aSpeter klausler errmsg->rank() == 0) {
828df28f0aSpeter klausler if (const char *msg{StatErrorString(stat)}) {
838df28f0aSpeter klausler char *buffer{errmsg->OffsetElement()};
848df28f0aSpeter klausler std::size_t bufferLength{errmsg->ElementBytes()};
858b953fddSSlava Zakharin std::size_t msgLength{Fortran::runtime::strlen(msg)};
86170e9061Speter klausler if (msgLength >= bufferLength) {
878df28f0aSpeter klausler std::memcpy(buffer, msg, bufferLength);
888df28f0aSpeter klausler } else {
898df28f0aSpeter klausler std::memcpy(buffer, msg, msgLength);
908df28f0aSpeter klausler std::memset(buffer + msgLength, ' ', bufferLength - msgLength);
918df28f0aSpeter klausler }
928df28f0aSpeter klausler }
938df28f0aSpeter klausler }
948df28f0aSpeter klausler return stat;
958df28f0aSpeter klausler }
968df28f0aSpeter klausler
ReturnError(Terminator & terminator,int stat,const Descriptor * errmsg,bool hasStat)978b953fddSSlava Zakharin RT_API_ATTRS int ReturnError(
98170e9061Speter klausler Terminator &terminator, int stat, const Descriptor *errmsg, bool hasStat) {
998df28f0aSpeter klausler if (stat == StatOk || hasStat) {
1008df28f0aSpeter klausler return ToErrmsg(errmsg, stat);
1018df28f0aSpeter klausler } else if (const char *msg{StatErrorString(stat)}) {
1028df28f0aSpeter klausler terminator.Crash(msg);
1038df28f0aSpeter klausler } else {
1048df28f0aSpeter klausler terminator.Crash("Invalid Fortran runtime STAT= code %d", stat);
1058df28f0aSpeter klausler }
1068df28f0aSpeter klausler return stat;
1078df28f0aSpeter klausler }
1088b953fddSSlava Zakharin
1098b953fddSSlava Zakharin RT_OFFLOAD_API_GROUP_END
1108df28f0aSpeter klausler } // namespace Fortran::runtime
111