Skip to content

[Flang] [OpenMP] Add semantic checks for detach clause in task #119172

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

Open
wants to merge 18 commits into
base: main
Choose a base branch
from

Conversation

Thirumalai-Shaktivel
Copy link
Member

Fixes:

  • Add semantic checks along with the tests
  • Move the detach clause to allowedOnceClauses list in Task construct

Restrictions:
OpenMP 5.0: Task construct

  • At most one detach clause can appear on the directive.
  • If a detach clause appears on the directive, then a mergeable clause cannot appear on the same directive.

OpenMP 5.2: Detach contruct

  • If a detach clause appears on a directive, then the encountering task must not be a final task.
  • A variable that appears in a detach clause cannot appear as a list item on a data-environment attribute clause on the same construct.
  • A variable that is part of another variable (as an array element or a structure element) cannot appear in a detach clause.
  • event-handle must not have the POINTER attribute.

@llvmbot llvmbot added flang Flang issues not falling into any other category flang:openmp flang:semantics clang:openmp OpenMP related changes to Clang labels Dec 9, 2024
@llvmbot
Copy link
Member

llvmbot commented Dec 9, 2024

@llvm/pr-subscribers-flang-openmp

@llvm/pr-subscribers-flang-semantics

Author: Thirumalai Shaktivel (Thirumalai-Shaktivel)

Changes

Fixes:

  • Add semantic checks along with the tests
  • Move the detach clause to allowedOnceClauses list in Task construct

Restrictions:
OpenMP 5.0: Task construct

  • At most one detach clause can appear on the directive.
  • If a detach clause appears on the directive, then a mergeable clause cannot appear on the same directive.

OpenMP 5.2: Detach contruct

  • If a detach clause appears on a directive, then the encountering task must not be a final task.
  • A variable that appears in a detach clause cannot appear as a list item on a data-environment attribute clause on the same construct.
  • A variable that is part of another variable (as an array element or a structure element) cannot appear in a detach clause.
  • event-handle must not have the POINTER attribute.

Full diff: https://github.com/llvm/llvm-project/pull/119172.diff

4 Files Affected:

  • (modified) flang/lib/Semantics/check-omp-structure.cpp (+110-30)
  • (modified) flang/lib/Semantics/check-omp-structure.h (+2)
  • (added) flang/test/Semantics/OpenMP/detach01.f90 (+65)
  • (modified) llvm/include/llvm/Frontend/OpenMP/OMP.td (+1-1)
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 3c9c5a02a338a6..23f7624182a556 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -2739,6 +2739,58 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
         llvm::omp::Clause::OMPC_copyprivate, {llvm::omp::Clause::OMPC_nowait});
   }
 
