Clang error: the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an lvalue expression with scalar type (err_omp_atomic_capture_not_compound_statement)

From emmtrix Wiki
Jump to navigation Jump to search
Text error: the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an lvalue expression with scalar type (since 12.0)
error: the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type (until 11.1)
Type Error
Category OpenMP Issue
Internal Id err_omp_atomic_capture_not_compound_statement
Internal Message the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an lvalue expression with scalar type (since 12.0)
the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an l-value expression with scalar type (until 11.1)
Regular Expression (?:error|fatal error)\: the statement for 'atomic capture' must be a compound statement of form '\{v \= x; x binop\= expr;\}', '\{x binop\= expr; v \= x;\}', '\{v \= x; x \= x binop expr;\}', '\{v \= x; x \= expr binop x;\}', '\{x \= x binop expr; v \= x;\}', '\{x \= expr binop x; v \= x;\}' or '\{v \= x; x \= expr;\}', '\{v \= x; x\+\+;\}', '\{v \= x; \+\+x;\}', '\{\+\+x; v \= x;\}', '\{x\+\+; v \= x;\}', '\{v \= x; x\-\-;\}', '\{v \= x; \-\-x;\}', '\{\-\-x; v \= x;\}', '\{x\-\-; v \= x;\}' where x is an lvalue expression 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 a programmer attempts to use the 'atomic capture' directive in a manner that does not comply with the specific syntactical requirements set by the OpenMP specification for parallel programming. Specifically, this happens when the statement for 'atomic capture' is not a compound statement that conforms to one of several predefined forms. This compound statement must be structured in such a way that it assigns a value to a variable (denoted as "v" in the error message) from another variable (denoted as "x"), followed or preceded by an operation on "x". These operations can include binary operations combined with an assignment (binop=), increment (++), or decrement (--) operations.

The error ensures that the operations performed within the 'atomic capture' directive are executed atomically, thus preventing race conditions on "x" among multiple threads. The 'atomic capture' directive is used to ensure that during the execution of the compound statement, the value of "x" is not changed by other threads between the two operations encapsulated within the compound block.

The correct form of the compound statement depends on whether the value of "x" needs to be captured before or after applying the binary operation, or increment/decrement operation. This includes forms where "v" captures the value of "x" either before or after the modification, as well as forms that directly modify "x" with a binary operation involving itself and another expression (expr).

These restrictions are in place to ensure that the operations maintain atomicity and are predictable in a multi-threaded environment, as specified since OpenMP version 12.0. The behavior remains consistent until version 11.1, with minor differences in the expression of the error message regarding the representation of types.

 
AI Generated

Example

In the following example, an attempt is made to use the OpenMP 'atomic capture' directive in C++. The directive is used incorrectly because it encapsulates a statement not conforming to the required syntactical structures specified for 'atomic capture'. Specifically, the example fails because the 'atomic capture' requires a compound statement that correctly performs an atomic operation coupled with the assignment of one variable's value to another, but only a simple increment and assignment is provided without adhering to the prescribed compound statement formats. The Clang compiler identifies this misuse, resulting in an error message indicating the correct form that the statement should take to comply with the 'atomic capture' directive's requirements. The error message precisely lists the acceptable compound statement forms, ensuring that the operations within the 'atomic capture' are executed atomically to prevent race conditions. This clarification by the compiler is intended to help in correcting the code to ensure atomicity and proper synchronization among threads when performing 'atomic capture' operations.  
AI Generated


Flags -fopenmp -xc

[Try out in Compiler Explorer]

Source
#include <omp.h>
int main() {
    int x = 0, v = 0;
    #pragma omp parallel
    #pragma omp atomic capture
    {v = x++;} // Incorrect usage
    return 0;
}
Compiler Output
<source>:6:5: error: the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an lvalue expression with scalar type
<source>:6:5: note: expected exactly two expression statements


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 12953)

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 (ErrorFound != NoError) {
      Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_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:214:3: error: the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an lvalue expression with scalar type
  • clang/test/OpenMP/atomic_messages.c:246:3: error: the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an lvalue expression with scalar type
  • clang/test/OpenMP/atomic_messages.c:250:3: error: the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an lvalue expression with scalar type
  • clang/test/OpenMP/atomic_messages.c:254:6: error: the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an lvalue expression with scalar type
  • clang/test/OpenMP/atomic_messages.c:258:6: error: the statement for 'atomic capture' must be a compound statement of form '{v = x; x binop= expr;}', '{x binop= expr; v = x;}', '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}', '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}' where x is an lvalue expression with scalar type