[flang-commits] [flang] 0446f12 - [flang] GET_COMMAND_ARGUMENT(ERRMSG) runtime implementation

Diana Picus via flang-commits flang-commits at lists.llvm.org
Tue Sep 28 01:38:02 PDT 2021


Author: Diana Picus
Date: 2021-09-28T08:32:19Z
New Revision: 0446f1299f6be9fd35bc5f458c78b34dca3105f6

URL: https://github.com/llvm/llvm-project/commit/0446f1299f6be9fd35bc5f458c78b34dca3105f6
DIFF: https://github.com/llvm/llvm-project/commit/0446f1299f6be9fd35bc5f458c78b34dca3105f6.diff

LOG: [flang] GET_COMMAND_ARGUMENT(ERRMSG) runtime implementation

Implement the final part of GET_COMMAND_ARGUMENT, i.e. the handling of
ERRMSG. This uses some of the infrastructure in stat.h and gets rid of
the magic numbers that we were using for return codes.

Differential Revision: https://reviews.llvm.org/D109814

Added: 
    

Modified: 
    flang/include/flang/Runtime/magic-numbers.h
    flang/runtime/command.cpp
    flang/runtime/stat.cpp
    flang/runtime/stat.h
    flang/unittests/Runtime/CommandTest.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Runtime/magic-numbers.h b/flang/include/flang/Runtime/magic-numbers.h
index f84b7ecf08376..0f1957b4648b7 100644
--- a/flang/include/flang/Runtime/magic-numbers.h
+++ b/flang/include/flang/Runtime/magic-numbers.h
@@ -39,4 +39,12 @@ start at 100 so as to never conflict with those codes.
 #define FORTRAN_RUNTIME_STAT_STOPPED_IMAGE 104
 #define FORTRAN_RUNTIME_STAT_UNLOCKED 105
 #define FORTRAN_RUNTIME_STAT_UNLOCKED_FAILED_IMAGE 106
+
+#if 0
+Status codes for GET_COMMAND_ARGUMENT. The status for 'value too short' needs
+to be -1, the others must be positive.
+#endif
+#define FORTRAN_RUNTIME_STAT_INVALID_ARG_NUMBER 107
+#define FORTRAN_RUNTIME_STAT_MISSING_ARG 108
+#define FORTRAN_RUNTIME_STAT_VALUE_TOO_SHORT -1
 #endif

diff  --git a/flang/runtime/command.cpp b/flang/runtime/command.cpp
index 9dea6e4ca903f..a133b70c250b4 100644
--- a/flang/runtime/command.cpp
+++ b/flang/runtime/command.cpp
@@ -8,6 +8,7 @@
 
 #include "flang/Runtime/command.h"
 #include "environment.h"
+#include "stat.h"
 #include "flang/Runtime/descriptor.h"
 #include <limits>
 
@@ -58,13 +59,13 @@ std::int32_t RTNAME(ArgumentValue)(
   }
 
   if (n < 0 || n >= executionEnvironment.argc) {
-    return 1;
+    return ToErrmsg(errmsg, StatInvalidArgumentNumber);
   }
 
   if (IsValidCharDescriptor(value)) {
     std::int64_t argLen{ArgumentLength(n)};
     if (argLen <= 0) {
-      return 2;
+      return ToErrmsg(errmsg, StatMissingArgument);
     }
 
     std::int64_t toCopy{
@@ -72,9 +73,10 @@ std::int32_t RTNAME(ArgumentValue)(
     std::strncpy(value->OffsetElement(), executionEnvironment.argv[n], toCopy);
 
     if (argLen > toCopy) {
-      return -1;
+      return ToErrmsg(errmsg, StatValueTooShort);
     }
   }
-  return 0;
+
+  return StatOk;
 }
 } // namespace Fortran::runtime

diff  --git a/flang/runtime/stat.cpp b/flang/runtime/stat.cpp
index c0620f4c23e33..d28187c1a4264 100644
--- a/flang/runtime/stat.cpp
+++ b/flang/runtime/stat.cpp
@@ -50,6 +50,13 @@ const char *StatErrorString(int stat) {
   case StatUnlockedFailedImage:
     return "Failed image unlocked";
 
+  case StatInvalidArgumentNumber:
+    return "Invalid argument number";
+  case StatMissingArgument:
+    return "Missing argument";
+  case StatValueTooShort:
+    return "Value too short";
+
   default:
     return nullptr;
   }

