Clang error: expected addressable lvalue expression, array element...... (err_omp_expected_addressable_lvalue_or_array_item)

From emmtrix Wiki
Jump to navigation Jump to search
Text
error: expected addressable lvalue expression, array element
or array section
, array section or array shaping expression
 
of non 'omp_depend_t' type

(since 11.0)
error: expected addressable lvalue expression, array element or array section (6.0 - 10.0)

Type Error
Category OpenMP Issue (since 6.0)
Internal Id err_omp_expected_addressable_lvalue_or_array_item (since 6.0)
Internal Message expected addressable lvalue expression, array element%select{ or array section|, array section or array shaping expression}0%select{| of non 'omp_depend_t' type}1 (since 11.0)
expected addressable lvalue expression, array element or array section (6.0 - 10.0)
Regular Expression (?:error|fatal error)\: expected addressable lvalue expression, array element(?: or array section|, array section or array shaping expression)(?:| of non 'omp_depend_t' type)
First Commit 2017-07-27 463a9fea1ec2 [OPENMP] Allow all lvalues in 'depend' clause.

Description

The error is issued by the Clang compiler when it encounters an expression that it cannot treat as an addressable lvalue within certain OpenMP constructs. These constructs require expressions that can be addressed directly in memory, as they involve dependencies or memory locations that the runtime must track or modify. Specifically, this error message relates to the use of array elements, array sections, or array shaping expressions in OpenMP clauses that do not evaluate to addressable lvalues or when such expressions are of an incorrect type, notably not of the 'omp_depend_t' type when required by the context. This situation can arise in various OpenMP directives that manage dependencies among tasks or dictate how data is shared or partitioned across tasks and threads. The requirement for expressions to be addressable lvalues ensures that the runtime can accurately determine dependencies or how data should be appropriately accessed or modified during parallel execution.  
AI Generated

Example

In the following example, two common mistakes that can lead to the Clang error message concerning expected addressable lvalue expressions within OpenMP constructs are showcased. The example begins with a demonstration of a parallel region that includes a single directive, within which a task is defined. This task attempts to use the omp_get_thread_num() function within its depend clause to specify a dependency. However, the result of omp_get_thread_num() is not an lvalue (an object that occupies a specific location in memory, such as a variable), leading to the issuance of the first error. This error explicates the expectation for an addressable lvalue expression, array element, array section, or array shaping expression of a non 'omp_depend_t' type.

Subsequently, an attempt is made to nest a loop marked for SIMD parallelization with a for simd directive inside a taskloop simd directive. Both directives are designed to facilitate loop parallelization but are not suitable for mutual nesting. This improper nesting results in an error because it violates the structured block requirements of OpenMP, particularly the rule against nesting certain OpenMP constructs within a SIMD region, excluding a few allowed directives. Overall, the first error stresses the necessity for dependencies to be based on addressable memory locations, while the second error highlights the restrictions on combining specific OpenMP directives.

 
AI Generated


Flags -xc++ -fopenmp

[Try out in Compiler Explorer]

Source
#include <omp.h>
int main() {
  // omp_get_thread_num() is not an lvalue
  #pragma omp parallel
  {
  #pragma omp single
  {
  #pragma omp task depend(inout: omp_get_thread_num())
  }
  }
  // Mixing omp for simd and omp taskloop simd incorrectly
  #pragma omp for simd
  for(int i = 0; i < 10; ++i) {
  #pragma omp taskloop simd
  for(int j = 0; j < 10; ++j) {
  }
  }
  return 0;
}
Compiler Output
<source>:8:34: error: expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type
<source>:9:3: error: expected statement
<source>:14:3: error: OpenMP constructs may not be nested inside a simd region except for ordered simd, simd, scan, or atomic directive


Clang Internals (17.0.6)

Git Commit Message

[OPENMP] Allow all lvalues in 'depend' clause.

According to upcoming OpenMP 5.0 all addressable lvalue expressions are
allowed in deoend clause.

llvm-svn: 309309

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

OMPClause *Sema::ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data, Expr *DepModifier, ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
  // ...
  if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
  // ...
  } else {
    for (Expr *RefExpr : VarList) {
      // ...
      if (DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) {
        // ...
        if (DepKind == OMPC_DEPEND_depobj) {
        // ...
        } else {
          // ...
          // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
          // List items used in depend clauses with the in, out, inout,
          // inoutset, or mutexinoutset dependence types cannot be
          // expressions of the omp_depend_t type.
          if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && !RefExpr->isInstantiationDependent() && !RefExpr->containsUnexpandedParameterPack() && (!RefExpr->IgnoreParenImpCasts()->isLValue() || (OMPDependTFound && DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr()))) {
            Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) << (LangOpts.OpenMP >= 50 ? 1 : 0) << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();

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

OMPClause *Sema::ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data, Expr *DepModifier, ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
  // ...
  if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
  // ...
  } else {
    for (Expr *RefExpr : VarList) {
      // ...
      if (DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) {
        // ...
        if (DepKind == OMPC_DEPEND_depobj) {
        // ...
        } else {
          // ...
          if (ASE && !ASE->getBase()->isTypeDependent() && !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) {
            Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) << (LangOpts.OpenMP >= 50 ? 1 : 0) << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();

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

OMPClause *Sema::ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data, Expr *DepModifier, ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
  // ...
  if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
  // ...
  } else {
    for (Expr *RefExpr : VarList) {
      // ...
      if (DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) {
        // ...
        if (DepKind == OMPC_DEPEND_depobj) {
        // ...
        } else {
          // ...
          if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && !isa<OMPArrayShapingExpr>(SimpleExpr)) {
            Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) << (LangOpts.OpenMP >= 50 ? 1 : 0) << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();

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

OMPClause *Sema::ActOnOpenMPAffinityClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
  // ...
  for (Expr *RefExpr : Locators) {
    // ...
    if (!SimpleExpr->isLValue()) {
      Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) << 1 << 0 << RefExpr->getSourceRange();

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

OMPClause *Sema::ActOnOpenMPAffinityClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
  // ...
  for (Expr *RefExpr : Locators) {
    // ...
    if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && !isa<OMPArrayShapingExpr>(SimpleExpr)) {
      Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) << 1 << 0 << RefExpr->getSourceRange();

Triggered in Clang Tests

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

clang/test/OpenMP/taskwait_depend_messages.cpp

  • clang/test/OpenMP/taskwait_depend_messages.cpp:36:40: error: expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type
  • clang/test/OpenMP/taskwait_depend_messages.cpp:40:37: error: expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type
  • clang/test/OpenMP/taskwait_depend_messages.cpp:44:36: error: expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type