+  if (GetContext().directive == llvm::omp::Directive::OMPD_task) {
+    if (auto *d_clause{FindClause(llvm::omp::Clause::OMPC_detach)}) {
+      // OpenMP 5.0: Task construct restrictions
+      CheckNotAllowedIfClause(
+          llvm::omp::Clause::OMPC_detach, {llvm::omp::Clause::OMPC_mergeable});
+
+      // OpenMP 5.2: Task construct restrictions
+      if (FindClause(llvm::omp::Clause::OMPC_final)) {
+        context_.Say(GetContext().clauseSource,
+            "If a DETACH clause appears on a directive, then the encountering task must not be a FINAL task"_err_en_US);
+      }
+
+      const auto &detachClause{
+          std::get<parser::OmpClause::Detach>(d_clause->u)};
+      if (const auto *name{parser::Unwrap<parser::Name>(detachClause.v.v)}) {
+        if (name->symbol) {
+          std::string eventHandleSymName{name->ToString()};
+          auto checkVarAppearsInDataEnvClause = [&](const parser::OmpObjectList
+                                                        &objs,
+                                                    std::string clause) {
+            for (const auto &obj : objs.v) {
+              if (const parser::Name *name{parser::Unwrap<parser::Name>(obj)}) {
+                if (name->ToString() == eventHandleSymName) {
+                  context_.Say(GetContext().clauseSource,
+                      "A variable: `%s` that appears in a DETACH clause cannot appear on %s clause on the same construct"_err_en_US,
+                      eventHandleSymName, clause);
+                }
+              }
+            }
+          };
+          if (auto *dataEnvClause{
+                  FindClause(llvm::omp::Clause::OMPC_private)}) {
+            const auto &pClause{
+                std::get<parser::OmpClause::Private>(dataEnvClause->u)};
+            checkVarAppearsInDataEnvClause(pClause.v, "PRIVATE");
+          } else if (auto *dataEnvClause{
+                         FindClause(llvm::omp::Clause::OMPC_firstprivate)}) {
+            const auto &fpClause{
+                std::get<parser::OmpClause::Firstprivate>(dataEnvClause->u)};
+            checkVarAppearsInDataEnvClause(fpClause.v, "FIRSTPRIVATE");
+          } else if (auto *dataEnvClause{
+                         FindClause(llvm::omp::Clause::OMPC_in_reduction)}) {
+            const auto &irClause{
+                std::get<parser::OmpClause::InReduction>(dataEnvClause->u)};
+            checkVarAppearsInDataEnvClause(
+                std::get<parser::OmpObjectList>(irClause.v.t), "IN_REDUCTION");
+          }
+        }
+      }
+    }
+  }
+
   auto testThreadprivateVarErr = [&](Symbol sym, parser::Name name,
                                      llvmOmpClause clauseTy) {
     if (sym.test(Symbol::Flag::OmpThreadprivate))
@@ -2823,7 +2875,6 @@ CHECK_SIMPLE_CLAUSE(Capture, OMPC_capture)
 CHECK_SIMPLE_CLAUSE(Contains, OMPC_contains)
 CHECK_SIMPLE_CLAUSE(Default, OMPC_default)
 CHECK_SIMPLE_CLAUSE(Depobj, OMPC_depobj)
-CHECK_SIMPLE_CLAUSE(Detach, OMPC_detach)
 CHECK_SIMPLE_CLAUSE(DeviceType, OMPC_device_type)
 CHECK_SIMPLE_CLAUSE(DistSchedule, OMPC_dist_schedule)
 CHECK_SIMPLE_CLAUSE(Exclusive, OMPC_exclusive)
@@ -3352,40 +3403,45 @@ void OmpStructureChecker::CheckIsVarPartOfAnotherVar(
     const parser::CharBlock &source, const parser::OmpObjectList &objList,
     llvm::StringRef clause) {
   for (const auto &ompObject : objList.v) {
-    common::visit(
-        common::visitors{
-            [&](const parser::Designator &designator) {
-              if (const auto *dataRef{
-                      std::get_if<parser::DataRef>(&designator.u)}) {
-                if (IsDataRefTypeParamInquiry(dataRef)) {
+    CheckIsVarPartOfAnotherVar(source, ompObject, clause);
+  }
+}
+
+void OmpStructureChecker::CheckIsVarPartOfAnotherVar(
+    const parser::CharBlock &source, const parser::OmpObject &ompObject,
+    llvm::StringRef clause) {
+  common::visit(
+      common::visitors{
+          [&](const parser::Designator &designator) {
+            if (const auto *dataRef{
+                    std::get_if<parser::DataRef>(&designator.u)}) {
+              if (IsDataRefTypeParamInquiry(dataRef)) {
+                context_.Say(source,
+                    "A type parameter inquiry cannot appear on the %s "
+                    "directive"_err_en_US,
+                    ContextDirectiveAsFortran());
+              } else if (parser::Unwrap<parser::StructureComponent>(
+                             ompObject) ||
+                  parser::Unwrap<parser::ArrayElement>(ompObject)) {
+                if (llvm::omp::nonPartialVarSet.test(GetContext().directive)) {
                   context_.Say(source,
-                      "A type parameter inquiry cannot appear on the %s "
+                      "A variable that is part of another variable (as an "
+                      "array or structure element) cannot appear on the %s "
                       "directive"_err_en_US,
                       ContextDirectiveAsFortran());
-                } else if (parser::Unwrap<parser::StructureComponent>(
-                               ompObject) ||
-                    parser::Unwrap<parser::ArrayElement>(ompObject)) {
-                  if (llvm::omp::nonPartialVarSet.test(
-                          GetContext().directive)) {
-                    context_.Say(source,
-                        "A variable that is part of another variable (as an "
-                        "array or structure element) cannot appear on the %s "
-                        "directive"_err_en_US,
-                        ContextDirectiveAsFortran());
-                  } else {
-                    context_.Say(source,
-                        "A variable that is part of another variable (as an "
-                        "array or structure element) cannot appear in a "
-                        "%s clause"_err_en_US,
-                        clause.data());
-                  }
+                } else {
+                  context_.Say(source,
+                      "A variable that is part of another variable (as an "
+                      "array or structure element) cannot appear in a "
+                      "%s clause"_err_en_US,
+                      clause.data());
                 }
               }
-            },
-            [&](const parser::Name &name) {},
-        },
-        ompObject.u);
-  }
+            }
+          },
+          [&](const parser::Name &name) {},
+      },
+      ompObject.u);
 }
 
 void OmpStructureChecker::Enter(const parser::OmpClause::Firstprivate &x) {
@@ -3711,6 +3767,30 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Linear &x) {
       x.v.u);
 }
 
+void OmpStructureChecker::Enter(const parser::OmpClause::Detach &x) {
+  // OpenMP 5.0: Task construct restrictions
+  CheckAllowedClause(llvm::omp::Clause::OMPC_detach);
+
+  // OpenMP 5.2: Detach clause restrictions
+  CheckIsVarPartOfAnotherVar(GetContext().clauseSource, x.v.v, "DETACH");
+  if (const auto *name{parser::Unwrap<parser::Name>(x.v.v)}) {
+    if (name->symbol) {
+      if (IsPointer(*name->symbol)) {
+        context_.Say(GetContext().clauseSource,
+            "The event-handle: `%s` must not have the POINTER attribute"_err_en_US,
+            name->ToString());
+      }
+    }
+    auto type{name->symbol->GetType()};
+    if (!name->symbol->GetType()->IsNumeric(TypeCategory::Integer) ||
+        evaluate::ToInt64(type->numericTypeSpec().kind()) != 8) {
+      context_.Say(GetContext().clauseSource,
+          "The event-handle: `%s` must be of type integer(kind=omp_event_handle_kind)"_err_en_US,
+          name->ToString());
+    }
+  }
+}
+
 void OmpStructureChecker::CheckAllowedMapTypes(
     const parser::OmpMapType::Value &type,
     const std::list<parser::OmpMapType::Value> &allowedMapTypeList) {
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 89af46d9171ad3..b8adbc77a8fce0 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -180,6 +180,8 @@ class OmpStructureChecker
       const common::Indirection<parser::ArrayElement> &, const parser::Name &);
   void CheckDoacross(const parser::OmpDoacross &doa);
   bool IsDataRefTypeParamInquiry(const parser::DataRef *dataRef);
+  void CheckIsVarPartOfAnotherVar(const parser::CharBlock &source,
+      const parser::OmpObject &obj, llvm::StringRef clause = "");
   void CheckIsVarPartOfAnotherVar(const parser::CharBlock &source,
       const parser::OmpObjectList &objList, llvm::StringRef clause = "");
   void CheckThreadprivateOrDeclareTargetVar(
diff --git a/flang/test/Semantics/OpenMP/detach01.f90 b/flang/test/Semantics/OpenMP/detach01.f90
new file mode 100644
index 00000000000000..e342fcd1b19b4a
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/detach01.f90
@@ -0,0 +1,65 @@
+! REQUIRES: openmp_runtime
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=50
+
+! OpenMP Version 5.2
+! Various checks for DETACH Clause (12.5.2)
+
+program test_detach
+    use omp_lib
+    implicit none
+    integer :: e, x
+    integer(omp_event_handle_kind) :: event_01, event_02(2)
+    integer(omp_event_handle_kind), pointer :: event_03
+
+
+    type :: t
+        integer(omp_event_handle_kind) :: event
+    end type
+
+    type(t) :: t_01
+
+    !ERROR: The event-handle: `e` must be of type integer(kind=omp_event_handle_kind)
+    !$omp task detach(e)
+        x = x + 1
+    !$omp end task
+
+    !ERROR: At most one DETACH clause can appear on the TASK directive
+    !$omp task detach(event_01) detach(event_01)
+        x = x + 1
+    !$omp end task
+
+    !ERROR: Clause MERGEABLE is not allowed if clause DETACH appears on the TASK directive
+    !$omp task detach(event_01) mergeable
+        x = x + 1
+    !$omp end task
+
+    !ERROR: If a DETACH clause appears on a directive, then the encountering task must not be a FINAL task
+    !$omp task detach(event_01) final(.false.)
+        x = x + 1
+    !$omp end task
+
+    !ERROR: A variable: `event_01` that appears in a DETACH clause cannot appear on PRIVATE clause on the same construct
+    !$omp task detach(event_01) private(event_01)
+        x = x + 1
+    !$omp end task
+
+    !ERROR: A variable: `event_01` that appears in a DETACH clause cannot appear on IN_REDUCTION clause on the same construct
+    !$omp task detach(event_01) in_reduction(+:event_01)
+        x = x + 1
+    !$omp end task
+
+    !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a DETACH clause
+    !$omp task detach(event_02(1))
+        x = x + 1
+    !$omp end task
+
+    !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a DETACH clause
+    !$omp task detach(t_01%event)
+        x = x + 1
+    !$omp end task
+
+    !ERROR: The event-handle: `event_03` must not have the POINTER attribute
+    !$omp task detach(event_03)
+        x = x + 1
+    !$omp end task
+end program
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index bd7fb2361aaeb1..9ada11241d3a56 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -1085,7 +1085,6 @@ def OMP_Task : Directive<"task"> {
     VersionedClause<OMPC_Affinity, 50>,
     VersionedClause<OMPC_Allocate>,
     VersionedClause<OMPC_Depend>,
-    VersionedClause<OMPC_Detach, 50>,
     VersionedClause<OMPC_FirstPrivate>,
     VersionedClause<OMPC_InReduction>,
     VersionedClause<OMPC_Mergeable>,
@@ -1095,6 +1094,7 @@ def OMP_Task : Directive<"task"> {
   ];
   let allowedOnceClauses = [
     VersionedClause<OMPC_Default>,
+    VersionedClause<OMPC_Detach, 50>,
     VersionedClause<OMPC_Final>,
     VersionedClause<OMPC_If>,
     VersionedClause<OMPC_Priority>,

@Thirumalai-Shaktivel Thirumalai-Shaktivel added flang Flang issues not falling into any other category flang:openmp and removed flang Flang issues not falling into any other category flang:openmp clang:openmp OpenMP related changes to Clang labels Dec 9, 2024
Copy link

github-actions bot commented Dec 9, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@Thirumalai-Shaktivel
Copy link
Member Author

There seems to be some problem with Check code formatting.

I get the following locally

$ git-clang-format
clang-format did not modify any files

The failed line seems to be within the range (80 characters):

              if (const parser::Name *name{parser::Unwrap<parser::Name>(obj)}) {

@llvmbot llvmbot added the clang:openmp OpenMP related changes to Clang label Dec 9, 2024
@Thirumalai-Shaktivel Thirumalai-Shaktivel removed the clang:openmp OpenMP related changes to Clang label Dec 9, 2024
@Thirumalai-Shaktivel Thirumalai-Shaktivel changed the title [OpenMP] [TASK] Add semantic checks for detach clause [Flang] [OpenMP] Add semantic checks for detach clause in task Dec 9, 2024
Fixes:
- Add semantic checks along with the tests
- Move the detach clause to allowedOnceClauses list in
  Task construct

Restrictions:\
OpenMP 5.0: Task construct
- At most one detach clause can appear on the directive.
- If a detach clause appears on the directive, then a mergeable
  clause cannot appear on the same directive.

OpenMP 5.2: Detach contruct
- If a detach clause appears on a directive, then the encountering
  task must not be a final task.
- A variable that appears in a detach clause cannot appear as a
  list item on a data-environment attribute clause on the same
  construct.
- A variable that is part of another variable (as an array element or a
  structure element) cannot appear in a detach clause.
- event-handle must not have the POINTER attribute.
}
auto type{name->symbol->GetType()};
if (!name->symbol->GetType()->IsNumeric(TypeCategory::Integer) ||
evaluate::ToInt64(type->numericTypeSpec().kind()) != 8) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove the check of the kind. We shouldn't be using hardcoded numbers.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I felt the same. But, the only info I had was the kind => 8 to throw an error for the following:

    !ERROR: The event-handle: `e` must be of type integer(kind=omp_event_handle_kind)
    !$omp task detach(e)
        x = x + 1
    !$omp end task

Do you know any other way to add a check for this?

Copy link
Contributor

Choose a reason for hiding this comment

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

We don't have a way of checking this, unfortunately. In other cases we limit it to checking that it has an INTEGER type, but without checking the kind.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yea, sure. I will add only checking the integer type.

@@ -2739,6 +2739,59 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
llvm::omp::Clause::OMPC_copyprivate, {llvm::omp::Clause::OMPC_nowait});
}

if (GetContext().directive == llvm::omp::Directive::OMPD_task) {
if (auto *d_clause{FindClause(llvm::omp::Clause::OMPC_detach)}) {
Copy link
Contributor

Choose a reason for hiding this comment

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

No snake_case please (d_clause).

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch, I forgot to update this.

Comment on lines 2744 to 2748
// OpenMP 5.0: Task construct restrictions
CheckNotAllowedIfClause(
llvm::omp::Clause::OMPC_detach, {llvm::omp::Clause::OMPC_mergeable});

// OpenMP 5.2: Task construct restrictions
Copy link
Contributor

Choose a reason for hiding this comment

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

If you're doing version-specific checks, please guard them with the actual version from -fopenmp-version. You can get it from the language options in context. This is done in a number of places in this file, you can check how to do it.

Comment on lines 2758 to 3180
std::string eventHandleSymName{name->ToString()};
auto checkVarAppearsInDataEnvClause = [&](const parser::OmpObjectList
&objs,
std::string clause) {
for (const auto &obj : objs.v) {
if (const parser::Name *objName{
parser::Unwrap<parser::Name>(obj)}) {
if (objName->ToString() == eventHandleSymName) {
context_.Say(GetContext().clauseSource,
"A variable: `%s` that appears in a DETACH clause cannot appear on %s clause on the same construct"_err_en_US,
eventHandleSymName, clause);
}
}
}
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Please compare symbols, not names. You can compare the results of &symbol->GetUltimate() to be accurate.

Comment on lines 3772 to 3775
// OpenMP 5.0: Task construct restrictions
CheckAllowedClause(llvm::omp::Clause::OMPC_detach);

// OpenMP 5.2: Detach clause restrictions
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here: please do version-specific checks based on the actual version.

@Thirumalai-Shaktivel
Copy link
Member Author

Thirumalai-Shaktivel commented Dec 11, 2024

Sure, thanks for the review. I will update it and report back soon.

integer(omp_event_handle_kind) :: event_01, event_02

!TODO: Throw following error for the versions 5.0 and 5.1
!ERR: At most one DETACH clause can appear on the TASK directive
Copy link
Member Author

Choose a reason for hiding this comment

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

This check is required for both OpenMP 5.0 and 5.1

So, for that, I can only add a check for this in OMP.td (by moving the clause to allowedOnceClauses)
and call CheckAllowedClause. but, this leads to throwing an error for OpenMP version >= 52. If I enclose CheckAllowedClause within an if block (checking the version to be 50 and 51). The clause context wouldn't be set as SetContextClauseInfo is called by this function, this caused a problem for version >= 52.

@kparzysz, do you have any suggestions here?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is not a blocker and can be fixed later on. Currently, we throw this error for every version with the latest commit

Copy link
Contributor

Choose a reason for hiding this comment

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

Couldn't you call SetContextClauseInfo manually for versions >= 52?

Copy link
Member Author

Choose a reason for hiding this comment

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

I thought I shouldn't be doing that (calling SetContextClauseInfo), but instead use only the CheckAllowed.

I will check it again and see what I can do there. Thank you for the suggestion.

@Thirumalai-Shaktivel
Copy link
Member Author

Done, @kparzysz, I addressed all of your comments

@Thirumalai-Shaktivel
Copy link
Member Author

Ping for review.

@Thirumalai-Shaktivel
Copy link
Member Author

@kparzysz, could you please review the changes again?

@llvmbot llvmbot added the clang:openmp OpenMP related changes to Clang label Mar 7, 2025
Copy link
Contributor

@tblah tblah left a comment

Choose a reason for hiding this comment

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

I'm sorry this PR got lost. Please feel free to ping me if something does not get reviewed

checkVarAppearsInDataEnvClause(
std::get<parser::OmpObjectList>(irClause.v.t),
"IN_REDUCTION");
}
Copy link
Contributor

Choose a reason for hiding this comment

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

what about SHARED?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch, I don't know how I missed this.

}
}

void OmpStructureChecker::CheckIsVarPartOfAnotherVar(
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion, feel free to ignore. I think this would be clearer

Suggested change
void OmpStructureChecker::CheckIsVarPartOfAnotherVar(
void OmpStructureChecker::CheckVarIsNotPartOfAnotherVar(

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor

@kparzysz kparzysz left a comment

Choose a reason for hiding this comment

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

Sorry for the delay in reviewing. Looks ok to me, but please wait for @tblah's input as well.

const auto &detach{
std::get<parser::OmpClause::Detach>(detachClause->u)};
if (const auto *name{parser::Unwrap<parser::Name>(detach.v.v)}) {
if (name->symbol) {
Copy link
Contributor

Choose a reason for hiding this comment

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

All parser::Name's should have non-null symbols by now (it's an internal compiler error if they don't).

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Comment on lines 3700 to 3701
"A type parameter inquiry cannot appear on the %s "
"directive"_err_en_US,
Copy link
Contributor

Choose a reason for hiding this comment

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

Please make message strings be in a single line (here and in other places you've changed). This is to make it easier to find them in the source based on the compiler output.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

@Thirumalai-Shaktivel
Copy link
Member Author

Thanks for the reviews, @kparzysz and @tblah.

@tblah, can you please do a final review on this PR? I have addressed your comments. If I missed anything, please let me know.

Copy link
Contributor

@tblah tblah left a comment

Choose a reason for hiding this comment

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

Thanks for the update. No need for another round of review for my nit comment.

Copy link
Contributor

@NimishMishra NimishMishra left a comment

Choose a reason for hiding this comment

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

LGTM. The code formatting needs to be fixed though

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:openmp OpenMP related changes to Clang flang:openmp flang:semantics flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants