[flang-commits] [flang] [flang][semantics] add semantic check that STAT and ERRMSG are not (de)allocated by same statement (PR #164529)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Fri Oct 24 12:47:19 PDT 2025


================
@@ -751,6 +751,65 @@ bool DescriptorInquiry::operator==(const DescriptorInquiry &that) const {
   return field_ == that.field_ && base_ == that.base_ &&
       dimension_ == that.dimension_;
 }
+#include <type_traits>
+#include <utility>
+template <typename T, typename = void> struct has_union : std::false_type {};
+template <typename T>
+struct has_union<T, std::void_t<decltype(T::u)>> : std::true_type {};
+template <typename T, typename = void> struct has_base : std::false_type {};
+template <typename T>
+struct has_base<T, std::void_t<decltype(std::declval<T>().base())>>
+    : std::true_type {};
+template <typename T, typename = void>
+struct has_GetFirstSymbol : std::false_type {};
+template <typename T>
+struct has_GetFirstSymbol<T,
+    std::void_t<decltype(std::declval<T>().GetFirstSymbol())>>
+    : std::true_type {};
+
+template <typename P, typename R>
+bool TestVariableIsPathFromRoot(const P &path, const R &root) {
+  const SymbolRef *pathSym{nullptr}, *rootSym{nullptr};
+  if constexpr (has_union<P>::value) {
+    pathSym = std::get_if<SymbolRef>(&path.u);
+  }
+  if constexpr (has_union<R>::value) {
+    rootSym = std::get_if<SymbolRef>(&root.u);
+  }
+  if (pathSym) {
+    return rootSym && AreSameSymbol(*rootSym, *pathSym);
+  }
+  if constexpr (has_GetFirstSymbol<P>::value) {
+    if (rootSym) {
+      return AreSameSymbol(path.GetFirstSymbol(), *rootSym);
+    }
+  }
+  if constexpr (std::is_same_v<P, R>) {
+    if (path == root) {
+      return true;
+    }
+  }
+  if constexpr (has_base<P>::value) {
+    return TestVariableIsPathFromRoot(path.base(), root);
+  }
+  if constexpr (has_union<P>::value) {
+    return common::visit(
+        common::visitors{
+            [&](const auto &x) { return TestVariableIsPathFromRoot(x, root); },
+        },
+        path.u);
+  }
+  return false;
+}
+
+bool DataRef::IsPathFrom(const DataRef &that) const {
+  return TestVariableIsPathFromRoot(*this, that);
+}
+
+template <typename T>
+bool Designator<T>::IsPathFrom(const Designator<T> &that) const {
+  return TestVariableIsPathFromRoot(*this, that);
+}
----------------
klausler wrote:

This seems a bit complicated.  I'll think about it some more.  It might be easier to use `evaluate::GetSymbolVector()`, perhaps extended to include `associate` variables, and check whether the `stat=` variable 's vector is a prefix of an `allocate`/`deallocate` variable's vector.  If it is, and all symbols in the common prefix, are scalar, then it would be a hard error, otherwise just a warning.

https://github.com/llvm/llvm-project/pull/164529


More information about the flang-commits mailing list