[flang-commits] [flang] eb7a02e - [flang] Single entry point for GET_COMMAND_ARGUMENT

Diana Picus via flang-commits flang-commits at lists.llvm.org
Wed Jul 27 03:27:43 PDT 2022


Author: Diana Picus
Date: 2022-07-27T10:27:25Z
New Revision: eb7a02ea009b6a2aa3689ee92905fb6acea905fc

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

LOG: [flang] Single entry point for GET_COMMAND_ARGUMENT

This patch refactors the runtime support for GET_COMMAND_ARGUMENT to
have a single entry point instead of 2. It also updates lowering
accordingly.

This makes it easier to handle dynamically optional arguments. See also
https://reviews.llvm.org/D118777

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

Added: 
    

Modified: 
    flang/include/flang/Optimizer/Builder/Runtime/Command.h
    flang/include/flang/Runtime/command.h
    flang/lib/Lower/IntrinsicCall.cpp
    flang/lib/Optimizer/Builder/Runtime/Command.cpp
    flang/runtime/command.cpp
    flang/test/Lower/Intrinsics/get_command_argument-optional.f90
    flang/test/Lower/Intrinsics/get_command_argument.f90
    flang/test/Runtime/no-cpp-dep.c
    flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
    flang/unittests/Runtime/CommandTest.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Optimizer/Builder/Runtime/Command.h b/flang/include/flang/Optimizer/Builder/Runtime/Command.h
index fb829f81b7970..7df67c1527c00 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/Command.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Command.h
@@ -23,19 +23,13 @@ namespace fir::runtime {
 /// Generate call to COMMAND_ARGUMENT_COUNT intrinsic runtime routine.
 mlir::Value genCommandArgumentCount(fir::FirOpBuilder &, mlir::Location);
 
-/// Generate a call to ArgumentValue runtime function which implements
-/// the part of GET_COMMAND_ARGUMENT related to VALUE, ERRMSG, and STATUS.
-/// \p value and \p errmsg must be fir.box that can be absent (but not null
-/// mlir values). The status value is returned.
-mlir::Value genArgumentValue(fir::FirOpBuilder &, mlir::Location,
-                             mlir::Value number, mlir::Value value,
-                             mlir::Value errmsg);
-
-/// Generate a call to ArgumentLength runtime function which implements
-/// the part of GET_COMMAND_ARGUMENT related to LENGTH.
-/// It returns the length of the \p number command arguments.
-mlir::Value genArgumentLength(fir::FirOpBuilder &, mlir::Location,
-                              mlir::Value number);
+/// Generate a call to the GetCommandArgument runtime function which implements
+/// the GET_COMMAND_ARGUMENT intrinsic.
+/// \p value, \p length and \p errmsg must be fir.box that can be absent (but
+/// not null mlir values). The status value is returned.
+mlir::Value genGetCommandArgument(fir::FirOpBuilder &, mlir::Location,
+                                  mlir::Value number, mlir::Value value,
+                                  mlir::Value length, mlir::Value errmsg);
 
 /// Generate a call to EnvVariableValue runtime function which implements
 /// the part of GET_ENVIRONMENT_ARGUMENT related to VALUE, ERRMSG, and STATUS.

diff  --git a/flang/include/flang/Runtime/command.h b/flang/include/flang/Runtime/command.h
index 55fe39323b92d..74b3d0b9992be 100644
--- a/flang/include/flang/Runtime/command.h
+++ b/flang/include/flang/Runtime/command.h
@@ -32,17 +32,12 @@ std::int32_t RTNAME(GetCommand)(const Descriptor *command = nullptr,
     const char *sourceFile = nullptr, int line = 0);
 
 // 16.9.83 GET_COMMAND_ARGUMENT
-// We're breaking up the interface into several 
diff erent functions, since most
-// of the parameters are optional.
-
 // Try to get the value of the n'th argument.
 // Returns a STATUS as described in the standard.
-std::int32_t RTNAME(ArgumentValue)(
-    std::int32_t n, const Descriptor *value, const Descriptor *errmsg);
-
-// Try to get the significant length of the n'th argument.
-// Returns 0 if it doesn't manage.
-std::int64_t RTNAME(ArgumentLength)(std::int32_t n);
+std::int32_t RTNAME(GetCommandArgument)(std::int32_t n,
+    const Descriptor *argument = nullptr, const Descriptor *length = nullptr,
+    const Descriptor *errmsg = nullptr, const char *sourceFile = nullptr,
+    int line = 0);
 
 // 16.9.84 GET_ENVIRONMENT_VARIABLE
 // We're breaking up the interface into several 
diff erent functions, since most

diff  --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp
index 826404e80c536..0cb5efccc5679 100644
--- a/flang/lib/Lower/IntrinsicCall.cpp
+++ b/flang/lib/Lower/IntrinsicCall.cpp
@@ -769,8 +769,8 @@ static constexpr IntrinsicHandler handlers[]{
      &I::genGetCommandArgument,
      {{{"number", asValue},
        {"value", asBox, handleDynamicOptional},
-       {"length", asAddr},
-       {"status", asAddr},
+       {"length", asBox, handleDynamicOptional},
+       {"status", asAddr, handleDynamicOptional},
        {"errmsg", asBox, handleDynamicOptional}}},
      /*isElemental=*/false},
     {"get_environment_variable",
@@ -2778,38 +2778,32 @@ void IntrinsicLibrary::genGetCommandArgument(
   if (!number)
     fir::emitFatalError(loc, "expected NUMBER parameter");
 
-  if (isStaticallyPresent(value) || isStaticallyPresent(status) ||
-      isStaticallyPresent(errmsg)) {
-    mlir::Type boxNoneTy = fir::BoxType::get(builder.getNoneType());
-    mlir::Value valBox =
-        isStaticallyPresent(value)
-            ? fir::getBase(value)
-            : builder.create<fir::AbsentOp>(loc, boxNoneTy).getResult();
-    mlir::Value errBox =
-        isStaticallyPresent(errmsg)
-            ? fir::getBase(errmsg)
-            : builder.create<fir::AbsentOp>(loc, boxNoneTy).getResult();
-    mlir::Value stat =
-        fir::runtime::genArgumentValue(builder, loc, number, valBox, errBox);
-    if (isStaticallyPresent(status)) {
-      mlir::Value statAddr = fir::getBase(status);
-      mlir::Value statIsPresentAtRuntime =
-          builder.genIsNotNullAddr(loc, statAddr);
-      builder.genIfThen(loc, statIsPresentAtRuntime)
-          .genThen(
-              [&]() { builder.createStoreWithConvert(loc, stat, statAddr); })
-          .end();
-    }
-  }
-  if (isStaticallyPresent(length)) {
-    mlir::Value lenAddr = fir::getBase(length);
-    mlir::Value lenIsPresentAtRuntime = builder.genIsNotNullAddr(loc, lenAddr);
-    builder.genIfThen(loc, lenIsPresentAtRuntime)
-        .genThen([&]() {
-          mlir::Value len =
-              fir::runtime::genArgumentLength(builder, loc, number);
-          builder.createStoreWithConvert(loc, len, lenAddr);
-        })
+  // If none of the optional parameters are present, do nothing.
+  if (!isStaticallyPresent(value) && !isStaticallyPresent(length) &&
+      !isStaticallyPresent(status) && !isStaticallyPresent(errmsg))
+    return;
+
+  mlir::Type boxNoneTy = fir::BoxType::get(builder.getNoneType());
+  mlir::Value valBox =
+      isStaticallyPresent(value)
+          ? fir::getBase(value)
+          : builder.create<fir::AbsentOp>(loc, boxNoneTy).getResult();
+  mlir::Value lenBox =
+      isStaticallyPresent(length)
+          ? fir::getBase(length)
+          : builder.create<fir::AbsentOp>(loc, boxNoneTy).getResult();
+  mlir::Value errBox =
+      isStaticallyPresent(errmsg)
+          ? fir::getBase(errmsg)
+          : builder.create<fir::AbsentOp>(loc, boxNoneTy).getResult();
+  mlir::Value stat = fir::runtime::genGetCommandArgument(
+      builder, loc, number, valBox, lenBox, errBox);
+  if (isStaticallyPresent(status)) {
+    mlir::Value statAddr = fir::getBase(status);
+    mlir::Value statIsPresentAtRuntime =
+        builder.genIsNotNullAddr(loc, statAddr);
+    builder.genIfThen(loc, statIsPresentAtRuntime)
+        .genThen([&]() { builder.createStoreWithConvert(loc, stat, statAddr); })
         .end();
   }
 }

diff  --git a/flang/lib/Optimizer/Builder/Runtime/Command.cpp b/flang/lib/Optimizer/Builder/Runtime/Command.cpp
index 9e12f649f95e7..6227013803775 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Command.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Command.cpp
@@ -32,27 +32,19 @@ mlir::Value fir::runtime::genCommandArgumentCount(fir::FirOpBuilder &builder,
   return builder.create<fir::CallOp>(loc, argumentCountFunc).getResult(0);
 }
 
-mlir::Value fir::runtime::genArgumentValue(fir::FirOpBuilder &builder,
-                                           mlir::Location loc,
-                                           mlir::Value number,
-                                           mlir::Value value,
-                                           mlir::Value errmsg) {
-  auto argumentValueFunc =
-      fir::runtime::getRuntimeFunc<mkRTKey(ArgumentValue)>(loc, builder);
-  llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
-      builder, loc, argumentValueFunc.getFunctionType(), number, value, errmsg);
-  return builder.create<fir::CallOp>(loc, argumentValueFunc, args).getResult(0);
-}
-
-mlir::Value fir::runtime::genArgumentLength(fir::FirOpBuilder &builder,
-                                            mlir::Location loc,
-                                            mlir::Value number) {
-  auto argumentLengthFunc =
-      fir::runtime::getRuntimeFunc<mkRTKey(ArgumentLength)>(loc, builder);
-  llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
-      builder, loc, argumentLengthFunc.getFunctionType(), number);
-  return builder.create<fir::CallOp>(loc, argumentLengthFunc, args)
-      .getResult(0);
+mlir::Value fir::runtime::genGetCommandArgument(
+    fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value number,
+    mlir::Value value, mlir::Value length, mlir::Value errmsg) {
+  auto runtimeFunc =
+      fir::runtime::getRuntimeFunc<mkRTKey(GetCommandArgument)>(loc, builder);
+  mlir::FunctionType runtimeFuncTy = runtimeFunc.getFunctionType();
+  mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
+  mlir::Value sourceLine =
+      fir::factory::locationToLineNo(builder, loc, runtimeFuncTy.getInput(5));
+  llvm::SmallVector<mlir::Value> args =
+      fir::runtime::createArguments(builder, loc, runtimeFuncTy, number, value,
+                                    length, errmsg, sourceFile, sourceLine);
+  return builder.create<fir::CallOp>(loc, runtimeFunc, args).getResult(0);
 }
 
 mlir::Value fir::runtime::genEnvVariableValue(

diff  --git a/flang/runtime/command.cpp b/flang/runtime/command.cpp
index fe54da2e6d68b..6ee012f85254c 100644
--- a/flang/runtime/command.cpp
+++ b/flang/runtime/command.cpp
@@ -37,15 +37,6 @@ static std::int64_t StringLength(const char *string) {
   }
 }
 
-std::int64_t RTNAME(ArgumentLength)(std::int32_t n) {
-  if (n < 0 || n >= executionEnvironment.argc ||
-      !executionEnvironment.argv[n]) {
-    return 0;
-  }
-
-  return StringLength(executionEnvironment.argv[n]);
-}
-
 static bool IsValidCharDescriptor(const Descriptor *value) {
   return value && value->IsAllocated() &&
       value->type() == TypeCode(TypeCategory::Character, 1) &&
@@ -107,48 +98,71 @@ static std::int32_t CheckAndCopyToDescriptor(const Descriptor *value,
   return stat;
 }
 
-std::int32_t RTNAME(ArgumentValue)(
-    std::int32_t n, const Descriptor *value, const Descriptor *errmsg) {
-  if (IsValidCharDescriptor(value)) {
+static void StoreLengthToDescriptor(
+    const Descriptor *length, std::int64_t value, Terminator &terminator) {
+  auto typeCode{length->type().GetCategoryAndKind()};
+  int kind{typeCode->second};
+  Fortran::runtime::ApplyIntegerKind<Fortran::runtime::StoreIntegerAt, void>(
+      kind, terminator, *length, /* atIndex = */ 0, value);
+}
+
+template <int KIND> struct FitsInIntegerKind {
+  bool operator()(std::int64_t value) {
+    return value <= std::numeric_limits<Fortran::runtime::CppTypeFor<
+                        Fortran::common::TypeCategory::Integer, KIND>>::max();
+  }
+};
+
+static bool FitsInDescriptor(
+    const Descriptor *length, std::int64_t value, Terminator &terminator) {
+  auto typeCode{length->type().GetCategoryAndKind()};
+  int kind{typeCode->second};
+  return Fortran::runtime::ApplyIntegerKind<FitsInIntegerKind, bool>(
+      kind, terminator, value);
+}
+
+std::int32_t RTNAME(GetCommandArgument)(std::int32_t n, const Descriptor *value,
+    const Descriptor *length, const Descriptor *errmsg, const char *sourceFile,
+    int line) {
+  Terminator terminator{sourceFile, line};
+
+  if (value) {
+    RUNTIME_CHECK(terminator, IsValidCharDescriptor(value));
     FillWithSpaces(*value);
   }
 
+  // Store 0 in case we error out later on.
+  if (length) {
+    RUNTIME_CHECK(terminator, IsValidIntDescriptor(length));
+    StoreLengthToDescriptor(length, 0, terminator);
+  }
+
   if (n < 0 || n >= executionEnvironment.argc) {
     return ToErrmsg(errmsg, StatInvalidArgumentNumber);
   }
 
-  if (IsValidCharDescriptor(value)) {
-    const char *arg{executionEnvironment.argv[n]};
-    std::int64_t argLen{StringLength(arg)};
-    if (argLen <= 0) {
-      return ToErrmsg(errmsg, StatMissingArgument);
-    }
+  const char *arg{executionEnvironment.argv[n]};
+  std::int64_t argLen{StringLength(arg)};
+  if (argLen <= 0) {
+    return ToErrmsg(errmsg, StatMissingArgument);
+  }
+
+  if (length && FitsInDescriptor(length, argLen, terminator)) {
+    StoreLengthToDescriptor(length, argLen, terminator);
+  }
 
+  if (value) {
     return CopyToDescriptor(*value, arg, argLen, errmsg);
   }
 
   return StatOk;
 }
 
-template <int KIND> struct FitsInIntegerKind {
-  bool operator()(std::int64_t value) {
-    return value <= std::numeric_limits<Fortran::runtime::CppTypeFor<
-                        Fortran::common::TypeCategory::Integer, KIND>>::max();
-  }
-};
-
 std::int32_t RTNAME(GetCommand)(const Descriptor *value,
     const Descriptor *length, const Descriptor *errmsg, const char *sourceFile,
     int line) {
   Terminator terminator{sourceFile, line};
 
-  auto storeLength = [&](std::int64_t value) {
-    auto typeCode{length->type().GetCategoryAndKind()};
-    int kind{typeCode->second};
-    Fortran::runtime::ApplyIntegerKind<Fortran::runtime::StoreIntegerAt, void>(
-        kind, terminator, *length, /* atIndex = */ 0, value);
-  };
-
   if (value) {
     RUNTIME_CHECK(terminator, IsValidCharDescriptor(value));
   }
@@ -156,7 +170,7 @@ std::int32_t RTNAME(GetCommand)(const Descriptor *value,
   // Store 0 in case we error out later on.
   if (length) {
     RUNTIME_CHECK(terminator, IsValidIntDescriptor(length));
-    storeLength(0);
+    StoreLengthToDescriptor(length, 0, terminator);
   }
 
   auto shouldContinue = [&](std::int32_t stat) -> bool {
@@ -192,15 +206,8 @@ std::int32_t RTNAME(GetCommand)(const Descriptor *value,
     }
   }
 
-  auto fitsInLength = [&](std::int64_t value) -> bool {
-    auto typeCode{length->type().GetCategoryAndKind()};
-    int kind{typeCode->second};
-    return Fortran::runtime::ApplyIntegerKind<FitsInIntegerKind, bool>(
-        kind, terminator, value);
-  };
-
-  if (length && fitsInLength(offset)) {
-    storeLength(offset);
+  if (length && FitsInDescriptor(length, offset, terminator)) {
+    StoreLengthToDescriptor(length, offset, terminator);
   }
 
   // value += spaces for padding

diff  --git a/flang/test/Lower/Intrinsics/get_command_argument-optional.f90 b/flang/test/Lower/Intrinsics/get_command_argument-optional.f90
index bd707f1f13f75..9268a7b3b5f7c 100644
--- a/flang/test/Lower/Intrinsics/get_command_argument-optional.f90
+++ b/flang/test/Lower/Intrinsics/get_command_argument-optional.f90
@@ -19,25 +19,25 @@ subroutine test(number, value, length, status, errmsg)
 ! CHECK:  %[[valueReboxed:.*]] = fir.embox %[[valueUnboxed]]#0 typeparams %[[valueUnboxed]]#1 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.box<!fir.char<1,?>>
 ! CHECK:  %[[valueAbsent:.*]] = fir.absent !fir.box<!fir.char<1,?>>
 ! CHECK:  %[[valueOrAbsent:.*]] = arith.select %[[valueIsPresent]], %[[valueReboxed]], %[[valueAbsent]] : !fir.box<!fir.char<1,?>>
+! CHECK:  %[[lengthIsPresent:.*]] = fir.is_present %[[lengthParam]] : (!fir.ref<i32>) -> i1
+! CHECK:  %[[lengthBoxed:.*]] = fir.embox %[[lengthParam]] : (!fir.ref<i32>) -> !fir.box<i32>
+! CHECK:  %[[lengthAbsent:.*]] = fir.absent !fir.box<i32>
+! CHECK:  %[[lengthOrAbsent:.*]] = arith.select %[[lengthIsPresent]], %[[lengthBoxed]], %[[lengthAbsent]] : !fir.box<i32>
 ! CHECK:  %[[errmsgIsPresent:.*]] = fir.is_present %[[errmsgUnboxed]]#0 : (!fir.ref<!fir.char<1,?>>) -> i1
 ! CHECK:  %[[errmsgReboxed:.*]] = fir.embox %[[errmsgUnboxed]]#0 typeparams %[[errmsgUnboxed]]#1 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.box<!fir.char<1,?>>
 ! CHECK:  %[[errmsgAbsent:.*]] = fir.absent !fir.box<!fir.char<1,?>>
 ! CHECK:  %[[errmsgOrAbsent:.*]] = arith.select %[[errmsgIsPresent]], %[[errmsgReboxed]], %[[errmsgAbsent]] : !fir.box<!fir.char<1,?>>
+! CHECK:  %[[sourceFileString:.*]] = fir.address_of(@_QQcl{{.*}}) : !fir.ref<!fir.char<1,[[sourceFileLength:.*]]>>
+! CHECK:  %[[sourceLine:.*]] = arith.constant [[# @LINE - 17]] : i32
 ! CHECK:  %[[value:.*]] = fir.convert %[[valueOrAbsent]] : (!fir.box<!fir.char<1,?>>) -> !fir.box<none>
+! CHECK:  %[[length:.*]] = fir.convert %[[lengthOrAbsent]] : (!fir.box<i32>) -> !fir.box<none>
 ! CHECK:  %[[errmsg:.*]] = fir.convert %[[errmsgOrAbsent]] : (!fir.box<!fir.char<1,?>>) -> !fir.box<none>
-! CHECK:  %[[status:.*]] = fir.call @_FortranAArgumentValue(%[[number]], %[[value]], %[[errmsg]]) : (i32, !fir.box<none>, !fir.box<none>) -> i32
+! CHECK:  %[[sourceFile:.*]] = fir.convert %[[sourceFileString]] : (!fir.ref<!fir.char<1,[[sourceFileLength]]>>) -> !fir.ref<i8>
+! CHECK:  %[[status:.*]] = fir.call @_FortranAGetCommandArgument(%[[number]], %[[value]], %[[length]], %[[errmsg]], %[[sourceFile]], %[[sourceLine]]) : (i32, !fir.box<none>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> i32
 ! CHECK:  %[[statusI64:.*]] = fir.convert %[[statusParam]] : (!fir.ref<i32>) -> i64
 ! CHECK:  %[[zero:.*]] = arith.constant 0 : i64
 ! CHECK:  %[[statusIsNonNull:.*]] = arith.cmpi ne, %[[statusI64]], %[[zero]] : i64
 ! CHECK:  fir.if %[[statusIsNonNull]] {
 ! CHECK:    fir.store %[[status]] to %[[statusParam]] : !fir.ref<i32>
 ! CHECK:  }
-! CHECK:  %[[lengthI64:.*]] = fir.convert %[[lengthParam]] : (!fir.ref<i32>) -> i64
-! CHECK:  %[[zero2:.*]] = arith.constant 0 : i64
-! CHECK:  %[[lengthIsNonNull:.*]] = arith.cmpi ne, %[[lengthI64]], %[[zero2]] : i64
-! CHECK:  fir.if %[[lengthIsNonNull]] {
-! CHECK:    %[[length:.*]] = fir.call @_FortranAArgumentLength(%[[number]]) : (i32) -> i64
-! CHECK:    %[[lengthTrunc:.*]] = fir.convert %[[length]] : (i64) -> i32
-! CHECK:    fir.store %[[lengthTrunc]] to %[[lengthParam]] : !fir.ref<i32>
-! CHECK:  }
 end subroutine

diff  --git a/flang/test/Lower/Intrinsics/get_command_argument.f90 b/flang/test/Lower/Intrinsics/get_command_argument.f90
index 3dc3f9ac20cd9..1b26e3493a636 100644
--- a/flang/test/Lower/Intrinsics/get_command_argument.f90
+++ b/flang/test/Lower/Intrinsics/get_command_argument.f90
@@ -6,8 +6,7 @@
 subroutine number_only(num)
     integer :: num
     call get_command_argument(num)
-! CHECK-NOT: fir.call @_FortranAArgumentValue
-! CHECK-NOT: fir.call @_FortranAArgumentLength
+! CHECK-NOT: fir.call @_FortranAGetCommandArgument
 ! CHECK-NEXT: return
 end subroutine number_only
 
@@ -21,12 +20,15 @@ subroutine number_and_value_only(num, value)
 ! CHECK-NEXT: %[[valueLength:.*]] = arith.constant 32 : index
 ! CHECK-NEXT: %[[numUnbox:.*]] = fir.load %[[num]] : !fir.ref<i[[DEFAULT_INTEGER_SIZE]]>
 ! CHECK-NEXT: %[[valueBoxed:.*]] = fir.embox %[[valueUnboxed]]#0 typeparams %[[valueLength]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.box<!fir.char<1,?>>
+! CHECK-NEXT: %[[length:.*]] = fir.absent !fir.box<none>
 ! CHECK-NEXT: %[[errmsg:.*]] = fir.absent !fir.box<none>
+! CHECK-NEXT: %[[sourceFileString:.*]] = fir.address_of(@_QQcl{{.*}}) : !fir.ref<!fir.char<1,[[sourceFileLength:.*]]>>
+! CHECK-NEXT: %[[sourceLine:.*]] = arith.constant [[# @LINE - 8]] : i32
 ! CHECK-64-NEXT: %[[numCast:.*]] = fir.convert %[[numUnbox]] : (i64) -> i32
 ! CHECK-NEXT: %[[valueCast:.*]] = fir.convert %[[valueBoxed]] : (!fir.box<!fir.char<1,?>>) -> !fir.box<none>
-! CHECK-32-NEXT: %{{[0-9]+}} = fir.call @_FortranAArgumentValue(%[[numUnbox]], %[[valueCast]], %[[errmsg]]) : (i32, !fir.box<none>, !fir.box<none>) -> i32
-! CHECK-64-NEXT: %{{[0-9]+}} = fir.call @_FortranAArgumentValue(%[[numCast]], %[[valueCast]], %[[errmsg]]) : (i32, !fir.box<none>, !fir.box<none>) -> i32
-! CHECK-NOT: fir.call @_FortranAArgumentLength
+! CHECK-NEXT: %[[sourceFile:.*]] = fir.convert %[[sourceFileString]] : (!fir.ref<!fir.char<1,[[sourceFileLength]]>>) -> !fir.ref<i8>
+! CHECK-32-NEXT: %{{[0-9]+}} = fir.call @_FortranAGetCommandArgument(%[[numUnbox]], %[[valueCast]], %[[length]], %[[errmsg]], %[[sourceFile]], %[[sourceLine]]) : (i32, !fir.box<none>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+! CHECK-64-NEXT: %{{[0-9]+}} = fir.call @_FortranAGetCommandArgument(%[[numCast]], %[[valueCast]], %[[length]], %[[errmsg]], %[[sourceFile]], %[[sourceLine]]) : (i32, !fir.box<none>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> i32
 end subroutine number_and_value_only
 
 ! CHECK-LABEL: func @_QPall_arguments(
@@ -41,19 +43,19 @@ subroutine all_arguments(num, value, length, status, errmsg)
 ! CHECK-NEXT: %[[valueLen:.*]] = arith.constant 32 : index
 ! CHECK-NEXT: %[[numUnboxed:.*]] = fir.load %[[num]] : !fir.ref<i[[DEFAULT_INTEGER_SIZE]]>
 ! CHECK-NEXT: %[[valueBoxed:.*]] = fir.embox %[[valueUnboxed]]#0 typeparams %[[valueLen]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.box<!fir.char<1,?>>
+! CHECK-NEXT: %[[lengthBoxed:.*]] = fir.embox %[[length]] : (!fir.ref<i[[DEFAULT_INTEGER_SIZE]]>) -> !fir.box<i[[DEFAULT_INTEGER_SIZE]]>
 ! CHECK-NEXT: %[[errmsgBoxed:.*]] = fir.embox %[[errmsgUnboxed]]#0 typeparams %[[errmsgLen]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.box<!fir.char<1,?>>
+! CHECK-NEXT: %[[sourceFileString:.*]] = fir.address_of(@_QQcl{{.*}}) : !fir.ref<!fir.char<1,[[sourceFileLength:.*]]>>
+! CHECK-NEXT: %[[sourceLine:.*]] = arith.constant [[# @LINE - 10]] : i32
 ! CHECK-64-NEXT: %[[numCast:.*]] = fir.convert %[[numUnboxed]] : (i64) -> i32
 ! CHECK-NEXT: %[[valueBuffer:.*]] = fir.convert %[[valueBoxed]] : (!fir.box<!fir.char<1,?>>) -> !fir.box<none>
+! CHECK-NEXT: %[[lengthBuffer:.*]] = fir.convert %[[lengthBoxed]] : (!fir.box<i[[DEFAULT_INTEGER_SIZE]]>) -> !fir.box<none>
 ! CHECK-NEXT: %[[errmsgBuffer:.*]] = fir.convert %[[errmsgBoxed]] : (!fir.box<!fir.char<1,?>>) -> !fir.box<none>
-! CHECK-32-NEXT: %[[statusResult:.*]] = fir.call @_FortranAArgumentValue(%[[numUnboxed]], %[[valueBuffer]], %[[errmsgBuffer]]) : (i32, !fir.box<none>, !fir.box<none>) -> i32
-! CHECK-64-NEXT: %[[statusResult32:.*]] = fir.call @_FortranAArgumentValue(%[[numCast]], %[[valueBuffer]], %[[errmsgBuffer]]) : (i32, !fir.box<none>, !fir.box<none>) -> i32
+! CHECK-NEXT: %[[sourceFile:.*]] = fir.convert %[[sourceFileString]] : (!fir.ref<!fir.char<1,[[sourceFileLength]]>>) -> !fir.ref<i8>
+! CHECK-32-NEXT: %[[statusResult:.*]] = fir.call @_FortranAGetCommandArgument(%[[numUnboxed]], %[[valueBuffer]], %[[lengthBuffer]], %[[errmsgBuffer]], %[[sourceFile]], %[[sourceLine]]) : (i32, !fir.box<none>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+! CHECK-64-NEXT: %[[statusResult32:.*]] = fir.call @_FortranAGetCommandArgument(%[[numCast]], %[[valueBuffer]], %[[lengthBuffer]], %[[errmsgBuffer]], %[[sourceFile]], %[[sourceLine]]) : (i32, !fir.box<none>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> i32
 ! CHECK-64: %[[statusResult:.*]] = fir.convert %[[statusResult32]] : (i32) -> i64
 ! CHECK: fir.store %[[statusResult]] to %[[status]] : !fir.ref<i[[DEFAULT_INTEGER_SIZE]]>
-! CHECK-64: %[[numCast:.*]] = fir.convert %[[numUnboxed]] : (i64) -> i32
-! CHECK-32: %[[lengthResult64:.*]] = fir.call @_FortranAArgumentLength(%[[numUnboxed]]) : (i32) -> i64
-! CHECK-64: %[[lengthResult:.*]] = fir.call @_FortranAArgumentLength(%[[numCast]]) : (i32) -> i64
-! CHECK-32-NEXT: %[[lengthResult:.*]] = fir.convert %[[lengthResult64]] : (i64) -> i32
-! CHECK-NEXT: fir.store %[[lengthResult]] to %[[length]] : !fir.ref<i[[DEFAULT_INTEGER_SIZE]]>
 end subroutine all_arguments
 
 ! CHECK-LABEL: func @_QPnumber_and_length_only(
@@ -61,13 +63,17 @@ end subroutine all_arguments
 subroutine number_and_length_only(num, length)
     integer :: num, length
     call get_command_argument(num, LENGTH=length)
-! CHECK-NOT: fir.call @_FortranAArgumentValue
 ! CHECK: %[[numLoaded:.*]] = fir.load %[[num]] : !fir.ref<i[[DEFAULT_INTEGER_SIZE]]>
+! CHECK-NEXT: %[[lengthBoxed:.*]] = fir.embox %[[length]] : (!fir.ref<i[[DEFAULT_INTEGER_SIZE]]>) -> !fir.box<i[[DEFAULT_INTEGER_SIZE]]>
+! CHECK-NEXT: %[[value:.*]] = fir.absent !fir.box<none>
+! CHECK-NEXT: %[[errmsg:.*]] = fir.absent !fir.box<none>
+! CHECK-NEXT: %[[sourceFileString:.*]] = fir.address_of(@_QQcl{{.*}}) : !fir.ref<!fir.char<1,[[sourceFileLength:.*]]>>
+! CHECK-NEXT: %[[sourceLine:.*]] = arith.constant [[# @LINE - 6]] : i32
 ! CHECK-64: %[[numCast:.*]] = fir.convert %[[numLoaded]] : (i64) -> i32
-! CHECK-32: %[[result64:.*]] = fir.call @_FortranAArgumentLength(%[[numLoaded]]) : (i32) -> i64
-! CHECK-64: %[[result:.*]] = fir.call @_FortranAArgumentLength(%[[numCast]]) : (i32) -> i64
-! CHECK-32-NEXT: %[[result:.*]] = fir.convert %[[result64]] : (i64) -> i32
-! CHECK-NEXT: fir.store %[[result]] to %[[length]] : !fir.ref<i[[DEFAULT_INTEGER_SIZE]]>
+! CHECK-NEXT: %[[lengthBuffer:.*]] = fir.convert %[[lengthBoxed]] : (!fir.box<i[[DEFAULT_INTEGER_SIZE]]>) -> !fir.box<none>
+! CHECK-NEXT: %[[sourceFile:.*]] = fir.convert %[[sourceFileString]] : (!fir.ref<!fir.char<1,[[sourceFileLength]]>>) -> !fir.ref<i8>
+! CHECK-32-NEXT: %{{.*}} = fir.call @_FortranAGetCommandArgument(%[[numLoaded]], %[[value]], %[[lengthBuffer]],  %[[errmsg]], %[[sourceFile]], %[[sourceLine]]) : (i32, !fir.box<none>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+! CHECK-64-NEXT: %{{.*}} = fir.call @_FortranAGetCommandArgument(%[[numCast]], %[[value]], %[[lengthBuffer]], %[[errmsg]], %[[sourceFile]], %[[sourceLine]]) : (i32, !fir.box<none>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> i32
 end subroutine number_and_length_only
 
 ! CHECK-LABEL: func @_QPnumber_and_status_only(
@@ -77,13 +83,16 @@ subroutine number_and_status_only(num, status)
     call get_command_argument(num, STATUS=status)
 ! CHECK: %[[numLoaded:.*]] = fir.load %[[num]] : !fir.ref<i[[DEFAULT_INTEGER_SIZE]]>
 ! CHECK-NEXT: %[[value:.*]] = fir.absent !fir.box<none>
+! CHECK-NEXT: %[[length:.*]] = fir.absent !fir.box<none>
 ! CHECK-NEXT: %[[errmsg:.*]] = fir.absent !fir.box<none>
+! CHECK-NEXT: %[[sourceFileString:.*]] = fir.address_of(@_QQcl{{.*}}) : !fir.ref<!fir.char<1,[[sourceFileLength:.*]]>>
+! CHECK-NEXT: %[[sourceLine:.*]] = arith.constant [[# @LINE - 6]] : i32
 ! CHECK-64: %[[numCast:.*]] = fir.convert %[[numLoaded]] : (i64) -> i32
-! CHECK-32-NEXT: %[[result:.*]] = fir.call @_FortranAArgumentValue(%[[numLoaded]], %[[value]], %[[errmsg]]) : (i32, !fir.box<none>, !fir.box<none>) -> i32
-! CHECK-64-NEXT: %[[result32:.*]] = fir.call @_FortranAArgumentValue(%[[numCast]], %[[value]], %[[errmsg]]) : (i32, !fir.box<none>, !fir.box<none>) -> i32
+! CHECK-NEXT: %[[sourceFile:.*]] = fir.convert %[[sourceFileString]] : (!fir.ref<!fir.char<1,[[sourceFileLength]]>>) -> !fir.ref<i8>
+! CHECK-32-NEXT: %[[result:.*]] = fir.call @_FortranAGetCommandArgument(%[[numLoaded]], %[[value]], %[[length]],  %[[errmsg]], %[[sourceFile]], %[[sourceLine]]) : (i32, !fir.box<none>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+! CHECK-64-NEXT: %[[result32:.*]] = fir.call @_FortranAGetCommandArgument(%[[numCast]], %[[value]], %[[length]], %[[errmsg]], %[[sourceFile]], %[[sourceLine]]) : (i32, !fir.box<none>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> i32
 ! CHECK-64: %[[result:.*]] = fir.convert %[[result32]] : (i32) -> i64
 ! CHECK-32: fir.store %[[result]] to %[[status]] : !fir.ref<i[[DEFAULT_INTEGER_SIZE]]>
-! CHECK-NOT: fir.call @_FortranAArgumentLength
 end subroutine number_and_status_only
 
 ! CHECK-LABEL: func @_QPnumber_and_errmsg_only(
@@ -97,9 +106,12 @@ subroutine number_and_errmsg_only(num, errmsg)
 ! CHECK-NEXT: %[[numUnboxed:.*]] = fir.load %[[num]] : !fir.ref<i[[DEFAULT_INTEGER_SIZE]]>
 ! CHECK-NEXT: %[[errmsgBoxed:.*]] = fir.embox %[[errmsgUnboxed]]#0 typeparams %[[errmsgLength]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.box<!fir.char<1,?>>
 ! CHECK-NEXT: %[[value:.*]] = fir.absent !fir.box<none>
+! CHECK-NEXT: %[[length:.*]] = fir.absent !fir.box<none>
+! CHECK-NEXT: %[[sourceFileString:.*]] = fir.address_of(@_QQcl{{.*}}) : !fir.ref<!fir.char<1,[[sourceFileLength:.*]]>>
+! CHECK-NEXT: %[[sourceLine:.*]] = arith.constant [[# @LINE - 8]] : i32
 ! CHECK-64: %[[numCast:.*]] = fir.convert %[[numUnboxed]] : (i64) -> i32
 ! CHECK-NEXT: %[[errmsg:.*]] = fir.convert %[[errmsgBoxed]] : (!fir.box<!fir.char<1,?>>) -> !fir.box<none>
-! CHECK-32-NEXT: %{{[0-9]+}} = fir.call @_FortranAArgumentValue(%[[numUnboxed]], %[[value]], %[[errmsg]]) : (i32, !fir.box<none>, !fir.box<none>) -> i32
-! CHECK-64-NEXT: %{{[0-9]+}} = fir.call @_FortranAArgumentValue(%[[numCast]], %[[value]], %[[errmsg]]) : (i32, !fir.box<none>, !fir.box<none>) -> i32
-! CHECK-NOT: fir.call @_FortranAArgumentLength
+! CHECK-NEXT: %[[sourceFile:.*]] = fir.convert %[[sourceFileString]] : (!fir.ref<!fir.char<1,[[sourceFileLength]]>>) -> !fir.ref<i8>
+! CHECK-32-NEXT: %{{[0-9]+}} = fir.call @_FortranAGetCommandArgument(%[[numUnboxed]], %[[value]], %[[length]], %[[errmsg]], %[[sourceFile]], %[[sourceLine]]) : (i32, !fir.box<none>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+! CHECK-64-NEXT: %{{[0-9]+}} = fir.call @_FortranAGetCommandArgument(%[[numCast]], %[[value]], %[[length]], %[[errmsg]], %[[sourceFile]], %[[sourceLine]]) : (i32, !fir.box<none>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> i32
 end subroutine number_and_errmsg_only

diff  --git a/flang/test/Runtime/no-cpp-dep.c b/flang/test/Runtime/no-cpp-dep.c
index 0f99ccc95e60c..259851615674e 100644
--- a/flang/test/Runtime/no-cpp-dep.c
+++ b/flang/test/Runtime/no-cpp-dep.c
@@ -22,15 +22,13 @@ double RTNAME(CpuTime)();
 
 void RTNAME(ProgramStart)(int, const char *[], const char *[]);
 int32_t RTNAME(ArgumentCount)();
-int32_t RTNAME(ArgumentValue)(
-    int32_t, const struct Descriptor *, const struct Descriptor *);
-int64_t RTNAME(ArgumentLength)(int32_t);
+int32_t RTNAME(GetCommandArgument)(int32_t, const struct Descriptor *,
+    const struct Descriptor *, const struct Descriptor *);
 
 int main() {
   double x = RTNAME(CpuTime)();
   RTNAME(ProgramStart)(0, 0, 0);
   int32_t c = RTNAME(ArgumentCount)();
-  int32_t v = RTNAME(ArgumentValue)(0, 0, 0);
-  int32_t l = RTNAME(ArgumentLength)(0);
-  return x + c + l;
+  int32_t v = RTNAME(GetCommandArgument)(0, 0, 0, 0);
+  return x + c + v;
 }

diff  --git a/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp b/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
index 856e2022b93e8..28dad42e64c8a 100644
--- a/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
+++ b/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
@@ -17,27 +17,19 @@ TEST_F(RuntimeCallTest, genCommandArgumentCountTest) {
       /*addLocArgs=*/false);
 }
 
-TEST_F(RuntimeCallTest, genArgumentValue) {
+TEST_F(RuntimeCallTest, genGetCommandArgument) {
   mlir::Location loc = firBuilder->getUnknownLoc();
   mlir::Type intTy = firBuilder->getDefaultIntegerType();
-  mlir::Type charTy = fir::BoxType::get(firBuilder->getNoneType());
+  mlir::Type boxTy = fir::BoxType::get(firBuilder->getNoneType());
   mlir::Value number = firBuilder->create<fir::UndefOp>(loc, intTy);
-  mlir::Value value = firBuilder->create<fir::UndefOp>(loc, charTy);
-  mlir::Value errmsg = firBuilder->create<fir::UndefOp>(loc, charTy);
-  mlir::Value result =
-      fir::runtime::genArgumentValue(*firBuilder, loc, number, value, errmsg);
-  checkCallOp(result.getDefiningOp(), "_FortranAArgumentValue", /*nbArgs=*/3,
-      /*addLocArgs=*/false);
-}
-
-TEST_F(RuntimeCallTest, genArgumentLen) {
-  mlir::Location loc = firBuilder->getUnknownLoc();
-  mlir::Type intTy = firBuilder->getDefaultIntegerType();
-  mlir::Value number = firBuilder->create<fir::UndefOp>(loc, intTy);
-  mlir::Value result =
-      fir::runtime::genArgumentLength(*firBuilder, loc, number);
-  checkCallOp(result.getDefiningOp(), "_FortranAArgumentLength", /*nbArgs=*/1,
-      /*addLocArgs=*/false);
+  mlir::Value value = firBuilder->create<fir::UndefOp>(loc, boxTy);
+  mlir::Value length = firBuilder->create<fir::UndefOp>(loc, boxTy);
+  mlir::Value errmsg = firBuilder->create<fir::UndefOp>(loc, boxTy);
+  mlir::Value result = fir::runtime::genGetCommandArgument(
+      *firBuilder, loc, number, value, length, errmsg);
+  checkCallOp(result.getDefiningOp(), "_FortranAGetCommandArgument",
+      /*nbArgs=*/4,
+      /*addLocArgs=*/true);
 }
 
 TEST_F(RuntimeCallTest, genEnvVariableValue) {

diff  --git a/flang/unittests/Runtime/CommandTest.cpp b/flang/unittests/Runtime/CommandTest.cpp
index 85f04267edd32..b44679cd9c51b 100644
--- a/flang/unittests/Runtime/CommandTest.cpp
+++ b/flang/unittests/Runtime/CommandTest.cpp
@@ -105,11 +105,11 @@ class CommandFixture : public ::testing::Test {
     SCOPED_TRACE(n);
     SCOPED_TRACE("Checking argument:");
     CheckValue(
-        [&](const Descriptor *value, const Descriptor *,
+        [&](const Descriptor *value, const Descriptor *length,
             const Descriptor *errmsg) {
-          return RTNAME(ArgumentValue)(n, value, errmsg);
+          return RTNAME(GetCommandArgument)(n, value, length, errmsg);
         },
-        expectedValue);
+        expectedValue, std::strlen(expectedValue));
   }
 
   void CheckCommandValue(const char *args[], int n) const {
@@ -162,13 +162,19 @@ class CommandFixture : public ::testing::Test {
     OwningPtr<Descriptor> value{CreateEmptyCharDescriptor()};
     ASSERT_NE(value, nullptr);
 
+    OwningPtr<Descriptor> length{EmptyIntDescriptor()};
+    ASSERT_NE(length, nullptr);
+
     OwningPtr<Descriptor> err{errStr ? CreateEmptyCharDescriptor() : nullptr};
 
-    EXPECT_GT(RTNAME(ArgumentValue)(n, value.get(), err.get()), 0);
+    EXPECT_GT(
+        RTNAME(GetCommandArgument)(n, value.get(), length.get(), err.get()), 0);
 
     std::string spaces(value->ElementBytes(), ' ');
     CheckDescriptorEqStr(value.get(), spaces);
 
+    CheckDescriptorEqInt(length.get(), 0);
+
     if (errStr) {
       std::string paddedErrStr(GetPaddedStr(errStr, err->ElementBytes()));
       CheckDescriptorEqStr(err.get(), paddedErrStr);
@@ -215,14 +221,10 @@ class ZeroArguments : public CommandFixture {
 
 TEST_F(ZeroArguments, ArgumentCount) { EXPECT_EQ(0, RTNAME(ArgumentCount)()); }
 
-TEST_F(ZeroArguments, ArgumentLength) {
-  EXPECT_EQ(0, RTNAME(ArgumentLength)(-1));
-  EXPECT_EQ(8, RTNAME(ArgumentLength)(0));
-  EXPECT_EQ(0, RTNAME(ArgumentLength)(1));
-}
-
-TEST_F(ZeroArguments, ArgumentValue) {
+TEST_F(ZeroArguments, GetCommandArgument) {
+  CheckMissingArgumentValue(-1);
   CheckArgumentValue(commandOnlyArgv[0], 0);
+  CheckMissingArgumentValue(1);
 }
 
 TEST_F(ZeroArguments, GetCommand) { CheckCommandValue(commandOnlyArgv, 1); }
@@ -235,16 +237,11 @@ class OneArgument : public CommandFixture {
 
 TEST_F(OneArgument, ArgumentCount) { EXPECT_EQ(1, RTNAME(ArgumentCount)()); }
 
-TEST_F(OneArgument, ArgumentLength) {
-  EXPECT_EQ(0, RTNAME(ArgumentLength)(-1));
-  EXPECT_EQ(8, RTNAME(ArgumentLength)(0));
-  EXPECT_EQ(20, RTNAME(ArgumentLength)(1));
-  EXPECT_EQ(0, RTNAME(ArgumentLength)(2));
-}
-
-TEST_F(OneArgument, ArgumentValue) {
+TEST_F(OneArgument, GetCommandArgument) {
+  CheckMissingArgumentValue(-1);
   CheckArgumentValue(oneArgArgv[0], 0);
   CheckArgumentValue(oneArgArgv[1], 1);
+  CheckMissingArgumentValue(2);
 }
 
 TEST_F(OneArgument, GetCommand) { CheckCommandValue(oneArgArgv, 2); }
@@ -262,17 +259,7 @@ TEST_F(SeveralArguments, ArgumentCount) {
   EXPECT_EQ(4, RTNAME(ArgumentCount)());
 }
 
-TEST_F(SeveralArguments, ArgumentLength) {
-  EXPECT_EQ(0, RTNAME(ArgumentLength)(-1));
-  EXPECT_EQ(8, RTNAME(ArgumentLength)(0));
-  EXPECT_EQ(16, RTNAME(ArgumentLength)(1));
-  EXPECT_EQ(0, RTNAME(ArgumentLength)(2));
-  EXPECT_EQ(22, RTNAME(ArgumentLength)(3));
-  EXPECT_EQ(1, RTNAME(ArgumentLength)(4));
-  EXPECT_EQ(0, RTNAME(ArgumentLength)(5));
-}
-
-TEST_F(SeveralArguments, ArgumentValue) {
+TEST_F(SeveralArguments, GetCommandArgument) {
   CheckArgumentValue(severalArgsArgv[0], 0);
   CheckArgumentValue(severalArgsArgv[1], 1);
   CheckArgumentValue(severalArgsArgv[3], 3);
@@ -280,10 +267,11 @@ TEST_F(SeveralArguments, ArgumentValue) {
 }
 
 TEST_F(SeveralArguments, NoArgumentValue) {
-  // Make sure we don't crash if the 'value' and 'error' parameters aren't
-  // passed.
-  EXPECT_EQ(RTNAME(ArgumentValue)(2, nullptr, nullptr), 0);
-  EXPECT_GT(RTNAME(ArgumentValue)(-1, nullptr, nullptr), 0);
+  // Make sure we don't crash if the 'value', 'length' and 'error' parameters
+  // aren't passed.
+  EXPECT_GT(RTNAME(GetCommandArgument)(2), 0);
+  EXPECT_EQ(RTNAME(GetCommandArgument)(1), 0);
+  EXPECT_GT(RTNAME(GetCommandArgument)(-1), 0);
 }
 
 TEST_F(SeveralArguments, MissingArguments) {
@@ -296,14 +284,19 @@ TEST_F(SeveralArguments, MissingArguments) {
 TEST_F(SeveralArguments, ArgValueTooShort) {
   OwningPtr<Descriptor> tooShort{CreateEmptyCharDescriptor<15>()};
   ASSERT_NE(tooShort, nullptr);
-  EXPECT_EQ(RTNAME(ArgumentValue)(1, tooShort.get(), nullptr), -1);
+  EXPECT_EQ(RTNAME(GetCommandArgument)(1, tooShort.get()), -1);
   CheckDescriptorEqStr(tooShort.get(), severalArgsArgv[1]);
 
+  OwningPtr<Descriptor> length{EmptyIntDescriptor()};
+  ASSERT_NE(length, nullptr);
   OwningPtr<Descriptor> errMsg{CreateEmptyCharDescriptor()};
   ASSERT_NE(errMsg, nullptr);
 
-  EXPECT_EQ(RTNAME(ArgumentValue)(1, tooShort.get(), errMsg.get()), -1);
+  EXPECT_EQ(
+      RTNAME(GetCommandArgument)(1, tooShort.get(), length.get(), errMsg.get()),
+      -1);
 
+  CheckDescriptorEqInt(length.get(), 16);
   std::string expectedErrMsg{
       GetPaddedStr("Value too short", errMsg->ElementBytes())};
   CheckDescriptorEqStr(errMsg.get(), expectedErrMsg);
@@ -311,7 +304,7 @@ TEST_F(SeveralArguments, ArgValueTooShort) {
 
 TEST_F(SeveralArguments, ArgErrMsgTooShort) {
   OwningPtr<Descriptor> errMsg{CreateEmptyCharDescriptor<3>()};
-  EXPECT_GT(RTNAME(ArgumentValue)(-1, nullptr, errMsg.get()), 0);
+  EXPECT_GT(RTNAME(GetCommandArgument)(-1, nullptr, nullptr, errMsg.get()), 0);
   CheckDescriptorEqStr(errMsg.get(), "Inv");
 }
 


        


More information about the flang-commits mailing list