Skip to content

[clang][OpenMP] Add error for large expr in collapse clause #138592

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

Merged
merged 6 commits into from
May 12, 2025

Conversation

AmrDeveloper
Copy link
Member

@AmrDeveloper AmrDeveloper commented May 5, 2025

Report error when OpenMP collapse clause has an expression that can't be represented in 64-bit

Issue #138445

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:openmp OpenMP related changes to Clang labels May 5, 2025
@llvmbot
Copy link
Member

llvmbot commented May 5, 2025

@llvm/pr-subscribers-clang

Author: Amr Hesham (AmrDeveloper)

Changes

Report error when OpenMP SIMD collapse clause has an expression that can't be represented in 64-bit

Issue #138445


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

4 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (+2)
  • (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+2)
  • (modified) clang/lib/Sema/SemaOpenMP.cpp (+7)
  • (modified) clang/test/OpenMP/simd_collapse_messages.cpp (+2)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 203958dab7430..93c296360aebe 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -503,6 +503,8 @@ Improvements to Clang's diagnostics
 - ``-Wreserved-identifier`` now fires on reserved parameter names in a function
   declaration which is not a definition.
 
+- An error is now emitted when OpenMP SIMD ``collapse`` clause has expression larger than 64 bit.
+
 Improvements to Clang's time-trace
 ----------------------------------
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index e5a7cdc14a737..b0cbcf8d8a131 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11519,6 +11519,8 @@ def note_omp_collapse_ordered_expr : Note<
   "as specified in %select{'collapse'|'ordered'|'collapse' and 'ordered'}0 clause%select{||s}0">;
 def err_omp_negative_expression_in_clause : Error<
   "argument to '%0' clause must be a %select{non-negative|strictly positive}1 integer value">;
+def err_omp_large_expression_in_clause : Error<
+  "argument to '%0' clause cannot have more than 64 bits size">;
 def err_omp_not_integral : Error<
   "expression must have integral or unscoped enumeration "
   "type, not %0">;
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 835dba22a858d..52cb5b1fb5d71 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -15901,6 +15901,13 @@ ExprResult SemaOpenMP::VerifyPositiveIntegerConstantInClause(
         << E->getSourceRange();
     return ExprError();
   }
+
+  if (!Result.isRepresentableByInt64()) {
+    Diag(E->getExprLoc(), diag::err_omp_large_expression_in_clause)
+        << getOpenMPClauseNameForDiag(CKind) << E->getSourceRange();
+    return ExprError();
+  }
+
   if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
     DSAStack->setAssociatedLoops(Result.getExtValue());
   else if (CKind == OMPC_ordered)
