Skip to content

[flang][runtime] Let FORT_CHECK_POINTER_DEALLOCATION=0 disable runtime … #84956

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
57 changes: 57 additions & 0 deletions flang/docs/RuntimeEnvironment.md
Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you for the document!

Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<!--===- docs/RuntimeEnvironment.md

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

-->

```{contents}
---
local:
---
```

# Environment variables of significance to Fortran execution

A few environment variables are queried by the Fortran runtime support
library.

The following environment variables can affect the behavior of
Fortran programs during execution.

## `DEFAULT_UTF8=1`

Set `DEFAULT_UTF8` to cause formatted external input to assume UTF-8
encoding on input and use UTF-8 encoding on formatted external output.

## `FORT_CONVERT`

Determines data conversions applied to unformatted I/O.

* `NATIVE`: no conversions (default)
* `LITTLE_ENDIAN`: assume input is little-endian; emit little-endian output
* `BIG_ENDIAN`: assume input is big-endian; emit big-endian output
* `SWAP`: reverse endianness (always convert)

## `FORT_CHECK_POINTER_DEALLOCATION`

Fortran requires that a pointer that appears in a `DEALLOCATE` statement
must have been allocated in an `ALLOCATE` statement with the same declared
type.
The runtime support library validates this requirement by checking the
size of the allocated data, and will fail with an error message if
the deallocated pointer is not valid.
Set `FORT_CHECK_POINTER_DEALLOCATION=0` to disable this check.

## `FORT_FMT_RECL`

Set to an integer value to specify the record length for list-directed
and `NAMELIST` output.
The default is 72.

## `NO_STOP_MESSAGE`

Set `NO_STOP_MESSAGE=1` to disable the extra information about
IEEE floating-point exception flags that the Fortran language
standard requires for `STOP` and `ERROR STOP` statements.
1 change: 1 addition & 0 deletions flang/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ on how to get in touch with us and to learn more about the current status.
Preprocessing
ProcedurePointer
RuntimeDescriptor
RuntimeEnvironment
RuntimeTypeInfo
Semantics
f2018-grammar.md
Expand Down
13 changes: 13 additions & 0 deletions flang/runtime/environment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,19 @@ void ExecutionEnvironment::Configure(int ac, const char *av[],
}
}

if (auto *x{std::getenv("FORT_CHECK_POINTER_DEALLOCATION")}) {
char *end;
auto n{std::strtol(x, &end, 10)};
if (n >= 0 && n <= 1 && *end == '\0') {
checkPointerDeallocation = n != 0;
} else {
std::fprintf(stderr,
"Fortran runtime: FORT_CHECK_POINTER_DEALLOCATION=%s is invalid; "
"ignored\n",
x);
}
}

// TODO: Set RP/ROUND='PROCESSOR_DEFINED' from environment
}

Expand Down
1 change: 1 addition & 0 deletions flang/runtime/environment.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ struct ExecutionEnvironment {
Convert conversion{Convert::Unknown}; // FORT_CONVERT
bool noStopMessage{false}; // NO_STOP_MESSAGE=1 inhibits "Fortran STOP"
bool defaultUTF8{false}; // DEFAULT_UTF8
bool checkPointerDeallocation{true}; // FORT_CHECK_POINTER_DEALLOCATION
};

extern ExecutionEnvironment executionEnvironment;
Expand Down
26 changes: 15 additions & 11 deletions flang/runtime/pointer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "flang/Runtime/pointer.h"
#include "assign-impl.h"
#include "derived.h"
#include "environment.h"
#include "stat.h"
#include "terminator.h"
#include "tools.h"
Expand Down Expand Up @@ -184,17 +185,20 @@ int RTDEF(PointerDeallocate)(Descriptor &pointer, bool hasStat,
if (!pointer.IsAllocated()) {
return ReturnError(terminator, StatBaseNull, errMsg, hasStat);
}
// Validate the footer. This should fail if the pointer doesn't
// span the entire object, or the object was not allocated as a
// pointer.
std::size_t byteSize{pointer.Elements() * pointer.ElementBytes()};
constexpr std::size_t align{sizeof(std::uintptr_t)};
byteSize = ((byteSize + align - 1) / align) * align;
void *p{pointer.raw().base_addr};
std::uintptr_t *footer{
reinterpret_cast<std::uintptr_t *>(static_cast<char *>(p) + byteSize)};
if (*footer != ~reinterpret_cast<std::uintptr_t>(p)) {
return ReturnError(terminator, StatBadPointerDeallocation, errMsg, hasStat);
if (executionEnvironment.checkPointerDeallocation) {
// Validate the footer. This should fail if the pointer doesn't
// span the entire object, or the object was not allocated as a
// pointer.
std::size_t byteSize{pointer.Elements() * pointer.ElementBytes()};
constexpr std::size_t align{sizeof(std::uintptr_t)};
byteSize = ((byteSize + align - 1) / align) * align;
void *p{pointer.raw().base_addr};
std::uintptr_t *footer{
reinterpret_cast<std::uintptr_t *>(static_cast<char *>(p) + byteSize)};
if (*footer != ~reinterpret_cast<std::uintptr_t>(p)) {
return ReturnError(
terminator, StatBadPointerDeallocation, errMsg, hasStat);
}
}
return ReturnError(terminator,
pointer.Destroy(/*finalize=*/true, /*destroyPointers=*/true, &terminator),
Expand Down