[flang-commits] [flang] af63d17 - [flang] GET_COMMAND_ARGUMENT(LENGTH) runtime implementation
Diana Picus via flang-commits
flang-commits at lists.llvm.org
Tue Sep 28 01:37:58 PDT 2021
Author: Diana Picus
Date: 2021-09-28T08:32:19Z
New Revision: af63d1791b102ed8bdd8b836ce8ab773c019d1a1
URL: https://github.com/llvm/llvm-project/commit/af63d1791b102ed8bdd8b836ce8ab773c019d1a1
DIFF: https://github.com/llvm/llvm-project/commit/af63d1791b102ed8bdd8b836ce8ab773c019d1a1.diff
LOG: [flang] GET_COMMAND_ARGUMENT(LENGTH) runtime implementation
Implement the ArgumentLength entry point of GET_COMMAND_ARGUMENT. Also
introduce a fixture for the tests.
Note that this also changes the interface for ArgumentLength from
returning a 4-byte integer to returning an 8-byte integer.
Differential Revision: https://reviews.llvm.org/D109227
Added:
Modified:
flang/include/flang/Runtime/command.h
flang/runtime/command.cpp
flang/test/Runtime/no-cpp-dep.c
flang/unittests/Runtime/CommandTest.cpp
Removed:
################################################################################
diff --git a/flang/include/flang/Runtime/command.h b/flang/include/flang/Runtime/command.h
index 5e98b41072918..f5f20a5a4f29a 100644
--- a/flang/include/flang/Runtime/command.h
+++ b/flang/include/flang/Runtime/command.h
@@ -9,9 +9,10 @@
#ifndef FORTRAN_RUNTIME_COMMAND_H_
#define FORTRAN_RUNTIME_COMMAND_H_
-#include "flang/Runtime/cpp-type.h"
#include "flang/Runtime/entry-names.h"
+#include <cstdint>
+
namespace Fortran::runtime {
class Descriptor;
@@ -20,7 +21,7 @@ extern "C" {
//
// Lowering may need to cast the result to match the precision of the default
// integer kind.
-CppTypeFor<TypeCategory::Integer, 4> RTNAME(ArgumentCount)();
+std::int32_t RTNAME(ArgumentCount)();
// 16.9.83 GET_COMMAND_ARGUMENT
// We're breaking up the interface into several
diff erent functions, since most
@@ -28,14 +29,12 @@ CppTypeFor<TypeCategory::Integer, 4> RTNAME(ArgumentCount)();
// Try to get the value of the n'th argument.
// Returns a STATUS as described in the standard.
-CppTypeFor<TypeCategory::Integer, 4> RTNAME(ArgumentValue)(
- CppTypeFor<TypeCategory::Integer, 4> n, const Descriptor *value,
- const Descriptor *errmsg);
+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.
-CppTypeFor<TypeCategory::Integer, 4> RTNAME(ArgumentLength)(
- CppTypeFor<TypeCategory::Integer, 4> n);
+std::int64_t RTNAME(ArgumentLength)(std::int32_t n);
}
} // namespace Fortran::runtime
diff --git a/flang/runtime/command.cpp b/flang/runtime/command.cpp
index 5d11d6c0c96c8..1a55061749a1c 100644
--- a/flang/runtime/command.cpp
+++ b/flang/runtime/command.cpp
@@ -8,9 +8,10 @@
#include "flang/Runtime/command.h"
#include "environment.h"
+#include <limits>
namespace Fortran::runtime {
-CppTypeFor<TypeCategory::Integer, 4> RTNAME(ArgumentCount)() {
+std::int32_t RTNAME(ArgumentCount)() {
int argc{executionEnvironment.argc};
if (argc > 1) {
// C counts the command name as one of the arguments, but Fortran doesn't.
@@ -18,4 +19,19 @@ CppTypeFor<TypeCategory::Integer, 4> RTNAME(ArgumentCount)() {
}
return 0;
}
+
+std::int64_t RTNAME(ArgumentLength)(std::int32_t n) {
+ if (n < 0 || n >= executionEnvironment.argc) {
+ return 0;
+ }
+
+ std::size_t length{std::strlen(executionEnvironment.argv[n])};
+ if constexpr (sizeof(std::size_t) <= sizeof(std::int64_t)) {
+ return static_cast<std::int64_t>(length);
+ } else {
+ std::size_t max{std::numeric_limits<std::int64_t>::max()};
+ return length > max ? 0 // Just fail.
+ : static_cast<std::int64_t>(length);
+ }
+}
} // namespace Fortran::runtime
diff --git a/flang/test/Runtime/no-cpp-dep.c b/flang/test/Runtime/no-cpp-dep.c
index 9f3b8b9269eed..9970e098c34ff 100644
--- a/flang/test/Runtime/no-cpp-dep.c
+++ b/flang/test/Runtime/no-cpp-dep.c
@@ -5,19 +5,29 @@ a C compiler.
REQUIRES: c-compiler
-RUN: %cc -std=c90 %s -I%include %libruntime %libdecimal -o /dev/null
+RUN: %cc -std=c99 %s -I%include %libruntime %libdecimal -lm -o /dev/null
*/
#include "flang/Runtime/entry-names.h"
+#include <stdint.h>
/*
Manually add declarations for the runtime functions that we want to make sure
we're testing. We can't include any headers directly since they likely contain
C++ code that would explode here.
*/
+struct Descriptor;
+
double RTNAME(CpuTime)();
+void RTNAME(ProgramStart)(int, const char *[], const char *[]);
+int32_t RTNAME(ArgumentCount)();
+int64_t RTNAME(ArgumentLength)(int32_t);
+
int main() {
double x = RTNAME(CpuTime)();
- return x;
+ RTNAME(ProgramStart)(0, 0, 0);
+ int32_t c = RTNAME(ArgumentCount)();
+ int32_t l = RTNAME(ArgumentLength)(0);
+ return x + c + l;
}
diff --git a/flang/unittests/Runtime/CommandTest.cpp b/flang/unittests/Runtime/CommandTest.cpp
index 84a05fc34e10b..3841bbe0ed3ba 100644
--- a/flang/unittests/Runtime/CommandTest.cpp
+++ b/flang/unittests/Runtime/CommandTest.cpp
@@ -13,20 +13,61 @@
using namespace Fortran::runtime;
-TEST(ArgumentCount, ZeroArguments) {
- const char *argv[]{"aProgram"};
- RTNAME(ProgramStart)(1, argv, {});
- EXPECT_EQ(0, RTNAME(ArgumentCount)());
+class CommandFixture : public ::testing::Test {
+protected:
+ CommandFixture(int argc, const char *argv[]) {
+ RTNAME(ProgramStart)(argc, argv, {});
+ }
+};
+
+static const char *commandOnlyArgv[]{"aProgram"};
+class ZeroArguments : public CommandFixture {
+protected:
+ ZeroArguments() : CommandFixture(1, commandOnlyArgv) {}
+};
+
+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(ArgumentCount, OneArgument) {
- const char *argv[]{"aProgram", "anArgument"};
- RTNAME(ProgramStart)(2, argv, {});
- EXPECT_EQ(1, RTNAME(ArgumentCount)());
+static const char *oneArgArgv[]{"aProgram", "anArgumentOfLength20"};
+class OneArgument : public CommandFixture {
+protected:
+ OneArgument() : CommandFixture(2, oneArgArgv) {}
+};
+
+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(ArgumentCount, SeveralArguments) {
- const char *argv[]{"aProgram", "arg1", "arg2", "arg3", "arg4"};
- RTNAME(ProgramStart)(5, argv, {});
+static const char *severalArgsArgv[]{
+ "aProgram", "16-char-long-arg", "", "-22-character-long-arg", "o"};
+class SeveralArguments : public CommandFixture {
+protected:
+ SeveralArguments()
+ : CommandFixture(sizeof(severalArgsArgv) / sizeof(*severalArgsArgv),
+ severalArgsArgv) {}
+};
+
+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));
+}
More information about the flang-commits
mailing list