Skip to content

[flang][OpenMP] Skip assertion while processing default clause on disallowed constructs #93438

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

Closed
wants to merge 2 commits into from

Conversation

NimishMishra
Copy link
Contributor

@NimishMishra NimishMishra commented May 27, 2024

Currently, the handling of default clause on directives enforces an assertion on whether default clause is allowed on the directive. This causes crashes when default is erroneously defined on a directive. This PR skips the assertion, as such semantic checks are handled elsewhere.

Fixes #93437

@llvmbot llvmbot added flang Flang issues not falling into any other category flang:openmp flang:semantics labels May 27, 2024
@llvmbot
Copy link
Member

llvmbot commented May 27, 2024

@llvm/pr-subscribers-flang-semantics

Author: None (NimishMishra)

Changes

Currently, the handling of default clause on directives enforces an assertion on whether default clause is allowed on the directive. This causes crashes when default is erroneously defined on a directive. This PR converts the assertion into a semantic failure.

Fixes #93437


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

1 Files Affected:

  • (modified) flang/lib/Semantics/resolve-directives.cpp (+7-2)
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index dbc531372c3f4..659f508e1c193 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -2109,8 +2109,13 @@ void OmpAttributeVisitor::Post(const parser::Name &name) {
           dirContext.defaultDSA == Symbol::Flag::OmpShared) {
         // 1) default
         // Allowed only with parallel, teams and task generating constructs.
-        assert(parallelDir || taskGenDir ||
-            llvm::omp::allTeamsSet.test(dirContext.directive));
+        if (!(parallelDir || taskGenDir ||
+                llvm::omp::allTeamsSet.test(dirContext.directive)))
+          context_.Say(dirContext.directiveSource,
+              "%s directive cannot have default clause"_err_en_US,
+              parser::ToUpperCaseLetters(
+                  llvm::omp::getOpenMPDirectiveName(dirContext.directive)
+                      .str()));
         if (dirContext.defaultDSA != Symbol::Flag::OmpShared)
           declNewSymbol(dirContext.defaultDSA);
         else

@llvmbot
Copy link
Member

llvmbot commented May 27, 2024

@llvm/pr-subscribers-flang-openmp

Author: None (NimishMishra)

Changes

Currently, the handling of default clause on directives enforces an assertion on whether default clause is allowed on the directive. This causes crashes when default is erroneously defined on a directive. This PR converts the assertion into a semantic failure.

Fixes #93437


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

1 Files Affected:

  • (modified) flang/lib/Semantics/resolve-directives.cpp (+7-2)
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index dbc531372c3f4..659f508e1c193 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -2109,8 +2109,13 @@ void OmpAttributeVisitor::Post(const parser::Name &name) {
           dirContext.defaultDSA == Symbol::Flag::OmpShared) {
         // 1) default
         // Allowed only with parallel, teams and task generating constructs.
-        assert(parallelDir || taskGenDir ||
-            llvm::omp::allTeamsSet.test(dirContext.directive));
+        if (!(parallelDir || taskGenDir ||
+                llvm::omp::allTeamsSet.test(dirContext.directive)))
+          context_.Say(dirContext.directiveSource,
+              "%s directive cannot have default clause"_err_en_US,
+              parser::ToUpperCaseLetters(
+                  llvm::omp::getOpenMPDirectiveName(dirContext.directive)
+                      .str()));
         if (dirContext.defaultDSA != Symbol::Flag::OmpShared)
           declNewSymbol(dirContext.defaultDSA);
         else

@NimishMishra
Copy link
Contributor Author

Another probable way of handling this crash is to let the check for directives handle whether default is indeed allowed or now. During processing of a Name, we silently skip processing symbols (i.e. not emit any error).

Indeed, for the linked reproducer, should we silently skip without emitting any error, at a later point, another semantic error "DEFAULT clause is not allowed on the DO directive" is emitted.

@kiranchandramohan
Copy link
Contributor

Isn't OMP.td responsible for what clauses are allowed on a directive? Could you add to the summary why this does not work for default in this case?

Is it possible to add this check in

void OmpAttributeVisitor::Post(const parser::OmpDefaultClause &x) {
?

Can you add a test?

@NimishMishra
Copy link
Contributor Author

Hi @kiranchandramohan, thanks for the review.

Yes indeed there is a semantic error in place. However, that is emitted after the assertion failure. That is why I was thinking that one way of working with this could be to silently return from this function (i.e. do not process default symbols) and let later checks emit the semantic error.

Currently, there are two semantic errors being emitted for the same violation.

@kiranchandramohan
Copy link
Contributor

Yes indeed there is a semantic error in place. However, that is emitted after the assertion failure. That is why I was thinking that one way of working with this could be to silently return from this function (i.e. do not process default symbols) and let later checks emit the semantic error.

This is fine, if the later code emits all the errors caught by the check in this function.

@NimishMishra NimishMishra changed the title [flang][OpenMP] Convert default assertion into a semantic error [flang][OpenMP] Skip assertion while processing default clause on disallowed constructs May 30, 2024
@@ -7,6 +7,15 @@ program main
integer :: i, N = 10
real :: a, arrayA(10), arrayB(10), arrayC(10)
real, external :: foo, bar, baz

!ERROR: DEFAULT clause is not allowed on the DO directive
Copy link
Contributor

Choose a reason for hiding this comment

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

The error message has to improve.

Copy link
Contributor Author

@NimishMishra NimishMishra May 30, 2024

Choose a reason for hiding this comment

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

This message is coming from CheckAllowed

void DirectiveStructureChecker<D, C, PC, ClauseEnumSize>::CheckAllowed(
. The message needs to be generic, since this is shared across different directives. Do you have anything specific in mind which we could add? Should we need something specific to default, then it would be better to resort to emitting the error at the position where the previous commit of this PR was doing.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, I was a bit confused by the presence of ordered and was thinking this is a restriction only if ordered is present. I see that this is a general constraint for the DO directive, so it is fine.

Copy link
Contributor

@kiranchandramohan kiranchandramohan left a comment

Choose a reason for hiding this comment

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

LG.

@@ -7,6 +7,15 @@ program main
integer :: i, N = 10
real :: a, arrayA(10), arrayB(10), arrayC(10)
real, external :: foo, bar, baz

!ERROR: DEFAULT clause is not allowed on the DO directive
!$omp do ordered default(private)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think ordered is not necessary for this test.

@@ -7,6 +7,15 @@ program main
integer :: i, N = 10
real :: a, arrayA(10), arrayB(10), arrayC(10)
real, external :: foo, bar, baz

!ERROR: DEFAULT clause is not allowed on the DO directive
Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, I was a bit confused by the presence of ordered and was thinking this is a restriction only if ordered is present. I see that this is a general constraint for the DO directive, so it is fine.

Copy link
Contributor

@luporl luporl left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for the fix.
I thought the check of whether a default clause is allowed on a directive would happen before the assert.

@NimishMishra
Copy link
Contributor Author

Already fixed by #107586, hence closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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.

[flang][OpenMP] Assertion failure in incorrect use of default clause
4 participants