From a9036f2eb42d2311d84198868e9e8ff060c79a95 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Fri, 26 Nov 2021 07:36:25 -0800 Subject: [PATCH] [OPENMP]Fix error emission for dependent expressions in iterators for depend clauses. Need to postpone analysis for addressable lvalue in a depend clause with iterators, otherwise the incorrect error message is emitted. Differential Revision: https://reviews.llvm.org/D114653 --- clang/lib/Sema/SemaOpenMP.cpp | 19 ++++++------- .../OpenMP/target_enter_data_depend_messages.cpp | 2 +- .../OpenMP/target_exit_data_depend_messages.cpp | 2 +- .../test/OpenMP/target_update_depend_messages.cpp | 2 +- .../OpenMP/task_depend_template_call_ast_print.cpp | 31 ++++++++++++++++++++++ 5 files changed, 42 insertions(+), 14 deletions(-) create mode 100644 clang/test/OpenMP/task_depend_template_call_ast_print.cpp diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 22ae5f5..b9b0005 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -18636,22 +18636,19 @@ Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && !RefExpr->isInstantiationDependent() && !RefExpr->containsUnexpandedParameterPack() && - (OMPDependTFound && - DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) { + (!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) << 1 - << RefExpr->getSourceRange(); + << (LangOpts.OpenMP >= 50 ? 1 : 0) + << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); continue; } auto *ASE = dyn_cast(SimpleExpr); - if (!RefExpr->IgnoreParenImpCasts()->isLValue() || - (ASE && !ASE->getBase()->isTypeDependent() && - !ASE->getBase() - ->getType() - .getNonReferenceType() - ->isPointerType() && - !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { + 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(); diff --git a/clang/test/OpenMP/target_enter_data_depend_messages.cpp b/clang/test/OpenMP/target_enter_data_depend_messages.cpp index 4b28067..8f3994f 100644 --- a/clang/test/OpenMP/target_enter_data_depend_messages.cpp +++ b/clang/test/OpenMP/target_enter_data_depend_messages.cpp @@ -46,7 +46,7 @@ int tmain(T argc, S **argv, R *env[]) { foo(); #pragma omp target enter data map(to: i) depend (out :S1) // expected-error {{'S1' does not refer to a value}} foo(); -#pragma omp target enter data map(to : i) depend(in : argv[1][1] = '2') // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} +#pragma omp target enter data map(to : i) depend(in : argv[1][1] = '2') foo(); #pragma omp target enter data map(to : i) depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); diff --git a/clang/test/OpenMP/target_exit_data_depend_messages.cpp b/clang/test/OpenMP/target_exit_data_depend_messages.cpp index a1bcdb0..2bb64c4 100644 --- a/clang/test/OpenMP/target_exit_data_depend_messages.cpp +++ b/clang/test/OpenMP/target_exit_data_depend_messages.cpp @@ -46,7 +46,7 @@ int tmain(T argc, S **argv, R *env[]) { foo(); #pragma omp target exit data map(from: i) depend (out :S1) // expected-error {{'S1' does not refer to a value}} foo(); -#pragma omp target exit data map(from : i) depend(in : argv[1][1] = '2') // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} +#pragma omp target exit data map(from : i) depend(in : argv[1][1] = '2') foo(); #pragma omp target exit data map(from : i) depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); diff --git a/clang/test/OpenMP/target_update_depend_messages.cpp b/clang/test/OpenMP/target_update_depend_messages.cpp index b218d4d..949b122 100644 --- a/clang/test/OpenMP/target_update_depend_messages.cpp +++ b/clang/test/OpenMP/target_update_depend_messages.cpp @@ -39,7 +39,7 @@ int tmain(T argc, S **argv, R *env[]) { #pragma omp target update to(z) depend(out:) // expected-error {{expected expression}} #pragma omp target update to(z) depend(inout : foobool(argc)), depend(in, argc) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} #pragma omp target update to(z) depend(out : S1) // expected-error {{'S1' does not refer to a value}} -#pragma omp target update to(z) depend(in : argv[1][1] = '2') // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} +#pragma omp target update to(z) depend(in : argv[1][1] = '2') #pragma omp target update to(z) depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} #pragma omp target update to(z) depend(in : argv[0]) #pragma omp target update to(z) depend(in:) // expected-error {{expected expression}} diff --git a/clang/test/OpenMP/task_depend_template_call_ast_print.cpp b/clang/test/OpenMP/task_depend_template_call_ast_print.cpp new file mode 100644 index 0000000..3456f7b --- /dev/null +++ b/clang/test/OpenMP/task_depend_template_call_ast_print.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +template class vector { +public: + int &at(long); +}; + +// CHECK: template void foo(int n) { +// CHECK-NEXT: vector v; +// CHECK-NEXT: vector iv1; +// CHECK-NEXT: #pragma omp task depend(iterator(int i = 0:n), in : v.at(i),iv1.at(i)) +// CHECK-NEXT: ; +// CHECK-NEXT: } + +template void foo(int n) { + vector v; + vector iv1; +#pragma omp task depend(iterator(i = 0 : n), in : v.at(i), iv1.at(i)) + ; +} +#endif -- 2.7.4