diff options
author | peter klausler <pklausler@nvidia.com> | 2021-03-25 11:03:32 -0700 |
---|---|---|
committer | peter klausler <pklausler@nvidia.com> | 2021-03-25 12:36:50 -0700 |
commit | d811c829af616fd0bec08c7bebbe946e9bc96eea (patch) | |
tree | 8f84449c679e5f76ddda69eae542742d9feb1270 /flang | |
parent | [Support][Windows] Make sure only executables are found by sys::findProgramBy... (diff) | |
download | llvm-project-d811c829af616fd0bec08c7bebbe946e9bc96eea.tar.gz llvm-project-d811c829af616fd0bec08c7bebbe946e9bc96eea.tar.bz2 llvm-project-d811c829af616fd0bec08c7bebbe946e9bc96eea.zip |
[flang] fix spurious runtime crash on TRIM('')
The standard interoperability routine CFI_establish() does not
accept a zero-length CHARACTER type. Since these can be valid
results of intrinsic function references, work around the design
of CFI_establish() in the wrapper routine that calls it.
Differential Revision: https://reviews.llvm.org/D99296
Diffstat (limited to 'flang')
-rw-r--r-- | flang/runtime/descriptor.cpp | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/flang/runtime/descriptor.cpp b/flang/runtime/descriptor.cpp index efcd61b50c4f..b66874b924e6 100644 --- a/flang/runtime/descriptor.cpp +++ b/flang/runtime/descriptor.cpp @@ -31,9 +31,23 @@ void Descriptor::Establish(TypeCode t, std::size_t elementBytes, void *p, int rank, const SubscriptValue *extent, ISO::CFI_attribute_t attribute, bool addendum) { Terminator terminator{__FILE__, __LINE__}; + // Subtle: the standard CFI_establish() function doesn't allow a zero + // elem_len argument in cases where elem_len is not ignored; and when it + // returns an error code (CFI_INVALID_ELEM_LEN in this case), it must not + // modify the descriptor. That design makes sense, maybe, for actual + // C interoperability, but we need to work around it here. A zero + // incoming element length is replaced by 4 so that it will be valid + // for all CHARACTER kinds. + std::size_t workaroundElemLen{elementBytes ? elementBytes : 4}; RUNTIME_CHECK(terminator, - ISO::CFI_establish(&raw_, p, attribute, t.raw(), elementBytes, rank, + ISO::CFI_establish(&raw_, p, attribute, t.raw(), workaroundElemLen, rank, extent) == CFI_SUCCESS); + if (elementBytes == 0) { + raw_.elem_len = 0; + for (int j{0}; j < rank; ++j) { + GetDimension(j).SetByteStride(0); + } + } raw_.f18Addendum = addendum; DescriptorAddendum *a{Addendum()}; RUNTIME_CHECK(terminator, addendum == (a != nullptr)); |