Clang error: the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both lvalue expressions with scalar type (err_omp_atomic_capture_not_expression_statement)

From emmtrix Wiki
Jump to navigation Jump to search
Text error: the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both lvalue expressions with scalar type (since 12.0)
error: the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type (until 11.1)
Type Error
Category OpenMP Issue
Internal Id err_omp_atomic_capture_not_expression_statement
Internal Message the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both lvalue expressions with scalar type (since 12.0)
the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both l-value expressions with scalar type (until 11.1)
Regular Expression (?:error|fatal error)\: the statement for 'atomic capture' must be an expression statement of form 'v \= \+\+x;', 'v \= \-\-x;', 'v \= x\+\+;', 'v \= x\-\-;', 'v \= x binop\= expr;', 'v \= x \= x binop expr' or 'v \= x \= expr binop x', where x and v are both lvalue expressions with scalar type
First Commit 2014-07-24 459dec0ca2a7 [OPENMP] Initial parsing and sema analysis for clause 'capture' in 'atomic' directive.

Description

The error is issued by the Clang compiler when code attempting to use the 'atomic capture' feature in an OpenMP context does not adhere to the specific syntax required for expression statements within such contexts. For an 'atomic capture' operation, the code statement must precisely follow one of several predefined forms. These forms allow operations on variables (denoted 'v' and 'x' in the error message) that are both considered left-value (lvalue) expressions with scalar types. This requirement ensures that the operation directly manipulates the storage location of the involved variables in a manner that meets the atomicity guarantees provided by the OpenMP 'atomic' directive.

The permissible operations include incrementing ('++x' or 'x++'), decrementing ('--x' or 'x--'), and binary operations with assignment ('binop='), where 'binop' can represent any of the standard C/C++ binary operators appropriate for scalar types. These operations must directly involve the variable being captured ('v') and the one being operated upon ('x'), ensuring that the final expression statement aligns with one of the forms described in the error message text. This strict syntax requirement is foundational for the compiler to generate code that adheres to the atomic semantics intended by the programmer under the OpenMP specifications.

 
AI Generated

Example

In the following example, an attempt is made to use the OpenMP 'atomic capture' directive in a way that does not conform to the required syntax for such operations. The code tries to simply assign the value of variable x to variable v within an atomic capture region. This usage is incorrect because the statement does not match any of the prescribed forms for an atomic capture operation, such as incrementing, decrementing, or applying a binary operation along with an assignment. The Clang compiler detects this mismatch and emits an error message highlighting the discrepancy, expecting instead a statement that strictly adheres to one of the acceptable patterns. These patterns ensure atomicity and correct semantics for the concurrent modification and capture of variable values as stipulated by OpenMP standards.  
AI Generated


Flags -fopenmp -xc

[Try out in Compiler Explorer]

Source
#include <omp.h>
int main() {
    int x = 0, v = 0;
    #pragma omp atomic capture
    v = x; // Invalid atomic capture
    return 0;
}
Compiler Output
<source>:5:9: error: the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both lvalue expressions with scalar type
<source>:5:9: note: expected built-in binary or unary operator


Clang Internals (17.0.6)

Git Commit Message

[OPENMP] Initial parsing and sema analysis for clause 'capture' in 'atomic' directive.

llvm-svn: 213842

Used in Clang Sources

This section lists all occurrences of the diagnostic within the Clang's codebase. For each occurrence, an auto-extracted snipped from the source code is listed including key elements like control structures, functions, or classes. It should illustrate the conditions under which the diagnostic is activated.

clang/lib/Sema/SemaOpenMP.cpp (line 12772)

StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
  // ...
  // OpenMP [2.12.6, atomic Construct]
  // In the next expressions:
  // * x and v (as applicable) are both l-value expressions with scalar type.
  // * During the execution of an atomic region, multiple syntactic
  // occurrences of x must designate the same storage location.
  // * Neither of v and expr (as applicable) may access the storage location
  // designated by x.
  // * Neither of x and expr (as applicable) may access the storage location
  // designated by v.
  // * expr is an expression with scalar type.
  // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
  // * binop, binop=, ++, and -- are not overloaded operators.
  // * The expression x binop expr must be numerically equivalent to x binop
  // (expr). This requirement is satisfied if the operators in expr have
  // precedence greater than binop, or by using parentheses around expr or
  // subexpressions of expr.
  // * The expression expr binop x must be numerically equivalent to (expr)
  // binop x. This requirement is satisfied if the operators in expr have
  // precedence equal to or greater than binop, or by using parentheses around
  // expr or subexpressions of expr.
  // * For forms that allow multiple occurrences of x, the number of times
  // that x is evaluated is unspecified.
  if (AtomicKind == OMPC_read) {
  // ...
  } else if (AtomicKind == OMPC_write) {
  // ...
  } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
  // ...
  } else if (AtomicKind == OMPC_capture) {
    // ...
    if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
      // ...
      if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
        // ...
        if (Checker.checkStatement(Body, diag::err_omp_atomic_capture_not_expression_statement, diag::note_omp_atomic_update))

clang/lib/Sema/SemaOpenMP.cpp (line 12790)

StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
  // ...
  // OpenMP [2.12.6, atomic Construct]
  // In the next expressions:
  // * x and v (as applicable) are both l-value expressions with scalar type.
  // * During the execution of an atomic region, multiple syntactic
  // occurrences of x must designate the same storage location.
  // * Neither of v and expr (as applicable) may access the storage location
  // designated by x.
  // * Neither of x and expr (as applicable) may access the storage location
  // designated by v.
  // * expr is an expression with scalar type.
  // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
  // * binop, binop=, ++, and -- are not overloaded operators.
  // * The expression x binop expr must be numerically equivalent to x binop
  // (expr). This requirement is satisfied if the operators in expr have
  // precedence greater than binop, or by using parentheses around expr or
  // subexpressions of expr.
  // * The expression expr binop x must be numerically equivalent to (expr)
  // binop x. This requirement is satisfied if the operators in expr have
  // precedence equal to or greater than binop, or by using parentheses around
  // expr or subexpressions of expr.
  // * For forms that allow multiple occurrences of x, the number of times
  // that x is evaluated is unspecified.
  if (AtomicKind == OMPC_read) {
  // ...
  } else if (AtomicKind == OMPC_write) {
  // ...
  } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
  // ...
  } else if (AtomicKind == OMPC_capture) {
    // ...
    if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
      // ...
      if (ErrorFound != NoError) {
        Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) << ErrorRange;

Triggered in Clang Tests

This section lists all internal Clang test cases that trigger the diagnostic.

clang/test/OpenMP/atomic_messages.c

  • clang/test/OpenMP/atomic_messages.c:218:3: error: the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both lvalue expressions with scalar type
  • clang/test/OpenMP/atomic_messages.c:222:7: error: the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both lvalue expressions with scalar type
  • clang/test/OpenMP/atomic_messages.c:226:9: error: the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both lvalue expressions with scalar type
  • clang/test/OpenMP/atomic_messages.c:230:13: error: the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both lvalue expressions with scalar type
  • clang/test/OpenMP/atomic_messages.c:234:16: error: the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both lvalue expressions with scalar type
  • clang/test/OpenMP/atomic_messages.c:238:9: error: the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both lvalue expressions with scalar type
  • clang/test/OpenMP/atomic_messages.c:242:9: error: the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both lvalue expressions with scalar type
  • clang/test/OpenMP/atomic_messages.c:264:20: error: the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both lvalue expressions with scalar type
  • clang/test/OpenMP/atomic_messages.c:268:13: error: the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both lvalue expressions with scalar type
  • clang/test/OpenMP/atomic_messages.c:272:13: error: the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x', where x and v are both lvalue expressions with scalar type