forked from OSchip/llvm-project
[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
This commit is contained in:
parent
bf4f9a468a
commit
eb7a02ea00
|
@ -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.
|
||||
|
|
|
@ -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 different 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 different functions, since most
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,27 +98,12 @@ 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)) {
|
||||
FillWithSpaces(*value);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return CopyToDescriptor(*value, arg, argLen, errmsg);
|
||||
}
|
||||
|
||||
return StatOk;
|
||||
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 {
|
||||
|
@ -137,17 +113,55 @@ template <int KIND> struct FitsInIntegerKind {
|
|||
}
|
||||
};
|
||||
|
||||
std::int32_t RTNAME(GetCommand)(const Descriptor *value,
|
||||
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};
|
||||
|
||||
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));
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
std::int32_t RTNAME(GetCommand)(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));
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 @@ call get_command_argument(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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -105,11 +105,11 @@ protected:
|
|||
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 @@ protected:
|
|||
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 @@ protected:
|
|||
|
||||
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 @@ protected:
|
|||
|
||||
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");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue