[clang] [flang] [llvm] [libc] [mlir] [flang] Fold MATMUL() (PR #72176)
https://github.com/klausler updated https://github.com/llvm/llvm-project/pull/72176 >From e2e0e60c5cf01b5e99cb2494e2444b91d1f6605d Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Fri, 3 Nov 2023 13:04:01 -0700 Subject: [PATCH] [flang] Fold MATMUL() Implements constant folding for matrix multiplication for all four accepted type categories. --- flang/lib/Evaluate/fold-complex.cpp | 4 +- flang/lib/Evaluate/fold-integer.cpp | 4 +- flang/lib/Evaluate/fold-logical.cpp | 4 +- flang/lib/Evaluate/fold-matmul.h| 103 flang/lib/Evaluate/fold-real.cpp| 4 +- flang/lib/Evaluate/fold-reduction.h | 4 +- flang/test/Evaluate/fold-matmul.f90 | 41 +++ 7 files changed, 158 insertions(+), 6 deletions(-) create mode 100644 flang/lib/Evaluate/fold-matmul.h create mode 100644 flang/test/Evaluate/fold-matmul.f90 diff --git a/flang/lib/Evaluate/fold-complex.cpp b/flang/lib/Evaluate/fold-complex.cpp index e40e3a37df14948..3260f82ffe8d734 100644 --- a/flang/lib/Evaluate/fold-complex.cpp +++ b/flang/lib/Evaluate/fold-complex.cpp @@ -7,6 +7,7 @@ //===--===// #include "fold-implementation.h" +#include "fold-matmul.h" #include "fold-reduction.h" namespace Fortran::evaluate { @@ -64,13 +65,14 @@ Expr> FoldIntrinsicFunction( } } else if (name == "dot_product") { return FoldDotProduct(context, std::move(funcRef)); + } else if (name == "matmul") { +return FoldMatmul(context, std::move(funcRef)); } else if (name == "product") { auto one{Scalar::FromInteger(value::Integer<8>{1}).value}; return FoldProduct(context, std::move(funcRef), Scalar{one}); } else if (name == "sum") { return FoldSum(context, std::move(funcRef)); } - // TODO: matmul return Expr{std::move(funcRef)}; } diff --git a/flang/lib/Evaluate/fold-integer.cpp b/flang/lib/Evaluate/fold-integer.cpp index dedfc20a491cd88..2882369105f6626 100644 --- a/flang/lib/Evaluate/fold-integer.cpp +++ b/flang/lib/Evaluate/fold-integer.cpp @@ -7,6 +7,7 @@ //===--===// #include "fold-implementation.h" +#include "fold-matmul.h" #include "fold-reduction.h" #include "flang/Evaluate/check-expression.h" @@ -1042,6 +1043,8 @@ Expr> FoldIntrinsicFunction( ScalarFunc([&fptr](const Scalar &places) -> Scalar { return fptr(static_cast(places.ToInt64())); })); + } else if (name == "matmul") { +return FoldMatmul(context, std::move(funcRef)); } else if (name == "max") { return FoldMINorMAX(context, std::move(funcRef), Ordering::Greater); } else if (name == "max0" || name == "max1") { @@ -1279,7 +1282,6 @@ Expr> FoldIntrinsicFunction( } else if (name == "ubound") { return UBOUND(context, std::move(funcRef)); } - // TODO: dot_product, matmul, sign return Expr{std::move(funcRef)}; } diff --git a/flang/lib/Evaluate/fold-logical.cpp b/flang/lib/Evaluate/fold-logical.cpp index bfedc32a33a8bad..82a5cb20db9e409 100644 --- a/flang/lib/Evaluate/fold-logical.cpp +++ b/flang/lib/Evaluate/fold-logical.cpp @@ -7,6 +7,7 @@ //===--===// #include "fold-implementation.h" +#include "fold-matmul.h" #include "fold-reduction.h" #include "flang/Evaluate/check-expression.h" #include "flang/Runtime/magic-numbers.h" @@ -231,6 +232,8 @@ Expr> FoldIntrinsicFunction( if (auto *expr{UnwrapExpr>(args[0])}) { return Fold(context, ConvertToType(std::move(*expr))); } + } else if (name == "matmul") { +return FoldMatmul(context, std::move(funcRef)); } else if (name == "out_of_range") { if (Expr * cx{UnwrapExpr>(args[0])}) { auto restorer{context.messages().DiscardMessages()}; @@ -367,7 +370,6 @@ Expr> FoldIntrinsicFunction( name == "__builtin_ieee_support_underflow_control") { return Expr{true}; } - // TODO: logical, matmul, parity return Expr{std::move(funcRef)}; } diff --git a/flang/lib/Evaluate/fold-matmul.h b/flang/lib/Evaluate/fold-matmul.h new file mode 100644 index 000..27b6db1fd8bf025 --- /dev/null +++ b/flang/lib/Evaluate/fold-matmul.h @@ -0,0 +1,103 @@ +//===-- lib/Evaluate/fold-matmul.h ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#ifndef FORTRAN_EVALUATE_FOLD_MATMUL_H_ +#define FORTRAN_EVALUATE_FOLD_MATMUL_H_ + +#include "fold-implementation.h" + +namespace Fortran::evaluate { + +template +static Expr FoldMatmul(FoldingContext &context, FunctionRef &&funcRef) { + using Element = typename Constant::Element; + auto args{funcRef.arguments()}; + CHECK(arg
[clang] [llvm] [flang] [clang-tools-extra] [flang] GETLOG runtime and extension implementation: get login username (PR #74628)
@@ -657,6 +657,11 @@ CALL CO_REDUCE CALL CO_SUM ``` +### Library subroutine klausler wrote: Please put this new section later, after all of the non-standard intrinsics, so the actual intrinsic procedures appear together. https://github.com/llvm/llvm-project/pull/74628 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang-tools-extra] [flang] [clang] [flang] GETLOG runtime and extension implementation: get login username (PR #74628)
@@ -10,10 +10,52 @@ // extensions that will eventually be implemented in Fortran. #include "flang/Runtime/extensions.h" +#include "terminator.h" +#include "flang/Runtime/character.h" #include "flang/Runtime/command.h" #include "flang/Runtime/descriptor.h" #include "flang/Runtime/io-api.h" +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#define NOMINMAX +#include + +#include // wcstombs_s +#include // UNLEN=256 +#include // wchar_t cast to LPWSTR +#pragma comment(lib, "Advapi32.lib") // Link Advapi32.lib for GetUserName +#define LOGIN_NAME_MAX UNLEN + +inline int getlogin_r(char *buf, size_t bufSize) { + wchar_t w_username[UNLEN + 1]; + DWORD nameLen{UNLEN + 1}; + + if (GetUserName(w_username, &nameLen)) { +// Convert the wchar_t string to a regular C string using wcstombs_s +if (wcstombs_s(nullptr, buf, bufSize, w_username, _TRUNCATE) != 0) { + // Conversion failed + return -1; +} +return (buf[0] == 0 ? -1 : 0); + } else { +return -1; + } + return -1; klausler wrote: This line will never be reached. https://github.com/llvm/llvm-project/pull/74628 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [flang] [clang-tools-extra] [clang] [flang] GETLOG runtime and extension implementation: get login username (PR #74628)
@@ -37,5 +79,34 @@ void FORTRAN_PROCEDURE_NAME(getarg)( (void)RTNAME(GetCommandArgument)( n, &value, nullptr, nullptr, __FILE__, __LINE__); } + +// CALL GETLOG(USRNAME) +void FORTRAN_PROCEDURE_NAME(getlog)(std::int8_t *arg, std::int64_t length) { + const int nameMaxLen{LOGIN_NAME_MAX + 1}; + char str[nameMaxLen]; + + int error{getlogin_r(str, nameMaxLen)}; + Terminator terminator{__FILE__, __LINE__}; + if (error != 0) { +// if there is error, then get username from environment variable +#ifdef _WIN32 +const int charLen = 9; +char envName[charLen] = "USERNAME"; +#else +const int charLen = 8; +char envName[charLen] = "LOGNAME"; +#endif +std::size_t n{std::strlen(envName)}; klausler wrote: `const std::size_t n{sizeof envName};` or just use `sizeof envName` below in place of `n`. https://github.com/llvm/llvm-project/pull/74628 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [clang-tools-extra] [flang] [flang] GETLOG runtime and extension implementation: get login username (PR #74628)
@@ -37,5 +79,34 @@ void FORTRAN_PROCEDURE_NAME(getarg)( (void)RTNAME(GetCommandArgument)( n, &value, nullptr, nullptr, __FILE__, __LINE__); } + +// CALL GETLOG(USRNAME) +void FORTRAN_PROCEDURE_NAME(getlog)(std::int8_t *arg, std::int64_t length) { + const int nameMaxLen{LOGIN_NAME_MAX + 1}; + char str[nameMaxLen]; + + int error{getlogin_r(str, nameMaxLen)}; + Terminator terminator{__FILE__, __LINE__}; + if (error != 0) { +// if there is error, then get username from environment variable +#ifdef _WIN32 +const int charLen = 9; klausler wrote: `static const char envName[]{"USERNAME"};` https://github.com/llvm/llvm-project/pull/74628 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [flang] [llvm] [flang] GETLOG runtime and extension implementation: get login username (PR #74628)
@@ -10,10 +10,52 @@ // extensions that will eventually be implemented in Fortran. #include "flang/Runtime/extensions.h" +#include "terminator.h" +#include "flang/Runtime/character.h" #include "flang/Runtime/command.h" #include "flang/Runtime/descriptor.h" #include "flang/Runtime/io-api.h" +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#define NOMINMAX +#include + +#include // wcstombs_s +#include // UNLEN=256 +#include // wchar_t cast to LPWSTR +#pragma comment(lib, "Advapi32.lib") // Link Advapi32.lib for GetUserName +#define LOGIN_NAME_MAX UNLEN + +inline int getlogin_r(char *buf, size_t bufSize) { + wchar_t w_username[UNLEN + 1]; + DWORD nameLen{UNLEN + 1}; + + if (GetUserName(w_username, &nameLen)) { +// Convert the wchar_t string to a regular C string using wcstombs_s +if (wcstombs_s(nullptr, buf, bufSize, w_username, _TRUNCATE) != 0) { + // Conversion failed + return -1; +} +return (buf[0] == 0 ? -1 : 0); klausler wrote: Please write the NUL character as a character literal (`'\0'`). The parentheses are needless. https://github.com/llvm/llvm-project/pull/74628 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [llvm] [clang] [flang] [flang] GETLOG runtime and extension implementation: get login username (PR #74628)
@@ -37,5 +79,34 @@ void FORTRAN_PROCEDURE_NAME(getarg)( (void)RTNAME(GetCommandArgument)( n, &value, nullptr, nullptr, __FILE__, __LINE__); } + +// CALL GETLOG(USRNAME) +void FORTRAN_PROCEDURE_NAME(getlog)(std::int8_t *arg, std::int64_t length) { + const int nameMaxLen{LOGIN_NAME_MAX + 1}; + char str[nameMaxLen]; + + int error{getlogin_r(str, nameMaxLen)}; + Terminator terminator{__FILE__, __LINE__}; + if (error != 0) { +// if there is error, then get username from environment variable +#ifdef _WIN32 +const int charLen = 9; klausler wrote: It needn't be `static` or `const`. https://github.com/llvm/llvm-project/pull/74628 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang] [llvm] [flang] [flang] GETLOG runtime and extension implementation: get login username (PR #74628)
@@ -37,5 +79,34 @@ void FORTRAN_PROCEDURE_NAME(getarg)( (void)RTNAME(GetCommandArgument)( n, &value, nullptr, nullptr, __FILE__, __LINE__); } + +// CALL GETLOG(USRNAME) +void FORTRAN_PROCEDURE_NAME(getlog)(std::int8_t *arg, std::int64_t length) { + const int nameMaxLen{LOGIN_NAME_MAX + 1}; + char str[nameMaxLen]; + + int error{getlogin_r(str, nameMaxLen)}; + Terminator terminator{__FILE__, __LINE__}; + if (error != 0) { +// if there is error, then get username from environment variable +#ifdef _WIN32 +const int charLen = 9; +char envName[charLen] = "USERNAME"; +#else +const int charLen = 8; +char envName[charLen] = "LOGNAME"; +#endif +std::size_t n{std::strlen(envName)}; klausler wrote: It is generally more error-prone to use explicit integer counts for things that the compiler can count correctly for you. https://github.com/llvm/llvm-project/pull/74628 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [flang] [libc] [mlir] [flang] Fold MATMUL() (PR #72176)
klausler wrote: ping! https://github.com/llvm/llvm-project/pull/72176 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[flang] [llvm] [clang] [mlir] [libc] [flang] Fold MATMUL() (PR #72176)
https://github.com/klausler closed https://github.com/llvm/llvm-project/pull/72176 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[flang] [clang] [llvm] [clang-tools-extra] [flang ]GETLOG runtime and extension implementation: get login username (PR #70917)
klausler wrote: > Hello @klausler, could you please share your thoughts or comments on this > patch, particularly with regard to the Windows side? Thanks in advance. You should use modern C++ braced initialization in flang/runtime. https://github.com/llvm/llvm-project/pull/70917 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [clang-tools-extra] [flang] [flang] GETLOG runtime and extension implementation: get login username (PR #74628)
@@ -6,6 +6,37 @@ // //===--===// +// Defines a utility function for copying and padding characters +#ifndef CHARACTER_H +#define CHARACTER_H klausler wrote: Either way, the name of the guard macro is wrong. https://github.com/llvm/llvm-project/pull/74628 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [clang-tools-extra] [flang] [flang] GETLOG runtime and extension implementation: get login username (PR #74628)
@@ -10,13 +10,29 @@ // extensions that will eventually be implemented in Fortran. #include "flang/Runtime/extensions.h" +#include "flang/Runtime/character.h" #include "flang/Runtime/command.h" #include "flang/Runtime/descriptor.h" #include "flang/Runtime/io-api.h" +#if _REENTRANT || _POSIX_C_SOURCE >= 199506L +// System is posix-compliant and has getlogin_r +#include +#endif + extern "C" { namespace Fortran::runtime { + +void GetUsernameEnvVar( +const char *envName, std::byte *arg, std::int64_t length) { + Descriptor name{ + *Descriptor::Create(1, sizeof(envName), const_cast(envName), 0)}; klausler wrote: Exactly. https://github.com/llvm/llvm-project/pull/74628 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang] [flang] [llvm] [flang] GETLOG runtime and extension implementation: get login username (PR #74628)
https://github.com/klausler approved this pull request. https://github.com/llvm/llvm-project/pull/74628 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [llvm] [flang] [clang] [flang ]GETLOG runtime and extension implementation: get login username (PR #70917)
@@ -9,6 +9,17 @@ // Defines the API between compiled code and the implementations of time-related // intrinsic subroutines in the runtime library. +// time-intrinsic.h +#ifndef TIME_INTRINSIC_H +#define TIME_INTRINSIC_H + +#include + +void copyBufferAndPad( +char *dest, std::size_t destChars, char *buffer, std::size_t len); klausler wrote: `buffer` can be `const char *`, yes? https://github.com/llvm/llvm-project/pull/70917 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [flang] [llvm] [clang] [flang ]GETLOG runtime and extension implementation: get login username (PR #70917)
@@ -9,6 +9,17 @@ // Defines the API between compiled code and the implementations of time-related // intrinsic subroutines in the runtime library. +// time-intrinsic.h +#ifndef TIME_INTRINSIC_H +#define TIME_INTRINSIC_H + +#include + +void copyBufferAndPad( klausler wrote: Function names are capitalized in flang/runtime. https://github.com/llvm/llvm-project/pull/70917 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [llvm] [clang] [flang] [flang ]GETLOG runtime and extension implementation: get login username (PR #70917)
@@ -751,7 +751,7 @@ This phase currently supports all the intrinsic procedures listed above but the | Object characteristic inquiry functions | ALLOCATED, ASSOCIATED, EXTENDS_TYPE_OF, IS_CONTIGUOUS, PRESENT, RANK, SAME_TYPE, STORAGE_SIZE | | Type inquiry intrinsic functions | BIT_SIZE, DIGITS, EPSILON, HUGE, KIND, MAXEXPONENT, MINEXPONENT, NEW_LINE, PRECISION, RADIX, RANGE, TINY| | Non-standard intrinsic functions | AND, OR, XOR, SHIFT, ZEXT, IZEXT, COSD, SIND, TAND, ACOSD, ASIND, ATAND, ATAN2D, COMPL, EQV, NEQV, INT8, JINT, JNINT, KNINT, QCMPLX, DREAL, DFLOAT, QEXT, QFLOAT, QREAL, DNUM, NUM, JNUM, KNUM, QNUM, RNUM, RAN, RANF, ILEN, SIZEOF, MCLOCK, SECNDS, COTAN, IBCHNG, ISHA, ISHC, ISHL, IXOR, IARG, IARGC, NARGS, GETPID, NUMARG, BADDRESS, IADDR, CACHESIZE, EOF, FP_CLASS, INT_PTR_KIND, ISNAN, MALLOC | -| Intrinsic subroutines |MVBITS (elemental), CPU_TIME, DATE_AND_TIME, EVENT_QUERY, EXECUTE_COMMAND_LINE, GET_COMMAND, GET_COMMAND_ARGUMENT, GET_ENVIRONMENT_VARIABLE, MOVE_ALLOC, RANDOM_INIT, RANDOM_NUMBER, RANDOM_SEED, SYSTEM_CLOCK | +| Intrinsic subroutines |MVBITS (elemental), CPU_TIME, DATE_AND_TIME, EVENT_QUERY, EXECUTE_COMMAND_LINE, GET_COMMAND, GET_COMMAND_ARGUMENT, GET_ENVIRONMENT_VARIABLE, GETLOG, MOVE_ALLOC, RANDOM_INIT, RANDOM_NUMBER, RANDOM_SEED, SYSTEM_CLOCK | klausler wrote: You are not really implementing `GETLOG` here as an intrinsic subroutine, but as a library subroutine. (There is no interface exposed to user programs in the intrinsic procedure tables.) https://github.com/llvm/llvm-project/pull/70917 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [flang] [llvm] [flang ]GETLOG runtime and extension implementation: get login username (PR #70917)
@@ -39,6 +39,17 @@ // overload will have a dummy parameter whose type indicates whether or not it // should be preferred. Any other parameters required for SFINAE should have // default values provided. + +// outside anonymous namespace, function reused klausler wrote: There's a `CopyAndPad()` template function in flang/runtime/character.cpp that could be moved to a header file and used here. https://github.com/llvm/llvm-project/pull/70917 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang] [flang] [llvm] [flang ]GETLOG runtime and extension implementation: get login username (PR #70917)
@@ -37,5 +80,17 @@ void FORTRAN_PROCEDURE_NAME(getarg)( (void)RTNAME(GetCommandArgument)( n, &value, nullptr, nullptr, __FILE__, __LINE__); } + +void FORTRAN_PROCEDURE_NAME(getlog)(std::int8_t *arg, std::int64_t length) { + std::array str; klausler wrote: Why not just `char str[LOGIN_NAME_MAX+1];`? https://github.com/llvm/llvm-project/pull/70917 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [flang] [clang-tools-extra] [flang] Add EXECUTE_COMMAND_LINE runtime and lowering intrinsics implementation (PR #74077)
@@ -411,6 +412,48 @@ RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from, bool toIsContiguous, bool fromIsContiguous); RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from); +RT_API_ATTRS const char *EnsureNullTerminated( +const char *str, size_t length, Terminator &terminator); + +RT_API_ATTRS std::size_t LengthWithoutTrailingSpaces(const Descriptor &d); + +// Returns the length of the \p string. Assumes \p string is valid. +RT_API_ATTRS std::int64_t StringLength(const char *string); + +// Assumes Descriptor \p value is not nullptr. +RT_API_ATTRS bool IsValidCharDescriptor(const Descriptor *value); + +// Assumes Descriptor \p intVal is not nullptr. +RT_API_ATTRS bool IsValidIntDescriptor(const Descriptor *intVal); + +// Assume Descriptor \p value is valid: pass IsValidCharDescriptor check. +RT_API_ATTRS void FillWithSpaces( +const Descriptor &value, std::size_t offset = 0); + +RT_API_ATTRS std::int32_t CopyToDescriptor(const Descriptor &value, +const char *rawValue, std::int64_t rawValueLength, const Descriptor *errmsg, +std::size_t offset = 0); + +void CopyCharToDescriptor( +const Descriptor &value, const char *rawValue, std::size_t offset = 0); + +RT_API_ATTRS std::int32_t CheckAndCopyToDescriptor(const Descriptor *value, +const char *rawValue, const Descriptor *errmsg, std::size_t &offset); + +RT_API_ATTRS void CheckAndCopyCharToDescriptor( +const Descriptor *value, const char *rawValue, std::size_t offset = 0); + +RT_API_ATTRS void StoreIntToDescriptor( +const Descriptor *length, std::int64_t value, Terminator &terminator); + +RT_API_ATTRS void CheckAndStoreIntToDescriptor( +const Descriptor *intVal, std::int64_t value, Terminator &terminator); + +template struct FitsInIntegerKind; klausler wrote: What does this do? https://github.com/llvm/llvm-project/pull/74077 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [clang-tools-extra] [llvm] [flang] Add EXECUTE_COMMAND_LINE runtime and lowering intrinsics implementation (PR #74077)
@@ -411,6 +412,48 @@ RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from, bool toIsContiguous, bool fromIsContiguous); RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from); +RT_API_ATTRS const char *EnsureNullTerminated( +const char *str, size_t length, Terminator &terminator); + +RT_API_ATTRS std::size_t LengthWithoutTrailingSpaces(const Descriptor &d); + +// Returns the length of the \p string. Assumes \p string is valid. klausler wrote: The comment doesn't specify how the length of the string is defined. If it is NUL terminated, how is this different from `std::strlen()`? https://github.com/llvm/llvm-project/pull/74077 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [flang] [clang] [clang-tools-extra] [flang] Add EXECUTE_COMMAND_LINE runtime and lowering intrinsics implementation (PR #74077)
@@ -411,6 +412,48 @@ RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from, bool toIsContiguous, bool fromIsContiguous); RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from); +RT_API_ATTRS const char *EnsureNullTerminated( +const char *str, size_t length, Terminator &terminator); + +RT_API_ATTRS std::size_t LengthWithoutTrailingSpaces(const Descriptor &d); + +// Returns the length of the \p string. Assumes \p string is valid. +RT_API_ATTRS std::int64_t StringLength(const char *string); + +// Assumes Descriptor \p value is not nullptr. +RT_API_ATTRS bool IsValidCharDescriptor(const Descriptor *value); + +// Assumes Descriptor \p intVal is not nullptr. +RT_API_ATTRS bool IsValidIntDescriptor(const Descriptor *intVal); + +// Assume Descriptor \p value is valid: pass IsValidCharDescriptor check. +RT_API_ATTRS void FillWithSpaces( +const Descriptor &value, std::size_t offset = 0); + +RT_API_ATTRS std::int32_t CopyToDescriptor(const Descriptor &value, +const char *rawValue, std::int64_t rawValueLength, const Descriptor *errmsg, +std::size_t offset = 0); + +void CopyCharToDescriptor( klausler wrote: Does this routine copy a single character, or some kind of NUL terminated string, or something else? https://github.com/llvm/llvm-project/pull/74077 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[flang] [clang-tools-extra] [llvm] [clang] [flang] Add EXECUTE_COMMAND_LINE runtime and lowering intrinsics implementation (PR #74077)
@@ -173,5 +173,141 @@ RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from) { ShallowCopy(to, from, to.IsContiguous(), from.IsContiguous()); } +RT_API_ATTRS const char *EnsureNullTerminated( +const char *str, size_t length, Terminator &terminator) { + if (length <= std::strlen(str)) { +char *newCmd{(char *)AllocateMemoryOrCrash(terminator, length + 1)}; +std::memcpy(newCmd, str, length); +newCmd[length] = '\0'; +return newCmd; + } else { +return str; + } +} + +RT_API_ATTRS std::size_t LengthWithoutTrailingSpaces(const Descriptor &d) { + std::size_t s{d.ElementBytes() - 1}; + while (*d.OffsetElement(s) == ' ') { +--s; + } + return s + 1; +} + +// Returns the length of the \p string. Assumes \p string is valid. +RT_API_ATTRS std::int64_t StringLength(const char *string) { + return static_cast(std::strlen(string)); +} + +// Assumes Descriptor \p value is not nullptr. +RT_API_ATTRS bool IsValidCharDescriptor(const Descriptor *value) { + return value && value->IsAllocated() && + value->type() == TypeCode(TypeCategory::Character, 1) && + value->rank() == 0; +} + +// Assumes Descriptor \p intVal is not nullptr. +RT_API_ATTRS bool IsValidIntDescriptor(const Descriptor *intVal) { klausler wrote: This function could easily accommodate a null `value`. https://github.com/llvm/llvm-project/pull/74077 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[flang] [clang] [clang-tools-extra] [llvm] [flang] Add EXECUTE_COMMAND_LINE runtime and lowering intrinsics implementation (PR #74077)
@@ -173,5 +173,141 @@ RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from) { ShallowCopy(to, from, to.IsContiguous(), from.IsContiguous()); } +RT_API_ATTRS const char *EnsureNullTerminated( +const char *str, size_t length, Terminator &terminator) { + if (length <= std::strlen(str)) { +char *newCmd{(char *)AllocateMemoryOrCrash(terminator, length + 1)}; +std::memcpy(newCmd, str, length); +newCmd[length] = '\0'; +return newCmd; + } else { +return str; + } +} + +RT_API_ATTRS std::size_t LengthWithoutTrailingSpaces(const Descriptor &d) { + std::size_t s{d.ElementBytes() - 1}; + while (*d.OffsetElement(s) == ' ') { +--s; + } + return s + 1; +} + +// Returns the length of the \p string. Assumes \p string is valid. +RT_API_ATTRS std::int64_t StringLength(const char *string) { + return static_cast(std::strlen(string)); +} + +// Assumes Descriptor \p value is not nullptr. klausler wrote: The comment is incorrect; the code works fine if `value` is null. https://github.com/llvm/llvm-project/pull/74077 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[flang] [clang-tools-extra] [clang] [llvm] [flang] Add EXECUTE_COMMAND_LINE runtime and lowering intrinsics implementation (PR #74077)
@@ -411,6 +412,48 @@ RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from, bool toIsContiguous, bool fromIsContiguous); RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from); +RT_API_ATTRS const char *EnsureNullTerminated( +const char *str, size_t length, Terminator &terminator); + +RT_API_ATTRS std::size_t LengthWithoutTrailingSpaces(const Descriptor &d); + +// Returns the length of the \p string. Assumes \p string is valid. +RT_API_ATTRS std::int64_t StringLength(const char *string); + +// Assumes Descriptor \p value is not nullptr. +RT_API_ATTRS bool IsValidCharDescriptor(const Descriptor *value); + +// Assumes Descriptor \p intVal is not nullptr. +RT_API_ATTRS bool IsValidIntDescriptor(const Descriptor *intVal); + +// Assume Descriptor \p value is valid: pass IsValidCharDescriptor check. +RT_API_ATTRS void FillWithSpaces( +const Descriptor &value, std::size_t offset = 0); + +RT_API_ATTRS std::int32_t CopyToDescriptor(const Descriptor &value, +const char *rawValue, std::int64_t rawValueLength, const Descriptor *errmsg, +std::size_t offset = 0); + +void CopyCharToDescriptor( +const Descriptor &value, const char *rawValue, std::size_t offset = 0); + +RT_API_ATTRS std::int32_t CheckAndCopyToDescriptor(const Descriptor *value, +const char *rawValue, const Descriptor *errmsg, std::size_t &offset); + +RT_API_ATTRS void CheckAndCopyCharToDescriptor( +const Descriptor *value, const char *rawValue, std::size_t offset = 0); + +RT_API_ATTRS void StoreIntToDescriptor( +const Descriptor *length, std::int64_t value, Terminator &terminator); + +RT_API_ATTRS void CheckAndStoreIntToDescriptor( +const Descriptor *intVal, std::int64_t value, Terminator &terminator); + +template struct FitsInIntegerKind; + +RT_API_ATTRS bool FitsInDescriptor( klausler wrote: This routine looks like a Boolean predicate but why does it require a `Terminator`? Can it crash? https://github.com/llvm/llvm-project/pull/74077 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang-tools-extra] [flang] [clang] [flang] Add EXECUTE_COMMAND_LINE runtime and lowering intrinsics implementation (PR #74077)
@@ -173,5 +173,145 @@ RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from) { ShallowCopy(to, from, to.IsContiguous(), from.IsContiguous()); } +RT_API_ATTRS const char *EnsureNullTerminated( +const char *str, size_t length, Terminator &terminator) { + if (length <= std::strlen(str)) { +char *newCmd{(char *)AllocateMemoryOrCrash(terminator, length + 1)}; +std::memcpy(newCmd, str, length); +newCmd[length] = '\0'; +return newCmd; + } else { +return str; + } +} + +RT_API_ATTRS std::size_t LengthWithoutTrailingSpaces(const Descriptor &d) { + std::size_t s{d.ElementBytes() - 1}; + while (*d.OffsetElement(s) == ' ') { +--s; + } + return s + 1; +} + +// Returns the length of the \p string. Assumes \p string is valid. +RT_API_ATTRS std::int64_t StringLength(const char *string) { + std::size_t length{std::strlen(string)}; + if constexpr (sizeof(std::size_t) < sizeof(std::int64_t)) { +return static_cast(length); + } else { +std::size_t max{std::numeric_limits::max()}; +return length > max ? 0 // Just fail. +: static_cast(length); + } +} + +RT_API_ATTRS bool IsValidCharDescriptor(const Descriptor *value) { + return value && value->IsAllocated() && + value->type() == TypeCode(TypeCategory::Character, 1) && + value->rank() == 0; +} + +RT_API_ATTRS bool IsValidIntDescriptor(const Descriptor *length) { + auto typeCode{length->type().GetCategoryAndKind()}; + // Check that our descriptor is allocated and is a scalar integer with + // kind != 1 (i.e. with a large enough decimal exponent range). + return length->IsAllocated() && length->rank() == 0 && + length->type().IsInteger() && typeCode && typeCode->second != 1; +} + +RT_API_ATTRS void FillWithSpaces(const Descriptor &value, std::size_t offset) { + if (offset < value.ElementBytes()) { klausler wrote: If it's not a safe general-purpose utility routine, then don't put it into `tools.cpp`. Or leave it here and add some checking. https://github.com/llvm/llvm-project/pull/74077 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang] [llvm] [flang] [flang] Add EXECUTE_COMMAND_LINE runtime and lowering intrinsics implementation (PR #74077)
@@ -173,5 +173,141 @@ RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from) { ShallowCopy(to, from, to.IsContiguous(), from.IsContiguous()); } +RT_API_ATTRS const char *EnsureNullTerminated( +const char *str, size_t length, Terminator &terminator) { + if (length <= std::strlen(str)) { +char *newCmd{(char *)AllocateMemoryOrCrash(terminator, length + 1)}; +std::memcpy(newCmd, str, length); +newCmd[length] = '\0'; +return newCmd; + } else { +return str; + } +} + +RT_API_ATTRS std::size_t LengthWithoutTrailingSpaces(const Descriptor &d) { + std::size_t s{d.ElementBytes() - 1}; + while (*d.OffsetElement(s) == ' ') { +--s; + } + return s + 1; +} + +// Returns the length of the \p string. Assumes \p string is valid. +RT_API_ATTRS std::int64_t StringLength(const char *string) { + return static_cast(std::strlen(string)); +} + +// Assumes Descriptor \p value is not nullptr. +RT_API_ATTRS bool IsValidCharDescriptor(const Descriptor *value) { + return value && value->IsAllocated() && + value->type() == TypeCode(TypeCategory::Character, 1) && + value->rank() == 0; +} + +// Assumes Descriptor \p intVal is not nullptr. +RT_API_ATTRS bool IsValidIntDescriptor(const Descriptor *intVal) { + auto typeCode{intVal->type().GetCategoryAndKind()}; + // Check that our descriptor is allocated and is a scalar integer with + // kind != 1 (i.e. with a large enough decimal exponent range). + return intVal->IsAllocated() && intVal->rank() == 0 && + intVal->type().IsInteger() && typeCode && typeCode->second != 1; +} + +// Assume Descriptor \p value is valid: pass IsValidCharDescriptor check. +RT_API_ATTRS void FillWithSpaces(const Descriptor &value, std::size_t offset) { klausler wrote: What if `offset` is larger than `ElementBytes()`? https://github.com/llvm/llvm-project/pull/74077 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [flang] [clang] [llvm] [flang] Add EXECUTE_COMMAND_LINE runtime and lowering intrinsics implementation (PR #74077)
@@ -173,5 +173,70 @@ RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from) { ShallowCopy(to, from, to.IsContiguous(), from.IsContiguous()); } +RT_API_ATTRS const char *EnsureNullTerminated( +const char *str, size_t length, Terminator &terminator) { + if (length <= std::strlen(str)) { klausler wrote: Do not call `std::strlen()` on a string that is not known to be NUL terminated. Use `std::memchr` instead. https://github.com/llvm/llvm-project/pull/74077 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [flang] [clang-tools-extra] [clang] [flang] Add EXECUTE_COMMAND_LINE runtime and lowering intrinsics implementation (PR #74077)
@@ -0,0 +1,203 @@ +//===-- runtime/execute.cpp ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "flang/Runtime/execute.h" +#include "environment.h" +#include "stat.h" +#include "terminator.h" +#include "tools.h" +#include "flang/Runtime/descriptor.h" +#include +#include +#include +#ifdef _WIN32 +#define LEAN_AND_MEAN +#define NOMINMAX +#include +#include +#else +#include +#include +#endif + +namespace Fortran::runtime { + +// cmdstat specified in 16.9.73 +// −1 if the processor does not support command line execution, +// a processor-dependent positive value if an error condition occurs +// −2 if no error condition occurs but WAIT is present with the value false +// and the processor does not support asynchronous execution. Otherwise it is +// assigned the value 0 +enum CMD_STAT { + ASYNC_NO_SUPPORT_ERR = -2, + NO_SUPPORT_ERR = -1, + CMD_EXECUTED = 0, + FORK_ERR = 1, + EXECL_ERR = 2, + INVALID_CL_ERR = 3, + SIGNAL_ERR = 4 +}; + +// Override CopyCharsToDescriptor in tools.h, pass string directly +void CopyCharsToDescriptor(const Descriptor &value, const char *rawValue) { + CopyCharsToDescriptor(value, rawValue, std::strlen(rawValue)); +} + +void CheckAndCopyCharsToDescriptor( +const Descriptor *value, const char *rawValue) { + if (value) { +CopyCharsToDescriptor(*value, rawValue); + } +} + +void CheckAndStoreIntToDescriptor( +const Descriptor *intVal, std::int64_t value, Terminator &terminator) { + if (intVal) { +StoreIntToDescriptor(intVal, value, terminator); + } +} + +// If a condition occurs that would assign a nonzero value to CMDSTAT but +// the CMDSTAT variable is not present, error termination is initiated. +int TerminationCheck(int status, const Descriptor *cmdstat, +const Descriptor *cmdmsg, Terminator &terminator) { + if (status == -1) { +if (!cmdstat) { + terminator.Crash("Execution error with system status code: %d", status); +} else { + CheckAndStoreIntToDescriptor(cmdstat, EXECL_ERR, terminator); + CopyCharsToDescriptor(*cmdmsg, "Execution error"); +} + } +#ifdef _WIN32 + // On WIN32 API std::system returns exit status directly + int exitStatusVal{status}; + if (exitStatusVal == 1) { +#else + int exitStatusVal{WEXITSTATUS(status)}; + if (exitStatusVal == 127 || exitStatusVal == 126) { +#endif +if (!cmdstat) { + terminator.Crash( + "Invalid command quit with exit status code: %d", exitStatusVal); +} else { + CheckAndStoreIntToDescriptor(cmdstat, INVALID_CL_ERR, terminator); + CopyCharsToDescriptor(*cmdmsg, "Invalid command line"); +} + } +#if defined(WIFSIGNALED) && defined(WTERMSIG) + if (WIFSIGNALED(status)) { +if (!cmdstat) { + terminator.Crash("killed by signal: %d", WTERMSIG(status)); +} else { + CheckAndStoreIntToDescriptor(cmdstat, SIGNAL_ERR, terminator); + CopyCharsToDescriptor(*cmdmsg, "killed by signal"); +} + } +#endif +#if defined(WIFSTOPPED) && defined(WSTOPSIG) + if (WIFSTOPPED(status)) { +if (!cmdstat) { + terminator.Crash("stopped by signal: %d", WSTOPSIG(status)); +} else { + CheckAndStoreIntToDescriptor(cmdstat, SIGNAL_ERR, terminator); + CopyCharsToDescriptor(*cmdmsg, "stopped by signal"); +} + } +#endif + return exitStatusVal; +} + +void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait, +const Descriptor *exitstat, const Descriptor *cmdstat, +const Descriptor *cmdmsg, const char *sourceFile, int line) { + Terminator terminator{sourceFile, line}; + const char *newCmd{EnsureNullTerminated( + command.OffsetElement(), command.ElementBytes(), terminator)}; + + if (exitstat) { +RUNTIME_CHECK(terminator, IsValidIntDescriptor(exitstat)); + } + + if (cmdstat) { +RUNTIME_CHECK(terminator, IsValidIntDescriptor(cmdstat)); +// Assigned 0 as specifed in standard, if error then overwrite +StoreIntToDescriptor(cmdstat, CMD_EXECUTED, terminator); + } + + if (cmdmsg) { +RUNTIME_CHECK(terminator, IsValidCharDescriptor(cmdmsg)); + } + + if (wait) { +// either wait is not specified or wait is true: synchronous mode +int status{std::system(newCmd)}; +int exitStatusVal{TerminationCheck(status, cmdstat, cmdmsg, terminator)}; +// If sync, assigned processor-dependent exit status. Otherwise unchanged +CheckAndStoreIntToDescriptor(exitstat, exitStatusVal, terminator); + } else { +// Asynchronous mode +#ifdef _WIN32 +STARTUPINFO si; +PROCESS_INFORMATION pi; +ZeroMemory(&si, sizeof(si)); +si.cb = sizeof(si); +ZeroMemory(&pi, sizeof(pi)); + +// append "cmd.exe /c " to the beginning of command +const char *pre
[llvm] [clang-tools-extra] [flang] [clang] [flang] Add EXECUTE_COMMAND_LINE runtime and lowering intrinsics implementation (PR #74077)
@@ -411,6 +412,24 @@ RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from, bool toIsContiguous, bool fromIsContiguous); RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from); +RT_API_ATTRS const char *EnsureNullTerminated( +const char *str, size_t length, Terminator &terminator); + +RT_API_ATTRS bool IsValidCharDescriptor(const Descriptor *value); + +RT_API_ATTRS bool IsValidIntDescriptor(const Descriptor *intVal); + +// Copy a null-terminated character array \p rawValue to descriptor \p value. +// The copy starts at the given \p offset, if not present then start at 0. +// If descriptor `errmsg` is provided, error messages will be stored to it. +// Returns stats specified in standard. +RT_API_ATTRS std::int32_t CopyCharsToDescriptor(const Descriptor &value, +const char *rawValue, std::int64_t rawValueLength, klausler wrote: `rawValueLength` should probably be `std::size_t`. https://github.com/llvm/llvm-project/pull/74077 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [flang] [clang-tools-extra] [flang] Add EXECUTE_COMMAND_LINE runtime and lowering intrinsics implementation (PR #74077)
@@ -0,0 +1,203 @@ +//===-- runtime/execute.cpp ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "flang/Runtime/execute.h" +#include "environment.h" +#include "stat.h" +#include "terminator.h" +#include "tools.h" +#include "flang/Runtime/descriptor.h" +#include +#include +#include +#ifdef _WIN32 +#define LEAN_AND_MEAN +#define NOMINMAX +#include +#include +#else +#include +#include +#endif + +namespace Fortran::runtime { + +// cmdstat specified in 16.9.73 +// −1 if the processor does not support command line execution, +// a processor-dependent positive value if an error condition occurs +// −2 if no error condition occurs but WAIT is present with the value false +// and the processor does not support asynchronous execution. Otherwise it is +// assigned the value 0 +enum CMD_STAT { + ASYNC_NO_SUPPORT_ERR = -2, + NO_SUPPORT_ERR = -1, + CMD_EXECUTED = 0, + FORK_ERR = 1, + EXECL_ERR = 2, + INVALID_CL_ERR = 3, + SIGNAL_ERR = 4 +}; + +// Override CopyCharsToDescriptor in tools.h, pass string directly +void CopyCharsToDescriptor(const Descriptor &value, const char *rawValue) { + CopyCharsToDescriptor(value, rawValue, std::strlen(rawValue)); +} + +void CheckAndCopyCharsToDescriptor( +const Descriptor *value, const char *rawValue) { + if (value) { +CopyCharsToDescriptor(*value, rawValue); + } +} + +void CheckAndStoreIntToDescriptor( +const Descriptor *intVal, std::int64_t value, Terminator &terminator) { + if (intVal) { +StoreIntToDescriptor(intVal, value, terminator); + } +} + +// If a condition occurs that would assign a nonzero value to CMDSTAT but +// the CMDSTAT variable is not present, error termination is initiated. +int TerminationCheck(int status, const Descriptor *cmdstat, +const Descriptor *cmdmsg, Terminator &terminator) { + if (status == -1) { +if (!cmdstat) { + terminator.Crash("Execution error with system status code: %d", status); +} else { + CheckAndStoreIntToDescriptor(cmdstat, EXECL_ERR, terminator); + CopyCharsToDescriptor(*cmdmsg, "Execution error"); +} + } +#ifdef _WIN32 + // On WIN32 API std::system returns exit status directly + int exitStatusVal{status}; + if (exitStatusVal == 1) { +#else + int exitStatusVal{WEXITSTATUS(status)}; + if (exitStatusVal == 127 || exitStatusVal == 126) { +#endif +if (!cmdstat) { + terminator.Crash( + "Invalid command quit with exit status code: %d", exitStatusVal); +} else { + CheckAndStoreIntToDescriptor(cmdstat, INVALID_CL_ERR, terminator); + CopyCharsToDescriptor(*cmdmsg, "Invalid command line"); +} + } +#if defined(WIFSIGNALED) && defined(WTERMSIG) + if (WIFSIGNALED(status)) { +if (!cmdstat) { + terminator.Crash("killed by signal: %d", WTERMSIG(status)); +} else { + CheckAndStoreIntToDescriptor(cmdstat, SIGNAL_ERR, terminator); + CopyCharsToDescriptor(*cmdmsg, "killed by signal"); +} + } +#endif +#if defined(WIFSTOPPED) && defined(WSTOPSIG) + if (WIFSTOPPED(status)) { +if (!cmdstat) { + terminator.Crash("stopped by signal: %d", WSTOPSIG(status)); +} else { + CheckAndStoreIntToDescriptor(cmdstat, SIGNAL_ERR, terminator); + CopyCharsToDescriptor(*cmdmsg, "stopped by signal"); +} + } +#endif + return exitStatusVal; +} + +void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait, +const Descriptor *exitstat, const Descriptor *cmdstat, +const Descriptor *cmdmsg, const char *sourceFile, int line) { + Terminator terminator{sourceFile, line}; + const char *newCmd{EnsureNullTerminated( + command.OffsetElement(), command.ElementBytes(), terminator)}; + + if (exitstat) { +RUNTIME_CHECK(terminator, IsValidIntDescriptor(exitstat)); + } + + if (cmdstat) { +RUNTIME_CHECK(terminator, IsValidIntDescriptor(cmdstat)); +// Assigned 0 as specifed in standard, if error then overwrite +StoreIntToDescriptor(cmdstat, CMD_EXECUTED, terminator); + } + + if (cmdmsg) { +RUNTIME_CHECK(terminator, IsValidCharDescriptor(cmdmsg)); + } + + if (wait) { +// either wait is not specified or wait is true: synchronous mode +int status{std::system(newCmd)}; +int exitStatusVal{TerminationCheck(status, cmdstat, cmdmsg, terminator)}; +// If sync, assigned processor-dependent exit status. Otherwise unchanged +CheckAndStoreIntToDescriptor(exitstat, exitStatusVal, terminator); + } else { +// Asynchronous mode +#ifdef _WIN32 +STARTUPINFO si; +PROCESS_INFORMATION pi; +ZeroMemory(&si, sizeof(si)); +si.cb = sizeof(si); +ZeroMemory(&pi, sizeof(pi)); + +// append "cmd.exe /c " to the beginning of command +const char *pre
[llvm] [clang] [flang] [clang-tools-extra] [flang] Add EXECUTE_COMMAND_LINE runtime and lowering intrinsics implementation (PR #74077)
@@ -0,0 +1,31 @@ +//===-- include/flang/Runtime/command.h -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#ifndef FORTRAN_RUNTIME_EXECUTE_H_ +#define FORTRAN_RUNTIME_EXECUTE_H_ + +#include "flang/Runtime/entry-names.h" + +#include klausler wrote: Is this `#include` necessary to define anything in this header? https://github.com/llvm/llvm-project/pull/74077 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [flang] [llvm] [clang] [flang] Add EXECUTE_COMMAND_LINE runtime and lowering intrinsics implementation (PR #74077)
@@ -173,5 +173,70 @@ RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from) { ShallowCopy(to, from, to.IsContiguous(), from.IsContiguous()); } +RT_API_ATTRS const char *EnsureNullTerminated( +const char *str, size_t length, Terminator &terminator) { klausler wrote: `std::size_t` https://github.com/llvm/llvm-project/pull/74077 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[flang] [clang] [libcxx] [lldb] [clang-tools-extra] [llvm] [compiler-rt] [libc] [flang] FDATE extension implementation: get date and time in ctime format (PR #71222)
@@ -22,6 +22,9 @@ extern "C" { // CALL FLUSH(n) antedates the Fortran 2003 FLUSH statement. void FORTRAN_PROCEDURE_NAME(flush)(const int &unit); +// GNU extension subroutine FDATE +void FORTRAN_PROCEDURE_NAME(fdate)(std::byte *string, std::int64_t length); klausler wrote: Why `std::byte` here instead of the usual `char`? https://github.com/llvm/llvm-project/pull/71222 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [flang] [llvm] [libc] [compiler-rt] [lldb] [clang] [libcxx] [flang] FDATE extension implementation: get date and time in ctime format (PR #71222)
@@ -43,6 +66,26 @@ void FORTRAN_PROCEDURE_NAME(flush)(const int &unit) { } } // namespace io +// CALL FDATE(DATE) +void FORTRAN_PROCEDURE_NAME(fdate)(std::byte *arg, std::int64_t length) { + // Day Mon dd hh:mm:ss \n\0 is 26 characters, e.g. + // Tue May 26 21:51:03 2015\n\0 + char str[26]; + // Insufficient space, fill with spaces and return. + if (length < 24) { +std::memset(reinterpret_cast(arg), ' ', length); +return; + } + + Terminator terminator{__FILE__, __LINE__}; + std::time_t current_time; + std::time(¤t_time); + CtimeBuffer(str, sizeof(str), current_time, terminator); + + // Pad space on \n\0 as well, start at index 24 (included). klausler wrote: What does "Pad space on \n\0 as well" mean? https://github.com/llvm/llvm-project/pull/71222 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [flang] [llvm] [libc] [compiler-rt] [lldb] [clang] [libcxx] [flang] FDATE extension implementation: get date and time in ctime format (PR #71222)
@@ -43,6 +66,26 @@ void FORTRAN_PROCEDURE_NAME(flush)(const int &unit) { } } // namespace io +// CALL FDATE(DATE) +void FORTRAN_PROCEDURE_NAME(fdate)(std::byte *arg, std::int64_t length) { + // Day Mon dd hh:mm:ss \n\0 is 26 characters, e.g. + // Tue May 26 21:51:03 2015\n\0 + char str[26]; + // Insufficient space, fill with spaces and return. + if (length < 24) { +std::memset(reinterpret_cast(arg), ' ', length); +return; + } + + Terminator terminator{__FILE__, __LINE__}; + std::time_t current_time; + std::time(¤t_time); + CtimeBuffer(str, sizeof(str), current_time, terminator); + + // Pad space on \n\0 as well, start at index 24 (included). klausler wrote: Do you mean that the last two bytes will be replaced with spaces? https://github.com/llvm/llvm-project/pull/71222 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxx] [clang-tools-extra] [flang] [lldb] [clang] [libc] [compiler-rt] [llvm] [flang] FDATE extension implementation: get date and time in ctime format (PR #71222)
@@ -22,6 +22,9 @@ extern "C" { // CALL FLUSH(n) antedates the Fortran 2003 FLUSH statement. void FORTRAN_PROCEDURE_NAME(flush)(const int &unit); +// GNU extension subroutine FDATE +void FORTRAN_PROCEDURE_NAME(fdate)(std::byte *string, std::int64_t length); klausler wrote: Like what? https://github.com/llvm/llvm-project/pull/71222 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[flang] [clang-tools-extra] [llvm] [clang] [flang] Add EXECUTE_COMMAND_LINE runtime and lowering intrinsics implementation (PR #74077)
@@ -0,0 +1,206 @@ +//===-- runtime/execute.cpp ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "flang/Runtime/execute.h" +#include "environment.h" +#include "stat.h" +#include "terminator.h" +#include "tools.h" +#include "flang/Runtime/descriptor.h" +#include +#include +#include +#ifdef _WIN32 +#define LEAN_AND_MEAN +#define NOMINMAX +#include +#else +#include +#include +#endif + +namespace Fortran::runtime { + +// cmdstat specified in 16.9.73 +// −1 if the processor does not support command line execution, +// a processor-dependent positive value if an error condition occurs +// −2 if no error condition occurs but WAIT is present with the value false +// and the processor does not support asynchronous execution. Otherwise it is +// assigned the value 0 +enum CMD_STAT { + ASYNC_NO_SUPPORT_ERR = -2, + NO_SUPPORT_ERR = -1, + CMD_EXECUTED = 0, + FORK_ERR = 1, + EXECL_ERR = 2, + INVALID_CL_ERR = 3, + SIGNAL_ERR = 4 +}; + +// Override CopyCharsToDescriptor in tools.h, pass string directly +void CopyCharsToDescriptor(const Descriptor &value, const char *rawValue) { + CopyCharsToDescriptor(value, rawValue, std::strlen(rawValue)); +} + +void CheckAndCopyCharsToDescriptor( +const Descriptor *value, const char *rawValue) { + if (value) { +CopyCharsToDescriptor(*value, rawValue); + } +} + +void CheckAndStoreIntToDescriptor( +const Descriptor *intVal, std::int64_t value, Terminator &terminator) { + if (intVal) { +StoreIntToDescriptor(intVal, value, terminator); + } +} + +// If a condition occurs that would assign a nonzero value to CMDSTAT but +// the CMDSTAT variable is not present, error termination is initiated. +int TerminationCheck(int status, const Descriptor *cmdstat, +const Descriptor *cmdmsg, Terminator &terminator) { + if (status == -1) { +if (!cmdstat) { + terminator.Crash("Execution error with system status code: %d", status); +} else { + CheckAndStoreIntToDescriptor(cmdstat, EXECL_ERR, terminator); + CopyCharsToDescriptor(*cmdmsg, "Execution error"); +} + } +#ifdef _WIN32 + // On WIN32 API std::system returns exit status directly + int exitStatusVal{status}; + if (exitStatusVal == 1) { +#else + int exitStatusVal{WEXITSTATUS(status)}; + if (exitStatusVal == 127 || exitStatusVal == 126) { +#endif +if (!cmdstat) { + terminator.Crash( + "Invalid command quit with exit status code: %d", exitStatusVal); +} else { + CheckAndStoreIntToDescriptor(cmdstat, INVALID_CL_ERR, terminator); + CopyCharsToDescriptor(*cmdmsg, "Invalid command line"); +} + } +#if defined(WIFSIGNALED) && defined(WTERMSIG) + if (WIFSIGNALED(status)) { +if (!cmdstat) { + terminator.Crash("killed by signal: %d", WTERMSIG(status)); +} else { + CheckAndStoreIntToDescriptor(cmdstat, SIGNAL_ERR, terminator); + CopyCharsToDescriptor(*cmdmsg, "killed by signal"); +} + } +#endif +#if defined(WIFSTOPPED) && defined(WSTOPSIG) + if (WIFSTOPPED(status)) { +if (!cmdstat) { + terminator.Crash("stopped by signal: %d", WSTOPSIG(status)); +} else { + CheckAndStoreIntToDescriptor(cmdstat, SIGNAL_ERR, terminator); + CopyCharsToDescriptor(*cmdmsg, "stopped by signal"); +} + } +#endif + return exitStatusVal; +} + +void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait, +const Descriptor *exitstat, const Descriptor *cmdstat, +const Descriptor *cmdmsg, const char *sourceFile, int line) { + Terminator terminator{sourceFile, line}; + const char *newCmd{EnsureNullTerminated( + command.OffsetElement(), command.ElementBytes(), terminator)}; + + if (exitstat) { +RUNTIME_CHECK(terminator, IsValidIntDescriptor(exitstat)); + } + + if (cmdstat) { +RUNTIME_CHECK(terminator, IsValidIntDescriptor(cmdstat)); +// Assigned 0 as specifed in standard, if error then overwrite +StoreIntToDescriptor(cmdstat, CMD_EXECUTED, terminator); + } + + if (cmdmsg) { +RUNTIME_CHECK(terminator, IsValidCharDescriptor(cmdmsg)); + } + + if (wait) { +// either wait is not specified or wait is true: synchronous mode +int status{std::system(newCmd)}; +int exitStatusVal{TerminationCheck(status, cmdstat, cmdmsg, terminator)}; +// If sync, assigned processor-dependent exit status. Otherwise unchanged +CheckAndStoreIntToDescriptor(exitstat, exitStatusVal, terminator); + } else { +// Asynchronous mode +#ifdef _WIN32 +STARTUPINFO si; +PROCESS_INFORMATION pi; +ZeroMemory(&si, sizeof(si)); +si.cb = sizeof(si); +ZeroMemory(&pi, sizeof(pi)); + +// append "cmd.exe /c " to the beginning of command klausler wrote
[llvm] [flang] [clang] [clang-tools-extra] [flang] Add EXECUTE_COMMAND_LINE runtime and lowering intrinsics implementation (PR #74077)
@@ -0,0 +1,206 @@ +//===-- runtime/execute.cpp ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "flang/Runtime/execute.h" +#include "environment.h" +#include "stat.h" +#include "terminator.h" +#include "tools.h" +#include "flang/Runtime/descriptor.h" +#include +#include +#include +#ifdef _WIN32 +#define LEAN_AND_MEAN +#define NOMINMAX +#include +#else +#include +#include +#endif + +namespace Fortran::runtime { + +// cmdstat specified in 16.9.73 +// −1 if the processor does not support command line execution, +// a processor-dependent positive value if an error condition occurs +// −2 if no error condition occurs but WAIT is present with the value false +// and the processor does not support asynchronous execution. Otherwise it is +// assigned the value 0 +enum CMD_STAT { + ASYNC_NO_SUPPORT_ERR = -2, + NO_SUPPORT_ERR = -1, + CMD_EXECUTED = 0, + FORK_ERR = 1, + EXECL_ERR = 2, + INVALID_CL_ERR = 3, + SIGNAL_ERR = 4 +}; + +// Override CopyCharsToDescriptor in tools.h, pass string directly +void CopyCharsToDescriptor(const Descriptor &value, const char *rawValue) { + CopyCharsToDescriptor(value, rawValue, std::strlen(rawValue)); +} + +void CheckAndCopyCharsToDescriptor( +const Descriptor *value, const char *rawValue) { + if (value) { +CopyCharsToDescriptor(*value, rawValue); + } +} + +void CheckAndStoreIntToDescriptor( +const Descriptor *intVal, std::int64_t value, Terminator &terminator) { + if (intVal) { +StoreIntToDescriptor(intVal, value, terminator); + } +} + +// If a condition occurs that would assign a nonzero value to CMDSTAT but +// the CMDSTAT variable is not present, error termination is initiated. +int TerminationCheck(int status, const Descriptor *cmdstat, +const Descriptor *cmdmsg, Terminator &terminator) { + if (status == -1) { +if (!cmdstat) { + terminator.Crash("Execution error with system status code: %d", status); +} else { + CheckAndStoreIntToDescriptor(cmdstat, EXECL_ERR, terminator); + CopyCharsToDescriptor(*cmdmsg, "Execution error"); +} + } +#ifdef _WIN32 + // On WIN32 API std::system returns exit status directly + int exitStatusVal{status}; + if (exitStatusVal == 1) { +#else + int exitStatusVal{WEXITSTATUS(status)}; + if (exitStatusVal == 127 || exitStatusVal == 126) { +#endif +if (!cmdstat) { + terminator.Crash( + "Invalid command quit with exit status code: %d", exitStatusVal); +} else { + CheckAndStoreIntToDescriptor(cmdstat, INVALID_CL_ERR, terminator); + CopyCharsToDescriptor(*cmdmsg, "Invalid command line"); +} + } +#if defined(WIFSIGNALED) && defined(WTERMSIG) + if (WIFSIGNALED(status)) { +if (!cmdstat) { + terminator.Crash("killed by signal: %d", WTERMSIG(status)); +} else { + CheckAndStoreIntToDescriptor(cmdstat, SIGNAL_ERR, terminator); + CopyCharsToDescriptor(*cmdmsg, "killed by signal"); +} + } +#endif +#if defined(WIFSTOPPED) && defined(WSTOPSIG) + if (WIFSTOPPED(status)) { +if (!cmdstat) { + terminator.Crash("stopped by signal: %d", WSTOPSIG(status)); +} else { + CheckAndStoreIntToDescriptor(cmdstat, SIGNAL_ERR, terminator); + CopyCharsToDescriptor(*cmdmsg, "stopped by signal"); +} + } +#endif + return exitStatusVal; +} + +void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait, +const Descriptor *exitstat, const Descriptor *cmdstat, +const Descriptor *cmdmsg, const char *sourceFile, int line) { + Terminator terminator{sourceFile, line}; + const char *newCmd{EnsureNullTerminated( + command.OffsetElement(), command.ElementBytes(), terminator)}; + + if (exitstat) { +RUNTIME_CHECK(terminator, IsValidIntDescriptor(exitstat)); + } + + if (cmdstat) { +RUNTIME_CHECK(terminator, IsValidIntDescriptor(cmdstat)); +// Assigned 0 as specifed in standard, if error then overwrite +StoreIntToDescriptor(cmdstat, CMD_EXECUTED, terminator); + } + + if (cmdmsg) { +RUNTIME_CHECK(terminator, IsValidCharDescriptor(cmdmsg)); + } + + if (wait) { +// either wait is not specified or wait is true: synchronous mode +int status{std::system(newCmd)}; +int exitStatusVal{TerminationCheck(status, cmdstat, cmdmsg, terminator)}; +// If sync, assigned processor-dependent exit status. Otherwise unchanged +CheckAndStoreIntToDescriptor(exitstat, exitStatusVal, terminator); + } else { +// Asynchronous mode +#ifdef _WIN32 +STARTUPINFO si; +PROCESS_INFORMATION pi; +ZeroMemory(&si, sizeof(si)); +si.cb = sizeof(si); +ZeroMemory(&pi, sizeof(pi)); + +// append "cmd.exe /c " to the beginning of command +const char *prefix{"cmd.ex
[clang] [llvm] [flang] [clang-tools-extra] [flang] Add EXECUTE_COMMAND_LINE runtime and lowering intrinsics implementation (PR #74077)
https://github.com/klausler approved this pull request. https://github.com/llvm/llvm-project/pull/74077 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[flang] [llvm] [clang] [clang-tools-extra] [flang] Add EXECUTE_COMMAND_LINE runtime and lowering intrinsics implementation (PR #74077)
@@ -173,5 +173,72 @@ RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from) { ShallowCopy(to, from, to.IsContiguous(), from.IsContiguous()); } +RT_API_ATTRS const char *EnsureNullTerminated( +const char *str, std::size_t length, Terminator &terminator) { + const void *nullTerminatorPos{std::memchr(str, '\0', length)}; + + if (nullTerminatorPos == nullptr) { klausler wrote: `if (std::memchr(str, '\0', length) == nullptr) {` https://github.com/llvm/llvm-project/pull/74077 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [clang-tools-extra] [flang] [flang] Add EXECUTE_COMMAND_LINE runtime and lowering intrinsics implementation (PR #74077)
https://github.com/klausler edited https://github.com/llvm/llvm-project/pull/74077 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [libc] [clang] [compiler-rt] [llvm] [flang] Apply kind code check on exitstat and cmdstat (PR #78286)
@@ -122,10 +122,22 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait, if (exitstat) { RUNTIME_CHECK(terminator, IsValidIntDescriptor(exitstat)); +auto exitstatKind{exitstat->type().GetCategoryAndKind()->second}; +if (exitstatKind < 4) { klausler wrote: The runtime code doesn't need to check these descriptors -- that will have been done statically when the intrinsic procedure reference was analyzed! What has to be done in the runtime is using those descriptors to store the integer result values properly, and I think that the code already does that. https://github.com/llvm/llvm-project/pull/78286 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libc] [llvm] [clang] [clang-tools-extra] [flang] [compiler-rt] Apply kind code check on exitstat and cmdstat (PR #78286)
https://github.com/klausler approved this pull request. https://github.com/llvm/llvm-project/pull/78286 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[flang] [clang] [compiler-rt] [llvm] [clang-tools-extra] [libc] Apply kind code check on exitstat and cmdstat (PR #78286)
https://github.com/klausler commented: Is there another patch that adds integer kind handling for these two arguments to the runtime implementation? https://github.com/llvm/llvm-project/pull/78286 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 3338ef9 - [flang] Produce proper "preprocessor output" for -E option
Author: peter klausler Date: 2021-07-30T15:13:56-07:00 New Revision: 3338ef93b02837edf69abc203e15a42fa55aa1b3 URL: https://github.com/llvm/llvm-project/commit/3338ef93b02837edf69abc203e15a42fa55aa1b3 DIFF: https://github.com/llvm/llvm-project/commit/3338ef93b02837edf69abc203e15a42fa55aa1b3.diff LOG: [flang] Produce proper "preprocessor output" for -E option Rename the current -E option to "-E -Xflang -fno-reformat". Add a new Parsing::EmitPreprocessedSource() routine to convert the cooked character stream output of the prescanner back to something more closely resembling output from a traditional preprocessor; call this new routine when -E appears. The new -E output is suitable for use as fixed form Fortran source to compilation by (one hopes) any Fortran compiler. If the original top-level source file had been free form source, the output will be suitable for use as free form source as well; otherwise there may be diagnostics about missing spaces if they were indeed absent in the original fixed form source. Unless the -P option appears, #line directives are interspersed with the output (but be advised, f18 will ignore these if presented with them in a later compilation). An effort has been made to preserve original alphabetic character case and source indentation. Add -P and -fno-reformat to the new drivers. Tweak test options to avoid confusion with prior -E output; use -fno-reformat where needed, but prefer to keep -E, sometimes in concert with -P, on most, updating expected results accordingly. Differential Revision: https://reviews.llvm.org/D106727 Added: flang/test/Preprocessing/dash-E.F90 Modified: clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Flang.cpp flang/include/flang/Frontend/FrontendOptions.h flang/include/flang/Frontend/PreprocessorOptions.h flang/include/flang/Parser/parsing.h flang/lib/Frontend/CompilerInvocation.cpp flang/lib/Frontend/FrontendActions.cpp flang/lib/Frontend/FrontendOptions.cpp flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp flang/lib/Parser/parsing.cpp flang/lib/Parser/provenance.cpp flang/lib/Parser/token-sequence.cpp flang/lib/Parser/token-sequence.h flang/test/Driver/cpp-nocpp-command-line-macro.f90 flang/test/Driver/driver-help-hidden.f90 flang/test/Driver/driver-help.f90 flang/test/Driver/escaped-backslash.f90 flang/test/Driver/fixed-free-detection.f90 flang/test/Driver/fixed-line-length.f90 flang/test/Driver/frontend-forwarding.f90 flang/test/Driver/include-header.f90 flang/test/Driver/input-from-stdin.f90 flang/test/Driver/macro-def-undef.F90 flang/test/Driver/macro-multiline.F90 flang/test/Parser/badlabel.f flang/test/Preprocessing/assert.F90 flang/test/Preprocessing/fixed-rescan.F flang/test/Preprocessing/hollerith.f flang/test/Preprocessing/pp001.F flang/test/Preprocessing/pp002.F flang/test/Preprocessing/pp003.F flang/test/Preprocessing/pp004.F flang/test/Preprocessing/pp005.F flang/test/Preprocessing/pp006.F flang/test/Preprocessing/pp007.F flang/test/Preprocessing/pp008.F flang/test/Preprocessing/pp009.F flang/test/Preprocessing/pp010.F flang/test/Preprocessing/pp011.F flang/test/Preprocessing/pp012.F flang/test/Preprocessing/pp013.F flang/test/Preprocessing/pp014.F flang/test/Preprocessing/pp015.F flang/test/Preprocessing/pp016.F flang/test/Preprocessing/pp017.F flang/test/Preprocessing/pp018.F flang/test/Preprocessing/pp019.F flang/test/Preprocessing/pp020.F flang/test/Preprocessing/pp021.F flang/test/Preprocessing/pp022.F flang/test/Preprocessing/pp023.F flang/test/Preprocessing/pp024.F flang/test/Preprocessing/pp025.F flang/test/Preprocessing/pp026.F flang/test/Preprocessing/pp027.F flang/test/Preprocessing/pp028.F flang/test/Preprocessing/pp029.F flang/test/Preprocessing/pp030.F flang/test/Preprocessing/pp031.F flang/test/Preprocessing/pp032.F flang/test/Preprocessing/pp033.F flang/test/Preprocessing/pp034.F flang/test/Preprocessing/pp035.F flang/test/Preprocessing/pp036.F flang/test/Preprocessing/pp037.F flang/test/Preprocessing/pp038.F flang/test/Preprocessing/pp039.F flang/test/Preprocessing/pp041.F flang/test/Preprocessing/pp043.F flang/test/Preprocessing/pp044.F flang/test/Preprocessing/pp101.F90 flang/test/Preprocessing/pp102.F90 flang/test/Preprocessing/pp104.F90 flang/test/Preprocessing/pp107.F90 flang/test/Preprocessing/pp108.F90 flang/test/Preprocessing/pp111.F90 flang/test/Preprocessing/pp112.F90 flang/test/Preprocessing/pp115.F90 flang/test/Preprocessing/pp116.F90 flang/test/Preprocessing/pp117.F90 flang/test/Preprocessing/pp118.F90 flang/test/Preprocessing/pp121.F90 flang/test/Preprocessing/pp123.F90 flang/test/Preprocessing/pp124.F90 flang/test/Preprocessing/pp1
[clang] 996ef89 - [flang] Add -fno-automatic, refine IsSaved()
Author: Peter Klausler Date: 2021-11-22T10:06:38-08:00 New Revision: 996ef895cd3d1313665a42fc8e20d1d4e1cf2a28 URL: https://github.com/llvm/llvm-project/commit/996ef895cd3d1313665a42fc8e20d1d4e1cf2a28 DIFF: https://github.com/llvm/llvm-project/commit/996ef895cd3d1313665a42fc8e20d1d4e1cf2a28.diff LOG: [flang] Add -fno-automatic, refine IsSaved() This legacy option (available in other Fortran compilers with various spellings) implies the SAVE attribute for local variables on subprograms that are not explicitly RECURSIVE. The SAVE attribute essentially implies static rather than stack storage. This was the default setting in Fortran until surprisingly recently, so explicit SAVE statements & attributes could be and often were omitted from older codes. Note that initialized objects already have an implied SAVE attribute, and objects in COMMON effectively do too, as data overlays are extinct; and since objects that are expected to survive from one invocation of a procedure to the next in static storage should probably be explicit initialized in the first place, so the use cases for this option are somewhat rare, and all of them could be handled with explicit SAVE statements or attributes. This implicit SAVE attribute must not apply to automatic (in the Fortran sense) local objects, whose sizes cannot be known at compilation time. To get the semantics of IsSaved() right, the IsAutomatic() predicate was moved into Evaluate/tools.cpp to allow for dynamic linking of the compiler. The redundant predicate IsAutomatic() was noticed, removed, and its uses replaced. GNU Fortran's spelling of the option (-fno-automatic) was added to the clang-based driver and used for basic sanity testing. Differential Revision: https://reviews.llvm.org/D114209 Added: flang/test/Semantics/save02.f90 Modified: clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Flang.cpp flang/include/flang/Common/Fortran-features.h flang/include/flang/Evaluate/tools.h flang/include/flang/Semantics/tools.h flang/lib/Evaluate/tools.cpp flang/lib/Frontend/CompilerInvocation.cpp flang/lib/Semantics/resolve-names-utils.cpp flang/lib/Semantics/runtime-type-info.cpp flang/lib/Semantics/tools.cpp flang/test/Driver/driver-help-hidden.f90 flang/test/Driver/driver-help.f90 flang/test/Semantics/entry01.f90 flang/test/Semantics/save01.f90 Removed: diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 9bde64cf49fd7..7730b7d1915e4 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4519,7 +4519,7 @@ def frecord_marker_EQ : Joined<["-"], "frecord-marker=">, Group; defm aggressive_function_elimination : BooleanFFlag<"aggressive-function-elimination">, Group; defm align_commons : BooleanFFlag<"align-commons">, Group; defm all_intrinsics : BooleanFFlag<"all-intrinsics">, Group; -defm automatic : BooleanFFlag<"automatic">, Group; +def fautomatic : Flag<["-"], "fautomatic">; // -fno-automatic is significant defm backtrace : BooleanFFlag<"backtrace">, Group; defm bounds_check : BooleanFFlag<"bounds-check">, Group; defm check_array_temporaries : BooleanFFlag<"check-array-temporaries">, Group; @@ -4616,6 +4616,9 @@ defm backslash : OptInFC1FFlag<"backslash", "Specify that backslash in string in defm xor_operator : OptInFC1FFlag<"xor-operator", "Enable .XOR. as a synonym of .NEQV.">; defm logical_abbreviations : OptInFC1FFlag<"logical-abbreviations", "Enable logical abbreviations">; defm implicit_none : OptInFC1FFlag<"implicit-none", "No implicit typing allowed unless overridden by IMPLICIT statements">; + +def fno_automatic : Flag<["-"], "fno-automatic">, Group, + HelpText<"Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE">; } def J : JoinedOrSeparate<["-"], "J">, diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index b82c5d7600df2..c169e3d457938 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -32,7 +32,8 @@ void Flang::AddFortranDialectOptions(const ArgList &Args, options::OPT_fxor_operator, options::OPT_fno_xor_operator, options::OPT_falternative_parameter_statement, options::OPT_fdefault_real_8, options::OPT_fdefault_integer_8, -options::OPT_fdefault_double_8, options::OPT_flarge_sizes}); +options::OPT_fdefault_double_8, options::OPT_flarge_sizes, +options::OPT_fno_automatic}); } void Flang::AddPreprocessingOptions(const ArgList &Args, diff --git a/flang/include/flang/Common/Fortran-features.h b/flang/include/flang/Common/Fortran-features.h index ddce794056320..f5fe2b5de475e 100644 --- a/flang/include/flang/Common/Fortran-features.h +++ b/flang/inc
[clang] [flang] [RFC][flang][runtime] Add FortranFloat128Math wrapper library. (PR #81971)
https://github.com/klausler approved this pull request. https://github.com/llvm/llvm-project/pull/81971 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add -fhermetic-module-files (PR #98083)
https://github.com/klausler created https://github.com/llvm/llvm-project/pull/98083 Module files emitted by this Fortran compiler are valid Fortran source files. Symbols that are USE-associated into modules are represented in their module files with USE statements and special comments with hash codes in them to ensure that those USE statements resolve to the same modules that were used to build the module when its module file was generated. This scheme prevents unchecked module file growth in large applications by not emitting USE-associated symbols redundantly. This problem can be especially bad when derived type definitions must be repeated in the module files of their clients, and the clients of those modules, and so on. However, this scheme has the disadvantage that clients of modules must be compiled with dependent modules in the module search path. This new -fhermetic-module-files option causes module file output to be free of dependences on any non-intrinsic module files; dependent modules are instead emitted as part of the module file, rather than being USE-associated. It is intended for top level library module files that are shipped with binary libraries when it is not convenient to collect and ship their dependent module files as well. Fixes https://github.com/llvm/llvm-project/issues/97398. >From e85b374f3f78090daf0293b6ed6258bf91fb7b95 Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Mon, 8 Jul 2024 14:27:02 -0700 Subject: [PATCH] [flang] Add -fhermetic-module-files Module files emitted by this Fortran compiler are valid Fortran source files. Symbols that are USE-associated into modules are represented in their module files with USE statements and special comments with hash codes in them to ensure that those USE statements resolve to the same modules that were used to build the module when its module file was generated. This scheme prevents unchecked module file growth in large applications by not emitting USE-associated symbols redundantly. This problem can be especially bad when derived type definitions must be repeated in the module files of their clients, and the clients of those modules, and so on. However, this scheme has the disadvantage that clients of modules must be compiled with dependent modules in the module search path. This new -fhermetic-module-files option causes module file output to be free of dependences on any non-intrinsic module files; dependent modules are instead emitted as part of the module file, rather than being USE-associated. It is intended for top level library module files that are shipped with binary libraries when it is not convenient to collect and ship their dependent module files as well. Fixes https://github.com/llvm/llvm-project/issues/97398. --- clang/include/clang/Driver/Options.td | 3 ++ clang/lib/Driver/ToolChains/Flang.cpp | 32 ++- .../flang/Frontend/CompilerInvocation.h | 9 flang/include/flang/Semantics/semantics.h | 10 ++-- flang/lib/Frontend/CompilerInvocation.cpp | 5 ++ flang/lib/Frontend/FrontendAction.cpp | 7 ++- flang/lib/Semantics/mod-file.cpp | 42 +++ flang/lib/Semantics/mod-file.h| 7 ++- flang/lib/Semantics/semantics.cpp | 4 +- flang/test/Semantics/modfile65.f90| 53 +++ 10 files changed, 142 insertions(+), 30 deletions(-) create mode 100644 flang/test/Semantics/modfile65.f90 diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 1c2b8cfeef6ce6..f3488c27ca1532 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -6667,6 +6667,9 @@ defm stack_arrays : BoolOptionWithoutMarshalling<"f", "stack-arrays", defm loop_versioning : BoolOptionWithoutMarshalling<"f", "version-loops-for-stride", PosFlag, NegFlag>; + +def fhermetic_module_files : Flag<["-"], "fhermetic-module-files">, Group, + HelpText<"Emit hermetic module files (no nested USE association)">; } // let Visibility = [FC1Option, FlangOption] def J : JoinedOrSeparate<["-"], "J">, diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 42b45dba2bd311..f9d4704dbb7bdf 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -35,18 +35,26 @@ static void addDashXForInput(const ArgList &Args, const InputInfo &Input, void Flang::addFortranDialectOptions(const ArgList &Args, ArgStringList &CmdArgs) const { - Args.addAllArgs( - CmdArgs, {options::OPT_ffixed_form, options::OPT_ffree_form, -options::OPT_ffixed_line_length_EQ, options::OPT_fopenacc, -options::OPT_finput_charset_EQ, options::OPT_fimplicit_none, -options::OPT_fno_implicit_none, options::OPT_fbackslash, -options::OPT_fno_backslash, options::OPT_flogical_abbrev
[clang] [flang] [flang][Frontend] Implement printing defined macros via -dM (PR #87627)
@@ -49,15 +51,21 @@ class Definition { TokenSequence Apply(const std::vector &args, Prescanner &); + void Print(llvm::raw_ostream &out, llvm::StringRef macroName = "") const; + private: static TokenSequence Tokenize(const std::vector &argNames, const TokenSequence &token, std::size_t firstToken, std::size_t tokens); + // For a given token, return the index of the argument to which the token + // corresponds, or `argumentCount` if the token does not correspond to any + // argument. + std::size_t getArgumentIndex(const CharBlock &token) const; klausler wrote: Capitalize function and member function names for consistency in the parser, please. https://github.com/llvm/llvm-project/pull/87627 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang][Frontend] Implement printing defined macros via -dM (PR #87627)
@@ -49,15 +51,21 @@ class Definition { TokenSequence Apply(const std::vector &args, Prescanner &); + void Print(llvm::raw_ostream &out, llvm::StringRef macroName = "") const; klausler wrote: `const char *` would be a more portable type for `macroName` for those who use this code outside llvm. https://github.com/llvm/llvm-project/pull/87627 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang][Frontend] Implement printing defined macros via -dM (PR #87627)
@@ -46,6 +49,38 @@ bool Definition::set_isDisabled(bool disable) { return was; } +void Definition::Print( +llvm::raw_ostream &out, llvm::StringRef macroName) const { + if (!isFunctionLike_) { +// If it's not a function-like macro, then just print the replacement. +out << ' ' << replacement_.ToString(); +return; + } + + size_t argCount{argumentCount()}; + + out << '('; + for (size_t i{0}; i != argCount; ++i) { +if (i != 0) { + out << ", "; +} +out << argNames_[i]; + } + if (isVariadic_) { +out << ", ..."; + } + out << ") "; + + for (size_t i{0}, e{replacement_.SizeInTokens()}; i != e; ++i) { +std::string tok{replacement_.TokenAt(i).ToString()}; +if (size_t idx = getArgumentIndex(tok); idx < argCount) { klausler wrote: `std::size_t idx {GetArgumentIndex(Tok)}; ...` https://github.com/llvm/llvm-project/pull/87627 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang][Frontend] Implement printing defined macros via -dM (PR #87627)
klausler wrote: > How is this code used outside of LLVM? Why do people want to use _without_ > LLVM? Just curious. There are people who want to construct tools to analyze or restructure Fortran programs outside of the context of compilation, and need to have access to a good parse tree or symbol table. Unlike most other languages, Fortran is weirdly hard to lex & parse, and tool writers would rather use an existing parser than do a partial job with something custom. So as a general rule, I avoid using llvm utilities in parsing and semantics (esp. parsing) when the facilities in `std::` are capable and portable, and try to encourage others to do the same. https://github.com/llvm/llvm-project/pull/87627 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang][Frontend] Implement printing defined macros via -dM (PR #87627)
https://github.com/klausler approved this pull request. https://github.com/llvm/llvm-project/pull/87627 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [lld] [flang] Generate main only when a Fortran program statement is present (PR #89938)
https://github.com/klausler approved this pull request. https://github.com/llvm/llvm-project/pull/89938 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [lld] [flang] Generate main only when a Fortran program statement is present (PR #89938)
https://github.com/klausler edited https://github.com/llvm/llvm-project/pull/89938 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [lld] [flang] Generate main only when a Fortran program statement is present (PR #89938)
@@ -0,0 +1,63 @@ +//===-- Main.cpp - generate main runtime API calls *- C++ klausler wrote: This header comment needs to be cleaned up. https://github.com/llvm/llvm-project/pull/89938 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [Flang] RFC: Add support for -w option (PR #90420)
klausler wrote: I am finishing up a patch that ensures that all warning messages are conditional in Semantics. https://github.com/llvm/llvm-project/pull/90420 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [Flang] RFC: Add support for -w option (PR #90420)
klausler wrote: See https://github.com/llvm/llvm-project/pull/90518, which I think would greatly ease implementation of `-w`. https://github.com/llvm/llvm-project/pull/90420 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] Allow disabling of types from the command line (PR #107126)
https://github.com/klausler approved this pull request. https://github.com/llvm/llvm-project/pull/107126 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] Allow disabling of types from the command line (PR #107126)
@@ -6761,6 +6761,12 @@ def fdefault_integer_8 : Flag<["-"],"fdefault-integer-8">, Group, HelpText<"Set the default integer and logical kind to an 8 byte wide type">; def fdefault_real_8 : Flag<["-"],"fdefault-real-8">, Group, HelpText<"Set the default real kind to an 8 byte wide type">; +def fdisable_real_3 : Flag<["-"],"fdisable-real-3">, Group, klausler wrote: maybe also `-fdisable-real-2`? https://github.com/llvm/llvm-project/pull/107126 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add -fhermetic-module-files (PR #98083)
https://github.com/klausler closed https://github.com/llvm/llvm-project/pull/98083 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] New -fdebug-unparse-with-modules option (PR #91660)
https://github.com/klausler created https://github.com/llvm/llvm-project/pull/91660 This option is a compilation action that parses a source file and performs semantic analysis on it, like the existing -fdebug-unparse option does. Its output, however, is preceded by the effective contents of all of the non-intrinsic modules on which it depends but does not define, transitively preceded by the closure of all of those modules' dependencies. The output from this option is therefore the analyzed parse tree for a source file encapsulated with all of its non-intrinsic module dependencies. This output may be useful for extracting code from large applications for use as an attachment to a bug report, or as input to a test case reduction tool for problem isolation. >From f56d89ab6ff37d974a3081792422a69d89266c38 Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Thu, 9 May 2024 14:27:02 -0700 Subject: [PATCH] [flang] New -fdebug-unparse-with-modules option This option is a compilation action that parses a source file and performs semantic analysis on it, like the existing -fdebug-unparse option does. Its output, however, is preceded by the effective contents of all of the non-intrinsic modules on which it depends but does not define, transitively preceded by the closure of all of those modules' dependencies. The output from this option is therefore the analyzed parse tree for a source file encapsulated with all of its non-intrinsic module dependencies. This output may be useful for extracting code from large applications for use as an attachment to a bug report, or as input to a test case reduction tool for problem isolation. --- clang/include/clang/Driver/Options.td | 4 +- .../include/flang/Frontend/FrontendActions.h | 4 ++ .../include/flang/Frontend/FrontendOptions.h | 4 ++ .../flang/Semantics/unparse-with-symbols.h| 4 ++ flang/lib/Frontend/CompilerInvocation.cpp | 3 ++ flang/lib/Frontend/FrontendActions.cpp| 9 + .../ExecuteCompilerInvocation.cpp | 2 + flang/lib/Semantics/mod-file.cpp | 20 +- flang/lib/Semantics/mod-file.h| 3 ++ flang/lib/Semantics/unparse-with-symbols.cpp | 38 +++ flang/test/Driver/unparse-with-modules.f90| 34 + 11 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 flang/test/Driver/unparse-with-modules.f90 diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 73a2518480e9b..2e6db8d5ebd56 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -6644,7 +6644,9 @@ def fdebug_unparse : Flag<["-"], "fdebug-unparse">, Group, DocBrief<[{Run the parser and the semantic checks. Then unparse the parse-tree and output the generated Fortran source file.}]>; def fdebug_unparse_with_symbols : Flag<["-"], "fdebug-unparse-with-symbols">, Group, - HelpText<"Unparse and stop.">; + HelpText<"Unparse with symbols and stop.">; +def fdebug_unparse_with_modules : Flag<["-"], "fdebug-unparse-with-modules">, Group, + HelpText<"Unparse with dependent modules and stop.">; def fdebug_dump_symbols : Flag<["-"], "fdebug-dump-symbols">, Group, HelpText<"Dump symbols after the semantic analysis">; def fdebug_dump_parse_tree : Flag<["-"], "fdebug-dump-parse-tree">, Group, diff --git a/flang/include/flang/Frontend/FrontendActions.h b/flang/include/flang/Frontend/FrontendActions.h index e2e859f3a81bd..7823565eb815f 100644 --- a/flang/include/flang/Frontend/FrontendActions.h +++ b/flang/include/flang/Frontend/FrontendActions.h @@ -108,6 +108,10 @@ class DebugUnparseWithSymbolsAction : public PrescanAndSemaAction { void executeAction() override; }; +class DebugUnparseWithModulesAction : public PrescanAndSemaAction { + void executeAction() override; +}; + class DebugUnparseAction : public PrescanAndSemaAction { void executeAction() override; }; diff --git a/flang/include/flang/Frontend/FrontendOptions.h b/flang/include/flang/Frontend/FrontendOptions.h index 06b1318f243b0..82ca99672ec61 100644 --- a/flang/include/flang/Frontend/FrontendOptions.h +++ b/flang/include/flang/Frontend/FrontendOptions.h @@ -63,6 +63,10 @@ enum ActionKind { /// Fortran source file DebugUnparseWithSymbols, + /// Parse, run semantics, and output a Fortran source file preceded + /// by all the necessary modules (transitively) + DebugUnparseWithModules, + /// Parse, run semantics and then output symbols from semantics DebugDumpSymbols, diff --git a/flang/include/flang/Semantics/unparse-with-symbols.h b/flang/include/flang/Semantics/unparse-with-symbols.h index d70110245e2b2..5e18b3fc3063d 100644 --- a/flang/include/flang/Semantics/unparse-with-symbols.h +++ b/flang/include/flang/Semantics/unparse-with-symbols.h @@ -21,8 +21,12 @@ struct Program; } namespace Fortran::semantics { +class SemanticsContext; void UnparseWithSymbols(llvm::raw_ostream &,
[clang] [flang] [flang] New -fdebug-unparse-with-modules option (PR #91660)
https://github.com/klausler closed https://github.com/llvm/llvm-project/pull/91660 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [llvm] [openmp] [flang][driver] rename flang-new to flang (PR #110023)
klausler wrote: > @klausler , can you point me specifically at the failure messages? The > failures I've seen so far from the merge did not look related to my > (admittedly untrained) eye. I ran the tests in the repo and they passed > locally. Are there other tests somewhere that need to be updated as well? They haven't shown up in the build bots, so it must be something in my local environment that I've missed. If you ran llvm-test-suite's Fortran tests cleanly, then don't worry. https://github.com/llvm/llvm-project/pull/110023 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [llvm] [openmp] [flang][driver] rename flang-new to flang (PR #110023)
klausler wrote: There are multiple weird failures in llvm-test-suite where clang++ complains about unknown options that look like they're slang-only options. Did you run llvm-test-suite before merging? Please check. These failures are going to cause build bot failures shortly in the clang-*-2stage builds if not repaired or reverted. https://github.com/llvm/llvm-project/pull/110023 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [llvm] [openmp] [flang][driver] rename flang-new to flang (PR #110023)
klausler wrote: > Which I don't think the rename is at fault for. If you rebase to current llvm-project/main, that test will (or should) work; it got broken yesterday and was fixed later. https://github.com/llvm/llvm-project/pull/110023 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add UNSIGNED (PR #113504)
@@ -0,0 +1,116 @@ + + +# Fortran Extensions supported by Flang + +```{contents} +--- +local: +--- +``` + +For better compatibility with GNU Fortran and Sun Fortran, +this compiler supports an option (`-funsigned`) that enables +the `UNSIGNED` data type, constants, intrinsic functions, +its use with intrinsic operations and `SELECT CASE`, and C +language interoperability. + +## `UNSIGNED` type + +`UNSIGNED` is a numeric type with the same kinds as `INTEGER`. +It may appear as a type-spec in any context, including +a type declaration statement, a type-decl in an array +constructor or `ALLOCATE` statement, `IMPLICIT`, or a +function statement's prefix. + +`UNSIGNED` constants are nonempty strings of decimal digits +followed by the letter `U` and optionally a kind suffix with +an underscore. + +## `UNSIGNED` operations + +`UNSIGNED` operands are accepted for unary negation (`-`), +the basic four binary arithmetic intrinsic operations `+`, `-`, `*`, and `/`, +and for numeric relational operators. +The power operator `**` does not accept `UNSIGNED` operands. + +Mixed operations with other types are not allowed. +Mixed operations with one `UNSIGNED` operand and one BOZ literal +constant operand are allowed. +When the operands' kinds differ, the smaller operand is zero-extended +to the size of the larger. + +The arithmetic operations `u+v`, `-u`, `u-v`, and `u*v` are implemented +modulo `MAX(HUGE(u),HUGE(v))+1`; +informally speaking, they always truncate their results, or are +guaranteed to "wrap". + +## `UNSIGNED` intrinsic functions + +`UNSIGNED` operands are accepted as operands to, +or may be returned as results from, +several intrinsic procedures. + +Bitwise operations: +* `NOT` +* `IAND`, `IOR`, `IEOR`, `IBCLR`, `IBSET`, `IBITS`, `MERGE_BITS` +* `BTEST` +* `ISHFT`, `ISHFTC` +* `SHIFTA`, `SHIFTL`, `SHIFTR` +* `TRANSFER` +* `MVBITS` + +The existing unsigned comparisons `BLT`, `BLE`, `BGE`, and `BGT`. + +The inquiries `BIT_SIZE`, `DIGITS`, `HUGE`, and `RANGE`. + +Homogeneous `MAX` and `MIN`. klausler wrote: It means that `MAX` and `MIN` should support `UNSIGNED` arguments, but only when all of the arguments are `UNSIGNED`. Mixed arguments with `UNSIGNED` combined with `REAL` or other types should not work. https://github.com/llvm/llvm-project/pull/113504 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add UNSIGNED (PR #113504)
https://github.com/klausler edited https://github.com/llvm/llvm-project/pull/113504 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add UNSIGNED (PR #113504)
@@ -135,8 +141,12 @@ static constexpr TypePattern SubscriptInt{IntType, KindCode::subscript}; // Match any kind of some intrinsic or derived types static constexpr TypePattern AnyInt{IntType, KindCode::any}; +static constexpr TypePattern AnyUnsigned{UnsignedType, KindCode::any}; klausler wrote: Thanks; removed. https://github.com/llvm/llvm-project/pull/113504 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add UNSIGNED (PR #113504)
@@ -178,7 +192,12 @@ static constexpr TypePattern SameType{AnyType, KindCode::same}; // universal extension feature. static constexpr TypePattern OperandReal{RealType, KindCode::operand}; static constexpr TypePattern OperandInt{IntType, KindCode::operand}; +static constexpr TypePattern OperandUnsigned{UnsignedType, KindCode::operand}; +static constexpr TypePattern OperandIntOrUnsigned{ klausler wrote: Thanks; removed. https://github.com/llvm/llvm-project/pull/113504 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add UNSIGNED (PR #113504)
@@ -968,21 +968,41 @@ struct BinaryOp {}; fir::FirOpBuilder &builder, \ const Op &, hlfir::Entity lhs, \ hlfir::Entity rhs) { \ - return hlfir::EntityWithAttributes{ \ - builder.create(loc, lhs, rhs)}; \ + if constexpr (Fortran::common::TypeCategory::GenBinTyCat == \ +Fortran::common::TypeCategory::Unsigned && \ +!std::is_same_v) { \ +int bits = \ +Fortran::evaluate::Type::Scalar::bits; \ +auto signlessType = mlir::IntegerType::get( \ +builder.getContext(), bits, \ +mlir::IntegerType::SignednessSemantics::Signless); \ +auto lhsSL = builder.createConvert(loc, signlessType, lhs); \ klausler wrote: The conversion of the operands is required in order to avoid errors from the MLIR validator. The conversion of the result ensures that it is characterized properly as unsigned for any later use as an argument to a runtime intrinsic function or an output data transfer statement. https://github.com/llvm/llvm-project/pull/113504 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add UNSIGNED (PR #113504)
@@ -213,6 +213,22 @@ def fir_IntegerType : FIR_Type<"Integer", "int"> { }]; } +def fir_UnsignedType : FIR_Type<"Unsigned", "unsigned"> { klausler wrote: I get HLFIR verifier errors on things like unsigned assignments if that type isn't defined and included in the sets of types below in that file. https://github.com/llvm/llvm-project/pull/113504 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add UNSIGNED (PR #113504)
@@ -400,6 +400,69 @@ constexpr TypeBuilderFunc getModel() { return fir::ReferenceType::get(f(context)); }; } +template <> +constexpr TypeBuilderFunc getModel() { + return getModel(); klausler wrote: The existing code does not distinguish `unsigned int` from `signed int`, so I followed that precedent for other sizes of `unsigned` types. Should the patch be changed to mark the signature for `unsigned int` as being unsigned, along with the other sizes, or just the other sizes? https://github.com/llvm/llvm-project/pull/113504 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add UNSIGNED (PR #113504)
klausler wrote: > Seems a place that needs to add UNSIGNED type case > > ``` > llvm-project/flang/lib/Semantics/resolve-names.cpp:7597:16: error: > enumeration value 'Unsigned' not handled in switch [-Werror,-Wswitch] > switch (type.category()) { > ~^~ > llvm-project/flang/lib/Semantics/resolve-names.cpp:7621:1: error: non-void > function does not return a value in all control paths [-Werror,-Wreturn-type] > } > ``` Thanks, added a case. https://github.com/llvm/llvm-project/pull/113504 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add UNSIGNED (PR #113504)
@@ -213,6 +213,22 @@ def fir_IntegerType : FIR_Type<"Integer", "int"> { }]; } +def fir_UnsignedType : FIR_Type<"Unsigned", "unsigned"> { klausler wrote: If I comment out the appearance of `fir_UnsignedType.predicate` in `AnyIntegerLike` with ``` def AnyIntegerLike : TypeConstraint, "any integer">; +fir_IntegerType.predicate /* pmk: , fir_UnsignedType.predicate */]>, "any integer">; ``` my operations test case then fails to compile with ``` error: loc("/home/pklausler/llvm-project/flang/test/Lower/unsigned-ops.f90":5:3): 'hlfir.assign' op operand #0 must be any Fortran value or variable type, but got 'ui32' error: verification of lowering to FIR failed ``` https://github.com/llvm/llvm-project/pull/113504 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add UNSIGNED (PR #113504)
https://github.com/klausler converted_to_draft https://github.com/llvm/llvm-project/pull/113504 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add UNSIGNED (PR #113504)
@@ -968,21 +968,41 @@ struct BinaryOp {}; fir::FirOpBuilder &builder, \ const Op &, hlfir::Entity lhs, \ hlfir::Entity rhs) { \ - return hlfir::EntityWithAttributes{ \ - builder.create(loc, lhs, rhs)}; \ + if constexpr (Fortran::common::TypeCategory::GenBinTyCat == \ +Fortran::common::TypeCategory::Unsigned && \ +!std::is_same_v) { \ +int bits = \ +Fortran::evaluate::Type::Scalar::bits; \ +auto signlessType = mlir::IntegerType::get( \ +builder.getContext(), bits, \ +mlir::IntegerType::SignednessSemantics::Signless); \ +auto lhsSL = builder.createConvert(loc, signlessType, lhs); \ klausler wrote: The conversions are gone from the llvm output so at least there aren't no-op copies in the generated code. When/if clang emits mlir, any missing/broken unsigned optimizations will be more prominent and likely to get fixed for us. https://github.com/llvm/llvm-project/pull/113504 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add UNSIGNED (PR #113504)
@@ -400,6 +400,69 @@ constexpr TypeBuilderFunc getModel() { return fir::ReferenceType::get(f(context)); }; } +template <> +constexpr TypeBuilderFunc getModel() { + return getModel(); klausler wrote: I did try marking all of these explicitly unsigned where appropriate and it broke the world in ways I didn't understand. We can look at this further later when/if I merge this feature and try to clean it up. https://github.com/llvm/llvm-project/pull/113504 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang][preprocessor] Don't expand INCLUDE under -E by default (PR #110333)
https://github.com/klausler created https://github.com/llvm/llvm-project/pull/110333 Fortran INCLUDE lines have (until now) been treated like #include directives. This isn't how things work with other Fortran compilers when running under the -E option for preprocessing only, so stop doing it by default, and add -fpreprocess-include-lines to turn it back on when desired. >From 985846bbdeed74a2a22d00fc96e29cfe68e1491f Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Fri, 27 Sep 2024 15:08:08 -0700 Subject: [PATCH] [flang][preprocessor] Don't expand INCLUDE under -E by default Fortran INCLUDE lines have (until now) been treated like #include directives. This isn't how things work with other Fortran compilers when running under the -E option for preprocessing only, so stop doing it by default, and add -fpreprocess-include-lines to turn it back on when desired. --- clang/include/clang/Driver/Options.td | 2 ++ flang/include/flang/Frontend/PreprocessorOptions.h | 3 +++ flang/include/flang/Parser/parsing.h | 1 + flang/lib/Frontend/CompilerInvocation.cpp | 6 ++ flang/lib/Frontend/FrontendAction.cpp | 4 flang/lib/Parser/parsing.cpp | 2 ++ flang/lib/Parser/prescan.cpp | 3 +++ flang/lib/Parser/prescan.h | 5 + flang/test/Parser/include.f| 2 +- 9 files changed, 27 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 376d7d4290c0bf..388d8cd9d68e5a 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -6886,6 +6886,8 @@ def module_suffix : Separate<["-"], "module-suffix">, Group, MetaVarNa HelpText<"Use as the suffix for module files (the default value is `.mod`)">; def fno_reformat : Flag<["-"], "fno-reformat">, Group, HelpText<"Dump the cooked character stream in -E mode">; +def fpreprocess_include_lines : Flag<["-"], "fpreprocess-include-lines">, Group, + HelpText<"Treat INCLUDE lines like #include directives in -E mode">; defm analyzed_objects_for_unparse : OptOutFC1FFlag<"analyzed-objects-for-unparse", "", "Do not use the analyzed objects when unparsing">; def emit_fir : Flag<["-"], "emit-fir">, Group, diff --git a/flang/include/flang/Frontend/PreprocessorOptions.h b/flang/include/flang/Frontend/PreprocessorOptions.h index 13a91ee9a184f8..2de9dabb1b3722 100644 --- a/flang/include/flang/Frontend/PreprocessorOptions.h +++ b/flang/include/flang/Frontend/PreprocessorOptions.h @@ -56,6 +56,9 @@ struct PreprocessorOptions { // -fno-reformat: Emit cooked character stream as -E output bool noReformat{false}; + // -fpreprocess-include-lines: Treat INCLUDE as #include for -E output + bool preprocessIncludeLines{false}; + // -dM: Show macro definitions with -dM -E bool showMacros{false}; diff --git a/flang/include/flang/Parser/parsing.h b/flang/include/flang/Parser/parsing.h index 4d329c189cb80e..0c774decb16d31 100644 --- a/flang/include/flang/Parser/parsing.h +++ b/flang/include/flang/Parser/parsing.h @@ -40,6 +40,7 @@ struct Options { bool needProvenanceRangeToCharBlockMappings{false}; Fortran::parser::Encoding encoding{Fortran::parser::Encoding::UTF_8}; bool prescanAndReformat{false}; // -E + bool expandIncludeLinesInPreprocessedOutput{true}; bool showColors{false}; }; diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 90c327546198b5..f30cda1d051efc 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -819,6 +819,8 @@ static void parsePreprocessorArgs(Fortran::frontend::PreprocessorOptions &opts, : PPMacrosFlag::Exclude; opts.noReformat = args.hasArg(clang::driver::options::OPT_fno_reformat); + opts.preprocessIncludeLines = + args.hasArg(clang::driver::options::OPT_fpreprocess_include_lines); opts.noLineDirectives = args.hasArg(clang::driver::options::OPT_P); opts.showMacros = args.hasArg(clang::driver::options::OPT_dM); } @@ -1479,6 +1481,10 @@ void CompilerInvocation::setFortranOpts() { } fortranOptions.fixedFormColumns = frontendOptions.fixedFormColumns; + // -E + fortranOptions.prescanAndReformat = + frontendOptions.programAction == PrintPreprocessedInput; + fortranOptions.features = frontendOptions.features; fortranOptions.encoding = frontendOptions.encoding; diff --git a/flang/lib/Frontend/FrontendAction.cpp b/flang/lib/Frontend/FrontendAction.cpp index 42a614fe46be5b..041182bdf61781 100644 --- a/flang/lib/Frontend/FrontendAction.cpp +++ b/flang/lib/Frontend/FrontendAction.cpp @@ -95,6 +95,10 @@ bool FrontendAction::beginSourceFile(CompilerInstance &ci, getCurrentInput().getIsCUDAFortran()); } + // -fpreprocess-include-lines + invoc.getFortranOpts().expandIncludeLinesInPreprocessedOutput = +
[clang] [flang] [flang][preprocessor] Don't expand INCLUDE under -E by default (PR #110333)
https://github.com/klausler closed https://github.com/llvm/llvm-project/pull/110333 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add UNSIGNED (PR #113504)
@@ -0,0 +1,119 @@ + + +# Fortran Extensions supported by Flang + +```{contents} +--- +local: +--- +``` + +For better compatibility with GNU Fortran and Sun Fortran, +this compiler supports an option (`-funsigned`) that enables +the `UNSIGNED` data type, constants, intrinsic functions, +its use with intrinsic operations and `SELECT CASE`, and C +language interoperability. + +## `UNSIGNED` type + +`UNSIGNED` is a numeric type with the same kinds as `INTEGER`. +It may appear as a type-spec in any context, including +a type declaration statement, a type-decl in an array +constructor or `ALLOCATE` statement, `IMPLICIT`, or a +function statement's prefix. + +`UNSIGNED` constants are nonempty strings of decimal digits +followed by the letter `U` and optionally a kind suffix with +an underscore. + +## `UNSIGNED` operations + +`UNSIGNED` operands are accepted for unary negation (`-`), +the basic four binary arithmetic intrinsic operations `+`, `-`, `*`, and `/`, +and for numeric relational operators. +The power operator `**` does not accept `UNSIGNED` operands. + klausler wrote: Yes, and I disagreed with that restriction, since `-x` just means `0u-x`, which is well-defined. https://github.com/llvm/llvm-project/pull/113504 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add UNSIGNED (PR #113504)
https://github.com/klausler edited https://github.com/llvm/llvm-project/pull/113504 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add UNSIGNED (PR #113504)
klausler wrote: I've exercised all of the operations and intrinsic procedures with end-to-end testing; those tests will end up in llvm-test-suite later. So I'm turning off "draft" status now for this PR, and request your reviews. Thank you in advance. https://github.com/llvm/llvm-project/pull/113504 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add UNSIGNED (PR #113504)
https://github.com/klausler ready_for_review https://github.com/llvm/llvm-project/pull/113504 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang][driver] add option to make all main program variable static (PR #121968)
https://github.com/klausler approved this pull request. https://github.com/llvm/llvm-project/pull/121968 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add support for -fimplicit-none-ext option (PR #125248)
https://github.com/klausler edited https://github.com/llvm/llvm-project/pull/125248 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add support for -fimplicit-none-ext option (PR #125248)
https://github.com/klausler approved this pull request. Well done! Thank you. https://github.com/llvm/llvm-project/pull/125248 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add support for -fimplicit-none-ext option (PR #125248)
@@ -54,7 +54,7 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines, PolymorphicActualAllocatableOrPointerToMonomorphicDummy, RelaxedPureDummy, UndefinableAsynchronousOrVolatileActual, AutomaticInMainProgram, PrintCptr, SavedLocalInSpecExpr, PrintNamelist, AssumedRankPassedToNonAssumedRank, -IgnoreIrrelevantAttributes, Unsigned) +IgnoreIrrelevantAttributes, Unsigned, ImplicitNoneExternal) klausler wrote: I'd put this new name right after `ImplicitNoneTypeAlways` instead of at the end of the list. https://github.com/llvm/llvm-project/pull/125248 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [flang] Add UNSIGNED (PR #113504)
https://github.com/klausler closed https://github.com/llvm/llvm-project/pull/113504 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [lld] [Flang] Remove FortranDecimal library (PR #121997)
klausler wrote: can you accomplish your goals while leaving the binary/decimal package's sources and headers in their own directory? they constitute a stand-alone package that would lose its identity if the files were to be scattered elsewhere. https://github.com/llvm/llvm-project/pull/121997 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [lld] [Flang] Don't use FortranDecimal for runtime (PR #121997)
https://github.com/klausler approved this pull request. https://github.com/llvm/llvm-project/pull/121997 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [llvm] [flang-rt] Pass the whole path of libflang_rt.runtime.a to linker on AIX and LoP (PR #131041)
klausler wrote: ``` FAIL: Flang :: Driver/linker-flags.f90 (1 of 3430) TEST 'Flang :: Driver/linker-flags.f90' FAILED Exit Code: 1 Command Output (stderr): -- /home/pklausler/llvm-project/build/x86/gcc/9.3.0/Release/shared/bin/flang -### --target=ppc64le-linux-gnu /home/pklausler/llvm-project/flang/test/Driver/Inputs/hello.f90 2>&1 | /home/pklausler/llvm-project/build/x86/gcc/9.3.0/Release/shared/bin/FileCheck /home/pklausler/llvm-project/flang/test/Driver/linker-flags.f90 --check-prefixes=CHECK,UNIX,UNIX-F128LIBQUADMATH # RUN: at line 5 + /home/pklausler/llvm-project/build/x86/gcc/9.3.0/Release/shared/bin/flang -### --target=ppc64le-linux-gnu /home/pklausler/llvm-project/flang/test/Driver/Inputs/hello.f90 + /home/pklausler/llvm-project/build/x86/gcc/9.3.0/Release/shared/bin/FileCheck /home/pklausler/llvm-project/flang/test/Driver/linker-flags.f90 --check-prefixes=CHECK,UNIX,UNIX-F128LIBQUADMATH /home/pklausler/llvm-project/flang/test/Driver/linker-flags.f90:34:30: error: UNIX-F128LIBQUADMATH-SAME: expected string not found in input ! UNIX-F128LIBQUADMATH-SAME: "-lflang_rt.quadmath" "--as-needed" "-lquadmath" "--no-as-needed" ^ :7:265: note: scanning from here "/usr/bin/ld" "-z" "relro" "--hash-style=gnu" "--eh-frame-hdr" "-m" "elf64lppc" "-pie" "-dynamic-linker" "/lib64/ld64.so.2" "-o" "a.out" "Scrt1.o" "crti.o" "crtbeginS.o" "-L/lib/../lib64" "-L/usr/lib64" "-L/lib" "-L/usr/lib" "/tmp/lit-tmp-lj2vq0ix/hello-bf8634.o" "-L/local/home/pklausler/build/llvm-project/x86/gcc/9.3.0/Release/shared/lib" "-lflang_rt.runtime" "-lm" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "crtendS.o" "crtn.o" ^ :7:409: note: possible intended match here "/usr/bin/ld" "-z" "relro" "--hash-style=gnu" "--eh-frame-hdr" "-m" "elf64lppc" "-pie" "-dynamic-linker" "/lib64/ld64.so.2" "-o" "a.out" "Scrt1.o" "crti.o" "crtbeginS.o" "-L/lib/../lib64" "-L/usr/lib64" "-L/lib" "-L/usr/lib" "/tmp/lit-tmp-lj2vq0ix/hello-bf8634.o" "-L/local/home/pklausler/build/llvm-project/x86/gcc/9.3.0/Release/shared/lib" "-lflang_rt.runtime" "-lm" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "crtendS.o" "crtn.o" ^ Input file: Check file: /home/pklausler/llvm-project/flang/test/Driver/linker-flags.f90 -dump-input=help explains the following input dump. Input was: << 1: flang version 21.0.0git (g...@github.com:klausler/llvm-project.git 8cc63d9cd4f14c4a4b01e5f77c0a9e500a3f) 2: Target: ppc64le-unknown-linux-gnu 3: Thread model: posix 4: InstalledDir: /local/home/pklausler/build/llvm-project/x86/gcc/9.3.0/Release/shared/bin 5: Build config: +assertions 6: "/local/home/pklausler/build/llvm-project/x86/gcc/9.3.0/Release/shared/bin/flang" "-fc1" "-triple" "ppc64le-unknown-linux-gnu" "-emit-obj" "-mrelocation-model" "pic" "-pic-level" "2" "-pic-is-pie" "-target-cpu" "ppc64le" "-resource-dir" "/local/home/pklausler/build/llvm-project/x86/gcc/9.3.0/Release/shared/lib/clang/21" "-mframe-pointer=all" "-o" "/tmp/lit-tmp-lj2vq0ix/hello-bf8634.o" "-x" "f95-cpp-input" "/home/pklausler/llvm-project/flang/test/Driver/Inputs/hello.f90" 7: "/usr/bin/ld" "-z" "relro" "--hash-style=gnu" "--eh-frame-hdr" "-m" "elf64lppc" "-pie" "-dynamic-linker" "/lib64/ld64.so.2" "-o" "a.out" "Scrt1.o" "crti.o" "crtbeginS.o" "-L/lib/../lib64" "-L/usr/lib64" "-L/lib" "-L/usr/lib" "/tmp/lit-tmp-lj2vq0ix/hello-bf8634.o" "-L/local/home/pklausler/build/llvm-project/x86/gcc/9.3.0/Release/shared/lib" "-lflang_rt.runtime" "-lm" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "crtendS.o" "crtn.o" same:34'0 X~~~
[clang] [flang] [llvm] [flang-rt] Pass the whole path of libflang_rt.runtime.a to linker on AIX and LoP (PR #131041)
klausler wrote: Still fails in my x86-64 environment. https://github.com/llvm/llvm-project/pull/131041 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits