Skip to content
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion flang-rt/lib/runtime/misc-intrinsic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,20 @@ void RTDEF(Rename)(const Descriptor &path1, const Descriptor &path2,
char *pathDst{EnsureNullTerminated(
path2.OffsetElement(), path2.ElementBytes(), terminator)};

// Trim trailing blanks
Copy link
Contributor

@kparzysz kparzysz Sep 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File names in most unix-like filesystems can have trailing spaces. I think it's the caller that should make sure the names are correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do agree with that sentiment, but this implements the semantics of GFortran with this PR: https://gcc.gnu.org/onlinedocs/gfortran/RENAME.html.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kparzysz, note that you can still deal with blank terminated files on UNIX system after this patch by using rename("test_trailing "//char(0), "new_name "//char(0)).

This is consistent not only with gfortran, but also with IFX and nvfortran/classic flang implementations. Given this is a legacy lib3f intrinsic, we must stick to the existing behaviors here.

auto srcTrimPos{TrimTrailingSpaces(pathSrc, path1.ElementBytes())};
auto dstTrimPos{TrimTrailingSpaces(pathDst, path2.ElementBytes())};
char *srcPathTrim{
static_cast<char *>(alloca((srcTrimPos + 1) * sizeof(char)))};
char *dstPathTrim{
static_cast<char *>(alloca((dstTrimPos + 1) * sizeof(char)))};
std::memcpy(srcPathTrim, pathSrc, srcTrimPos);
std::memcpy(dstPathTrim, pathDst, dstTrimPos);
srcPathTrim[srcTrimPos] = '\0';
dstPathTrim[dstTrimPos] = '\0';

// We simply call rename(2) from POSIX
int result{rename(pathSrc, pathDst)};
int result{rename(srcPathTrim, dstPathTrim)};
if (status) {
// When an error has happened,
int errorCode{0}; // Assume success
Expand Down
Loading