diff  --git a/flang/runtime/stat.h b/flang/runtime/stat.h
index 5c1828e918bfe..5042f4bc4263c 100644
--- a/flang/runtime/stat.h
+++ b/flang/runtime/stat.h
@@ -44,6 +44,9 @@ enum Stat {
   StatUnlockedFailedImage = FORTRAN_RUNTIME_STAT_UNLOCKED_FAILED_IMAGE,
 
   // Additional "processor-defined" STAT= values
+  StatInvalidArgumentNumber = FORTRAN_RUNTIME_STAT_INVALID_ARG_NUMBER,
+  StatMissingArgument = FORTRAN_RUNTIME_STAT_MISSING_ARG,
+  StatValueTooShort = FORTRAN_RUNTIME_STAT_VALUE_TOO_SHORT,
 };
 
 const char *StatErrorString(int);

diff  --git a/flang/unittests/Runtime/CommandTest.cpp b/flang/unittests/Runtime/CommandTest.cpp
index 69c309d61af0d..a13addd75a214 100644
--- a/flang/unittests/Runtime/CommandTest.cpp
+++ b/flang/unittests/Runtime/CommandTest.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "flang/Runtime/command.h"
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include "flang/Runtime/descriptor.h"
 #include "flang/Runtime/main.h"
@@ -53,14 +54,21 @@ class CommandFixture : public ::testing::Test {
     CheckDescriptorEqStr(value.get(), expected);
   }
 
-  void CheckMissingArgumentValue(int n) const {
+  void CheckMissingArgumentValue(int n, const char *errStr = nullptr) const {
     OwningPtr<Descriptor> value{CreateEmptyCharDescriptor()};
     ASSERT_NE(value, nullptr);
 
-    EXPECT_GT(RTNAME(ArgumentValue)(n, value.get(), nullptr), 0);
+    OwningPtr<Descriptor> err{errStr ? CreateEmptyCharDescriptor() : nullptr};
+
+    EXPECT_GT(RTNAME(ArgumentValue)(n, value.get(), err.get()), 0);
 
     std::string spaces(value->ElementBytes(), ' ');
     CheckDescriptorEqStr(value.get(), spaces);
+
+    if (errStr) {
+      std::string paddedErrStr(GetPaddedStr(errStr, err->ElementBytes()));
+      CheckDescriptorEqStr(err.get(), paddedErrStr);
+    }
   }
 };
 
@@ -128,7 +136,6 @@ TEST_F(SeveralArguments, ArgumentLength) {
 TEST_F(SeveralArguments, ArgumentValue) {
   CheckArgumentValue(0, severalArgsArgv[0]);
   CheckArgumentValue(1, severalArgsArgv[1]);
-  CheckMissingArgumentValue(2);
   CheckArgumentValue(3, severalArgsArgv[3]);
   CheckArgumentValue(4, severalArgsArgv[4]);
 }
@@ -140,12 +147,31 @@ TEST_F(SeveralArguments, NoArgumentValue) {
   EXPECT_GT(RTNAME(ArgumentValue)(-1, nullptr, nullptr), 0);
 }
 
-TEST_F(SeveralArguments, ArgumentValueErrors) {
-  CheckMissingArgumentValue(-1);
+TEST_F(SeveralArguments, MissingArguments) {
+  CheckMissingArgumentValue(-1, "Invalid argument number");
+  CheckMissingArgumentValue(2, "Missing argument");
+  CheckMissingArgumentValue(5, "Invalid argument number");
   CheckMissingArgumentValue(5);
+}
 
+TEST_F(SeveralArguments, ValueTooShort) {
   OwningPtr<Descriptor> tooShort{CreateEmptyCharDescriptor<15>()};
   ASSERT_NE(tooShort, nullptr);
   EXPECT_EQ(RTNAME(ArgumentValue)(1, tooShort.get(), nullptr), -1);
   CheckDescriptorEqStr(tooShort.get(), severalArgsArgv[1]);
+
+  OwningPtr<Descriptor> errMsg{CreateEmptyCharDescriptor()};
+  ASSERT_NE(errMsg, nullptr);
+
+  EXPECT_EQ(RTNAME(ArgumentValue)(1, tooShort.get(), errMsg.get()), -1);
+
+  std::string expectedErrMsg{
+      GetPaddedStr("Value too short", errMsg->ElementBytes())};
+  CheckDescriptorEqStr(errMsg.get(), expectedErrMsg);
+}
+
+TEST_F(SeveralArguments, ErrMsgTooShort) {
+  OwningPtr<Descriptor> errMsg{CreateEmptyCharDescriptor<3>()};
+  EXPECT_GT(RTNAME(ArgumentValue)(-1, nullptr, errMsg.get()), 0);
+  CheckDescriptorEqStr(errMsg.get(), "Inv");
 }


        


More information about the flang-commits mailing list