diff --git a/clang/test/OpenMP/simd_collapse_messages.cpp b/clang/test/OpenMP/simd_collapse_messages.cpp
index 1ce3bef3535ce..3ae0a818284e9 100644
--- a/clang/test/OpenMP/simd_collapse_messages.cpp
+++ b/clang/test/OpenMP/simd_collapse_messages.cpp
@@ -43,6 +43,8 @@ T tmain(T argc, S **argv) {
   for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
   #pragma omp simd collapse (S) // expected-error {{'S' does not refer to a value}}
   for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp simd collapse (0xFFFFFFFFFFFFFFFF) // expected-error {{argument to 'collapse' clause cannot have more than 64 bits size}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
 #if __cplusplus <= 199711L
   // expected-error@+4 2 {{integral constant expression}} expected-note@+4 0+{{constant expression}}
 #else

Copy link

@k-arrows k-arrows left a comment

Choose a reason for hiding this comment

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

I am not a developer, so I won't review the implementation, but I have one comment. The way I originally wrote the bug report was poor, but it is not necessary to limit the fix and its test to OpenMP SIMD. For example, the code below also crashes:
https://godbolt.org/z/7T8MbE5j5

void f(void) {
#pragma omp for collapse(0xFFFFFFFFFFFFFFFF)
  for (int i = 0; i < 10; i++)
    ;
}

@AmrDeveloper
Copy link
Member Author

I am not a developer, so I won't review the implementation, but I have one comment. The way I originally wrote the bug report was poor, but it is not necessary to limit the fix and its test to OpenMP SIMD. For example, the code below also crashes: https://godbolt.org/z/7T8MbE5j5

void f(void) {
#pragma omp for collapse(0xFFFFFFFFFFFFFFFF)
  for (int i = 0; i < 10; i++)
    ;
}

Thank you, that makes sense. I will extend the test with more cases

@AmrDeveloper AmrDeveloper force-pushed the fix_omp_overflow_crash branch from 3f484eb to d39464b Compare May 6, 2025 17:17
@AmrDeveloper AmrDeveloper changed the title [clang][OpenMP] Add error for large expr in SIMD collapse [clang][OpenMP] Add error for large expr in collapse clause May 6, 2025
@k-arrows
Copy link

k-arrows commented May 7, 2025

In addition to the collapse clause, the ordered clause also seems to have the same problem. For example, does your patch also fix the following crash? If so, you also need tests regarding the ordered clause.
https://godbolt.org/z/96sa5jxff

void f(void) {
#pragma omp for ordered(0xFFFFFFFFFFFFFFFF)
  for (int i = 0; i < 10; i++)
    ;
}

@AmrDeveloper AmrDeveloper force-pushed the fix_omp_overflow_crash branch from f1ba307 to dc940a3 Compare May 8, 2025 16:32
@AmrDeveloper
Copy link
Member Author

In addition to the collapse clause, the ordered clause also seems to have the same problem. For example, does your patch also fix the following crash? If so, you also need tests regarding the ordered clause. https://godbolt.org/z/96sa5jxff

void f(void) {
#pragma omp for ordered(0xFFFFFFFFFFFFFFFF)
  for (int i = 0; i < 10; i++)
    ;
}

Thank you, yes, it will fix this case too

@AaronBallman
Copy link
Collaborator

Thank you for the fix! I've added a few more reviewers. This is a pretty general problem, so I think we may want additional test coverage for basically any of the OpenMP clauses which accept an integer argument. For example, this is another related issue: #139268 -- I expect they're all resolved by your fix, perhaps?

@AmrDeveloper
Copy link
Member Author

AmrDeveloper commented May 9, 2025

Thank you for the fix! I've added a few more reviewers. This is a pretty general problem, so I think we may want additional test coverage for basically any of the OpenMP clauses which accept an integer argument. For example, this is another related issue: #139268 -- I expect they're all resolved by your fix, perhaps?

Thank you for adding reviewers.

It will not fix the other issue because ActOnOpenMPUnrollDirective uses getZValue directly and doesn't call VerifyPositiveIntegerConstantInClause, the solution will be similar, but inside ActOnOpenMPUnrollDirective.

I will check for cases that fixed because they are using VerifyPositiveIntegerConstantInClause and add them to the test

@@ -15901,6 +15901,13 @@ ExprResult SemaOpenMP::VerifyPositiveIntegerConstantInClause(
<< E->getSourceRange();
return ExprError();
}

if (!Result.isRepresentableByInt64()) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

So these are always 64 bit integers? This: https://www.openmp.org/spec-html/5.2/openmpsu30.html#x60-620004.4.3, "expression of integer type"

Copy link
Member Author

Choose a reason for hiding this comment

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

In our implementation, yes, because we const evaluate the value to APInt and it store the value in i64

@@ -11523,6 +11523,8 @@ def note_omp_collapse_ordered_expr : Note<
"as specified in %select{'collapse'|'ordered'|'collapse' and 'ordered'}0 clause%select{||s}0">;
def err_omp_negative_expression_in_clause : Error<
"argument to '%0' clause must be a %select{non-negative|strictly positive}1 integer value">;
def err_omp_large_expression_in_clause : Error<
"argument to '%0' clause cannot have more than 64 bits size">;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
"argument to '%0' clause cannot have more than 64 bits size">;
"argument to '%0' clause cannot have more than 64 bits">;

@AmrDeveloper AmrDeveloper force-pushed the fix_omp_overflow_crash branch from dc940a3 to f808ca3 Compare May 10, 2025 15:03
Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

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

LGTM, but I'd appreciate confirmation from an OpenMP code owner too.

@AmrDeveloper AmrDeveloper merged commit a4186bd into llvm:main May 12, 2025
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:openmp OpenMP related changes to Clang clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants