From b7a9b746b4b78d03f16d4f0d581886665bd4626b Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Tue, 5 Dec 2017 19:20:09 +0000 Subject: [PATCH] [OPENMP] Fix implicit mapping analysis. Fixed processing of implicitly mapped objects in target-based executable directives. llvm-svn: 319814 --- clang/lib/Sema/SemaOpenMP.cpp | 77 ++++++++++++++--------- clang/test/OpenMP/target_map_messages.cpp | 10 ++- 2 files changed, 56 insertions(+), 31 deletions(-) diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index fa861b46339e..a06dd8c32a4e 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -38,7 +38,7 @@ using namespace clang; static Expr *CheckMapClauseExpressionBase( Sema &SemaRef, Expr *E, OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, - OpenMPClauseKind CKind); + OpenMPClauseKind CKind, bool NoDiagnose); namespace { /// \brief Default data sharing attributes, which can be applied to directive. @@ -1932,10 +1932,10 @@ public: E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) return; auto *FD = dyn_cast(E->getMemberDecl()); - if (!FD) - return; OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); if (isa(E->getBase()->IgnoreParens())) { + if (!FD) + return; auto DVar = Stack->getTopDSA(FD, false); // Check if the variable has explicit DSA set and stop analysis if it // so. @@ -1958,12 +1958,8 @@ public: // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] // A bit-field cannot appear in a map clause. // - if (FD->isBitField()) { - SemaRef.Diag(E->getMemberLoc(), - diag::err_omp_bit_fields_forbidden_in_clause) - << E->getSourceRange() << getOpenMPClauseName(OMPC_map); + if (FD->isBitField()) return; - } ImplicitMap.emplace_back(E); return; } @@ -1994,9 +1990,10 @@ public: ImplicitFirstprivate.push_back(E); return; } - if (isOpenMPTargetExecutionDirective(DKind) && !FD->isBitField()) { + if (isOpenMPTargetExecutionDirective(DKind)) { OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; - if (!CheckMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map)) + if (!CheckMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, + /*NoDiagnose=*/true)) return; auto *VD = cast( CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); @@ -11418,7 +11415,7 @@ static bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, static Expr *CheckMapClauseExpressionBase( Sema &SemaRef, Expr *E, OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, - OpenMPClauseKind CKind) { + OpenMPClauseKind CKind, bool NoDiagnose) { SourceLocation ELoc = E->getExprLoc(); SourceRange ERange = E->getSourceRange(); @@ -11489,9 +11486,14 @@ static Expr *CheckMapClauseExpressionBase( E = BaseE; if (!isa(CurE->getMemberDecl())) { - SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) - << CurE->getSourceRange(); - return nullptr; + if (!NoDiagnose) { + SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) + << CurE->getSourceRange(); + return nullptr; + } + if (RelevantExpr) + return nullptr; + continue; } auto *FD = cast(CurE->getMemberDecl()); @@ -11500,9 +11502,14 @@ static Expr *CheckMapClauseExpressionBase( // A bit-field cannot appear in a map clause. // if (FD->isBitField()) { - SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) - << CurE->getSourceRange() << getOpenMPClauseName(CKind); - return nullptr; + if (!NoDiagnose) { + SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) + << CurE->getSourceRange() << getOpenMPClauseName(CKind); + return nullptr; + } + if (RelevantExpr) + return nullptr; + continue; } // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] @@ -11514,12 +11521,16 @@ static Expr *CheckMapClauseExpressionBase( // A list item cannot be a variable that is a member of a structure with // a union type. // - if (auto *RT = CurType->getAs()) + if (auto *RT = CurType->getAs()) { if (RT->isUnionType()) { - SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) - << CurE->getSourceRange(); - return nullptr; + if (!NoDiagnose) { + SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) + << CurE->getSourceRange(); + return nullptr; + } + continue; } + } // If we got a member expression, we should not expect any array section // before that: @@ -11537,9 +11548,12 @@ static Expr *CheckMapClauseExpressionBase( E = CurE->getBase()->IgnoreParenImpCasts(); if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { - SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) - << 0 << CurE->getSourceRange(); - return nullptr; + if (!NoDiagnose) { + SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) + << 0 << CurE->getSourceRange(); + return nullptr; + } + continue; } // If we got an array subscript that express the whole dimension we @@ -11552,6 +11566,7 @@ static Expr *CheckMapClauseExpressionBase( // Record the component - we don't have any declaration associated. CurComponents.emplace_back(CurE, nullptr); } else if (auto *CurE = dyn_cast(E)) { + assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); E = CurE->getBase()->IgnoreParenImpCasts(); QualType CurType = @@ -11597,10 +11612,12 @@ static Expr *CheckMapClauseExpressionBase( // Record the component - we don't have any declaration associated. CurComponents.emplace_back(CurE, nullptr); } else { - // If nothing else worked, this is not a valid map clause expression. - SemaRef.Diag(ELoc, - diag::err_omp_expected_named_var_member_or_array_expression) - << ERange; + if (!NoDiagnose) { + // If nothing else worked, this is not a valid map clause expression. + SemaRef.Diag( + ELoc, diag::err_omp_expected_named_var_member_or_array_expression) + << ERange; + } return nullptr; } } @@ -11893,8 +11910,8 @@ checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, // Obtain the array or member expression bases if required. Also, fill the // components array with all the components identified in the process. - auto *BE = - CheckMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind); + auto *BE = CheckMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, + CKind, /*NoDiagnose=*/false); if (!BE) continue; diff --git a/clang/test/OpenMP/target_map_messages.cpp b/clang/test/OpenMP/target_map_messages.cpp index 52a492920fbb..0850d27f228a 100644 --- a/clang/test/OpenMP/target_map_messages.cpp +++ b/clang/test/OpenMP/target_map_messages.cpp @@ -26,7 +26,14 @@ struct SA { T d; float e[I]; T *f; + int bf : 20; void func(int arg) { + #pragma omp target + { + a = 0.0; + func(arg); + bf = 20; + } #pragma omp target map(arg,a,d) {} #pragma omp target map(arg[2:2],a,d) // expected-error {{subscripted value is not an array or pointer}} @@ -271,7 +278,8 @@ void SAclient(int arg) { {} #pragma omp target { - u.B = 0; // expected-error {{mapped storage cannot be derived from a union}} + u.B = 0; + r.S.foo(); } #pragma omp target data map(to: r.C) //expected-note {{used here}}