[flang-commits] [flang] 39b747d - [Flang][OpenMP][Sema] More gracefully handle undefined symbol in a no implicit module for declare target

Andrew Gozillon via flang-commits flang-commits at lists.llvm.org
Fri May 5 04:30:12 PDT 2023


Author: Andrew Gozillon
Date: 2023-05-05T06:29:51-05:00
New Revision: 39b747d0b5e9a92fcea59ac454a04d20ed025e71

URL: https://github.com/llvm/llvm-project/commit/39b747d0b5e9a92fcea59ac454a04d20ed025e71
DIFF: https://github.com/llvm/llvm-project/commit/39b747d0b5e9a92fcea59ac454a04d20ed025e71.diff

LOG: [Flang][OpenMP][Sema] More gracefully handle undefined symbol in a no implicit module for declare target

Prior to this change, if you define a module as such with a declare target in it:

module test_0
    implicit none
!$omp declare target(no_implicit_materialization_1)
end module test_0

The compiler will crash rather than give some form of reasonable
diagnostic. This patch attempts to fix that.

Reviewers: kiranchandramohan

Differential Revision: https://reviews.llvm.org/D149913

Added: 
    flang/test/Semantics/OpenMP/declare-target06.f90

Modified: 
    flang/lib/Semantics/check-omp-structure.cpp
    flang/lib/Semantics/check-omp-structure.h

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index c7bc0197630c9..cd30441d5ad1e 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -970,6 +970,13 @@ void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
         common::visitors{
             [&](const parser::Designator &) {
               if (const auto *name{parser::Unwrap<parser::Name>(ompObject)}) {
+                // The symbol is null, return early, CheckSymbolNames
+                // should have already reported the missing symbol as a
+                // diagnostic error
+                if (!name->symbol) {
+                  return;
+                }
+
                 if (name->symbol->GetUltimate().IsSubprogram()) {
                   if (GetContext().directive ==
                       llvm::omp::Directive::OMPD_threadprivate)
@@ -1061,6 +1068,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPThreadprivate &c) {
 void OmpStructureChecker::Leave(const parser::OpenMPThreadprivate &c) {
   const auto &dir{std::get<parser::Verbatim>(c.t)};
   const auto &objectList{std::get<parser::OmpObjectList>(c.t)};
+  CheckSymbolNames(dir.source, objectList);
   CheckIsVarPartOfAnotherVar(dir.source, objectList);
   CheckThreadprivateOrDeclareTargetVar(objectList);
   dirContext_.pop_back();
@@ -1117,20 +1125,49 @@ void OmpStructureChecker::Enter(const parser::OpenMPDeclareTargetConstruct &x) {
   }
 }
 
+void OmpStructureChecker::CheckSymbolNames(
+    const parser::CharBlock &source, const parser::OmpObjectList &objList) {
+  for (const auto &ompObject : objList.v) {
+    common::visit(
+        common::visitors{
+            [&](const parser::Designator &designator) {
+              if (const auto *name{parser::Unwrap<parser::Name>(ompObject)}) {
+                if (!name->symbol) {
+                  context_.Say(source,
+                      "The given %s directive clause has an invalid argument"_err_en_US,
+                      ContextDirectiveAsFortran());
+                }
+              }
+            },
+            [&](const parser::Name &name) {
+              if (!name.symbol) {
+                context_.Say(source,
+                    "The given %s directive clause has an invalid argument"_err_en_US,
+                    ContextDirectiveAsFortran());
+              }
+            },
+        },
+        ompObject.u);
+  }
+}
+
 void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &x) {
   const auto &dir{std::get<parser::Verbatim>(x.t)};
   const auto &spec{std::get<parser::OmpDeclareTargetSpecifier>(x.t)};
   if (const auto *objectList{parser::Unwrap<parser::OmpObjectList>(spec.u)}) {
+    CheckSymbolNames(dir.source, *objectList);
     CheckIsVarPartOfAnotherVar(dir.source, *objectList);
     CheckThreadprivateOrDeclareTargetVar(*objectList);
   } else if (const auto *clauseList{
                  parser::Unwrap<parser::OmpClauseList>(spec.u)}) {
     for (const auto &clause : clauseList->v) {
       if (const auto *toClause{std::get_if<parser::OmpClause::To>(&clause.u)}) {
+        CheckSymbolNames(dir.source, toClause->v);
         CheckIsVarPartOfAnotherVar(dir.source, toClause->v);
         CheckThreadprivateOrDeclareTargetVar(toClause->v);
       } else if (const auto *linkClause{
                      std::get_if<parser::OmpClause::Link>(&clause.u)}) {
+        CheckSymbolNames(dir.source, linkClause->v);
         CheckIsVarPartOfAnotherVar(dir.source, linkClause->v);
         CheckThreadprivateOrDeclareTargetVar(linkClause->v);
       }
@@ -1797,9 +1834,12 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
               common::visitors{
                   [&](const parser::Designator &) {
                     if (const auto *name{
-                            parser::Unwrap<parser::Name>(ompObject)})
-                      testThreadprivateVarErr(
-                          name->symbol->GetUltimate(), *name, type);
+                            parser::Unwrap<parser::Name>(ompObject)}) {
+                      if (name->symbol) {
+                        testThreadprivateVarErr(
+                            name->symbol->GetUltimate(), *name, type);
+                      }
+                    }
                   },
                   [&](const parser::Name &name) {
                     if (name.symbol) {

diff  --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 992531a586db8..b99a19013c8c1 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -216,6 +216,8 @@ class OmpStructureChecker
       const parser::CharBlock &source, const parser::OmpObjectList &objList);
   void CheckThreadprivateOrDeclareTargetVar(
       const parser::OmpObjectList &objList);
+  void CheckSymbolNames(
+      const parser::CharBlock &source, const parser::OmpObjectList &objList);
   void CheckIntentInPointer(
       const parser::OmpObjectList &, const llvm::omp::Clause);
   void GetSymbolsInObjectList(const parser::OmpObjectList &, SymbolSourceMap &);

diff  --git a/flang/test/Semantics/OpenMP/declare-target06.f90 b/flang/test/Semantics/OpenMP/declare-target06.f90
new file mode 100644
index 0000000000000..a2d8263a60294
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/declare-target06.f90
@@ -0,0 +1,23 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 5.1
+! Check OpenMP construct validity for the following directives:
+! 2.14.7 Declare Target Directive
+! When used in an implicit none context.
+
+module test_0
+    implicit none
+!ERROR: The given DECLARE TARGET directive clause has an invalid argument
+!ERROR: No explicit type declared for 'no_implicit_materialization_1'
+!$omp declare target(no_implicit_materialization_1)
+
+!ERROR: The given DECLARE TARGET directive clause has an invalid argument
+!ERROR: No explicit type declared for 'no_implicit_materialization_2'
+!$omp declare target link(no_implicit_materialization_2)
+
+!ERROR: The given DECLARE TARGET directive clause has an invalid argument
+!ERROR: No explicit type declared for 'no_implicit_materialization_3'
+!$omp declare target to(no_implicit_materialization_3)
+
+INTEGER :: data_int = 10
+!$omp declare target(data_int)
+end module test_0


        


More information about the flang-commits mailing list