[flang-commits] [flang] [flang][OpenMP] Implicit declarations of procedures in DECLARE_TARGET (PR #201935)

Krzysztof Parzyszek via flang-commits flang-commits at lists.llvm.org
Sat Jun 6 07:03:20 PDT 2026


================
@@ -9756,6 +9742,28 @@ void ResolveNamesVisitor::HandleProcedureName(
     Symbol::Flag flag, const parser::Name &name) {
   CHECK(flag == Symbol::Flag::Function || flag == Symbol::Flag::Subroutine);
   auto *symbol{FindSymbol(NonDerivedTypeScope(), name)};
+  // A symbol listed on OpenMP declare_target directive may be a variable
+  // or a procedure. If the directive is the first occurrence of the name,
+  // it will create an implicit declaration of an object (since the name
+  // is not used in a call at that location). If the name turns out to be
+  // that of a procedure, this is going to create a problem.
+  // If a symbol was created because of its appearance in a declare_target,
+  // a use in a call should override it with the procedure symbol.
+  Scope *ompDTScope{nullptr};
+  // A name implicitly declared by a DECLARE_TARGET may have been followed
+  // by an explcit declaration. Make sure the symbol is still implicit
+  // before doing anything.
+  if (WasDeclaredByOmpDeclareTarget(symbol) &&
----------------
kparzysz wrote:

Yes, removing that was intentional.  We should defer to the standard Fortran rules for resolving symbols (handling of implicit declarations in this case) as much as possible(*), and `FindAndMarkDeclareTargetSymbol` was doing something contrary to those. In Fortran rules a mention of a name outside of a function/subroutine call will implicitly declare an object in the given scoping unit even if an external procedure with that name exists in the global scope.  However, when that name is first time used in a call instead, then it will resolve to the procedure.

(*) A name mentioned on **declare_target** should resolve to the same thing as if the **declare_target** was absent. In other words, the presence of **declare_target** should not change what a name mentioned in it resolves to. This is more of a guideline, but it's motivated by a user expectation that adding a declarative directive should only inform the compiler about additional properties of the thing the name refers to and not actually change what the name denotes.

This can be accomplished by just performing normal name resolution on names in directives. The **declare_target** (and the **enter** clause) are the only exceptions though, since they allow a procedure name to be listed without being used in a call. This "tricks" the normal resolution into thinking that the name refers to an object, and this PR undoes that.

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


More information about the flang-commits mailing list