diff options
| author | Alexey Bataev <a.bataev@hotmail.com> | 2018-09-13 16:54:05 +0000 |
|---|---|---|
| committer | Alexey Bataev <a.bataev@hotmail.com> | 2018-09-13 16:54:05 +0000 |
| commit | e6aa4694de2d11fdc3e352a29b1491740bfcb5e5 (patch) | |
| tree | 544278f19137d1f2e4d9ceb4011e0b2ea9093fc8 /clang/lib | |
| parent | 939468d4b278a2432df1ed962fe3ba447b3adafe (diff) | |
| download | bcm5719-llvm-e6aa4694de2d11fdc3e352a29b1491740bfcb5e5.tar.gz bcm5719-llvm-e6aa4694de2d11fdc3e352a29b1491740bfcb5e5.zip | |
[OPENMP] Fix PR38903: Crash on instantiation of the non-dependent
declare reduction.
If the declare reduction construct with the non-dependent type is
defined in the template construct, the compiler might crash on the
template instantition. Reworked the whole instantiation scheme for the
declare reduction constructs to fix this problem correctly.
llvm-svn: 342151
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/CodeGen/CGOpenMPRuntime.cpp | 31 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGOpenMPRuntime.h | 6 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseOpenMP.cpp | 10 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 10 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 79 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 15 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 4 |
7 files changed, 93 insertions, 62 deletions
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 6c37c6cf115..9452e964c15 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -1295,27 +1295,19 @@ void CGOpenMPRuntime::emitUserDefinedReduction( CodeGenFunction *CGF, const OMPDeclareReductionDecl *D) { if (UDRMap.count(D) > 0) return; - ASTContext &C = CGM.getContext(); - if (!In || !Out) { - In = &C.Idents.get("omp_in"); - Out = &C.Idents.get("omp_out"); - } llvm::Function *Combiner = emitCombinerOrInitializer( - CGM, D->getType(), D->getCombiner(), cast<VarDecl>(D->lookup(In).front()), - cast<VarDecl>(D->lookup(Out).front()), + CGM, D->getType(), D->getCombiner(), + cast<VarDecl>(cast<DeclRefExpr>(D->getCombinerIn())->getDecl()), + cast<VarDecl>(cast<DeclRefExpr>(D->getCombinerOut())->getDecl()), /*IsCombiner=*/true); llvm::Function *Initializer = nullptr; if (const Expr *Init = D->getInitializer()) { - if (!Priv || !Orig) { - Priv = &C.Idents.get("omp_priv"); - Orig = &C.Idents.get("omp_orig"); - } Initializer = emitCombinerOrInitializer( CGM, D->getType(), D->getInitializerKind() == OMPDeclareReductionDecl::CallInit ? Init : nullptr, - cast<VarDecl>(D->lookup(Orig).front()), - cast<VarDecl>(D->lookup(Priv).front()), + cast<VarDecl>(cast<DeclRefExpr>(D->getInitOrig())->getDecl()), + cast<VarDecl>(cast<DeclRefExpr>(D->getInitPriv())->getDecl()), /*IsCombiner=*/false); } UDRMap.try_emplace(D, Combiner, Initializer); @@ -8052,19 +8044,19 @@ void CGOpenMPRuntime::scanForTargetRegionsFunctions(const Stmt *S, } bool CGOpenMPRuntime::emitTargetFunctions(GlobalDecl GD) { - const auto *FD = cast<FunctionDecl>(GD.getDecl()); - // If emitting code for the host, we do not process FD here. Instead we do // the normal code generation. if (!CGM.getLangOpts().OpenMPIsDevice) return false; // Try to detect target regions in the function. - scanForTargetRegionsFunctions(FD->getBody(), CGM.getMangledName(GD)); + const ValueDecl *VD = cast<ValueDecl>(GD.getDecl()); + if (const auto *FD = dyn_cast<FunctionDecl>(VD)) + scanForTargetRegionsFunctions(FD->getBody(), CGM.getMangledName(GD)); // Do not to emit function if it is not marked as declare target. - return !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD) && - AlreadyEmittedTargetFunctions.count(FD->getCanonicalDecl()) == 0; + return !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) && + AlreadyEmittedTargetFunctions.count(VD->getCanonicalDecl()) == 0; } bool CGOpenMPRuntime::emitTargetGlobalVariable(GlobalDecl GD) { @@ -8152,7 +8144,8 @@ void CGOpenMPRuntime::registerTargetGlobalVariable(const VarDecl *VD, } bool CGOpenMPRuntime::emitTargetGlobal(GlobalDecl GD) { - if (isa<FunctionDecl>(GD.getDecl())) + if (isa<FunctionDecl>(GD.getDecl()) || + isa<OMPDeclareReductionDecl>(GD.getDecl())) return emitTargetFunctions(GD); return emitTargetGlobalVariable(GD); diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h index 46fa774f2ae..e0685d9bc66 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.h +++ b/clang/lib/CodeGen/CGOpenMPRuntime.h @@ -315,10 +315,6 @@ private: SmallVector<const OMPDeclareReductionDecl *, 4>> FunctionUDRMapTy; FunctionUDRMapTy FunctionUDRMap; - IdentifierInfo *In = nullptr; - IdentifierInfo *Out = nullptr; - IdentifierInfo *Priv = nullptr; - IdentifierInfo *Orig = nullptr; /// Type kmp_critical_name, originally defined as typedef kmp_int32 /// kmp_critical_name[8]; llvm::ArrayType *KmpCriticalNameTy; @@ -600,7 +596,7 @@ private: OffloadEntriesInfoManagerTy OffloadEntriesInfoManager; bool ShouldMarkAsGlobal = true; - llvm::SmallDenseSet<const FunctionDecl *> AlreadyEmittedTargetFunctions; + llvm::SmallDenseSet<const Decl *> AlreadyEmittedTargetFunctions; /// List of variables that can become declare target implicitly and, thus, /// must be emitted. diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 9871e5bbf9f..cdcbf797678 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -353,8 +353,14 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) { // Check if initializer is omp_priv <init_expr> or something else. if (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->isStr("omp_priv")) { - ConsumeToken(); - ParseOpenMPReductionInitializerForDecl(OmpPrivParm); + if (Actions.getLangOpts().CPlusPlus) { + InitializerResult = Actions.ActOnFinishFullExpr( + ParseAssignmentExpression().get(), D->getLocation(), + /*DiscardedValue=*/true); + } else { + ConsumeToken(); + ParseOpenMPReductionInitializerForDecl(OmpPrivParm); + } } else { InitializerResult = Actions.ActOnFinishFullExpr( ParseAssignmentExpression().get(), D->getLocation(), diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 7287194683d..ffcb4ba2de5 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -12763,6 +12763,11 @@ void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { DRD->addDecl(OmpInParm); DRD->addDecl(OmpOutParm); } + Expr *InE = + ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); + Expr *OutE = + ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); + DRD->setCombinerData(InE, OutE); } void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { @@ -12818,6 +12823,11 @@ VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { DRD->addDecl(OmpPrivParm); DRD->addDecl(OmpOrigParm); } + Expr *OrigE = + ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); + Expr *PrivE = + ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); + DRD->setInitializerData(OrigE, PrivE); return OmpPrivParm; } diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 2c29b8cbcc1..09aa25ca0a2 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2733,10 +2733,19 @@ Decl *TemplateDeclInstantiator::VisitOMPThreadPrivateDecl( Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl( OMPDeclareReductionDecl *D) { // Instantiate type and check if it is allowed. - QualType SubstReductionType = SemaRef.ActOnOpenMPDeclareReductionType( - D->getLocation(), - ParsedType::make(SemaRef.SubstType(D->getType(), TemplateArgs, - D->getLocation(), DeclarationName()))); + const bool RequiresInstantiation = + D->getType()->isDependentType() || + D->getType()->isInstantiationDependentType() || + D->getType()->containsUnexpandedParameterPack(); + QualType SubstReductionType; + if (RequiresInstantiation) { + SubstReductionType = SemaRef.ActOnOpenMPDeclareReductionType( + D->getLocation(), + ParsedType::make(SemaRef.SubstType( + D->getType(), TemplateArgs, D->getLocation(), DeclarationName()))); + } else { + SubstReductionType = D->getType(); + } if (SubstReductionType.isNull()) return nullptr; bool IsCorrect = !SubstReductionType.isNull(); @@ -2753,25 +2762,35 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl( /*S=*/nullptr, Owner, D->getDeclName(), ReductionTypes, D->getAccess(), PrevDeclInScope); auto *NewDRD = cast<OMPDeclareReductionDecl>(DRD.get().getSingleDecl()); - if (isDeclWithinFunction(NewDRD)) - SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewDRD); + SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewDRD); + if (!RequiresInstantiation) { + if (Expr *Combiner = D->getCombiner()) { + NewDRD->setCombinerData(D->getCombinerIn(), D->getCombinerOut()); + NewDRD->setCombiner(Combiner); + if (Expr *Init = D->getInitializer()) { + NewDRD->setInitializerData(D->getInitOrig(), D->getInitPriv()); + NewDRD->setInitializer(Init, D->getInitializerKind()); + } + } + (void)SemaRef.ActOnOpenMPDeclareReductionDirectiveEnd( + /*S=*/nullptr, DRD, IsCorrect && !D->isInvalidDecl()); + return NewDRD; + } Expr *SubstCombiner = nullptr; Expr *SubstInitializer = nullptr; // Combiners instantiation sequence. if (D->getCombiner()) { SemaRef.ActOnOpenMPDeclareReductionCombinerStart( /*S=*/nullptr, NewDRD); - const char *Names[] = {"omp_in", "omp_out"}; - for (auto &Name : Names) { - DeclarationName DN(&SemaRef.Context.Idents.get(Name)); - auto OldLookup = D->lookup(DN); - auto Lookup = NewDRD->lookup(DN); - if (!OldLookup.empty() && !Lookup.empty()) { - assert(Lookup.size() == 1 && OldLookup.size() == 1); - SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldLookup.front(), - Lookup.front()); - } - } + SemaRef.CurrentInstantiationScope->InstantiatedLocal( + cast<DeclRefExpr>(D->getCombinerIn())->getDecl(), + cast<DeclRefExpr>(NewDRD->getCombinerIn())->getDecl()); + SemaRef.CurrentInstantiationScope->InstantiatedLocal( + cast<DeclRefExpr>(D->getCombinerOut())->getDecl(), + cast<DeclRefExpr>(NewDRD->getCombinerOut())->getDecl()); + auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(Owner); + Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, /*TypeQuals*/ 0, + ThisContext); SubstCombiner = SemaRef.SubstExpr(D->getCombiner(), TemplateArgs).get(); SemaRef.ActOnOpenMPDeclareReductionCombinerEnd(NewDRD, SubstCombiner); // Initializers instantiation sequence. @@ -2779,19 +2798,12 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl( VarDecl *OmpPrivParm = SemaRef.ActOnOpenMPDeclareReductionInitializerStart( /*S=*/nullptr, NewDRD); - const char *Names[] = {"omp_orig", "omp_priv"}; - for (auto &Name : Names) { - DeclarationName DN(&SemaRef.Context.Idents.get(Name)); - auto OldLookup = D->lookup(DN); - auto Lookup = NewDRD->lookup(DN); - if (!OldLookup.empty() && !Lookup.empty()) { - assert(Lookup.size() == 1 && OldLookup.size() == 1); - auto *OldVD = cast<VarDecl>(OldLookup.front()); - auto *NewVD = cast<VarDecl>(Lookup.front()); - SemaRef.InstantiateVariableInitializer(NewVD, OldVD, TemplateArgs); - SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldVD, NewVD); - } - } + SemaRef.CurrentInstantiationScope->InstantiatedLocal( + cast<DeclRefExpr>(D->getInitOrig())->getDecl(), + cast<DeclRefExpr>(NewDRD->getInitOrig())->getDecl()); + SemaRef.CurrentInstantiationScope->InstantiatedLocal( + cast<DeclRefExpr>(D->getInitPriv())->getDecl(), + cast<DeclRefExpr>(NewDRD->getInitPriv())->getDecl()); if (D->getInitializerKind() == OMPDeclareReductionDecl::CallInit) { SubstInitializer = SemaRef.SubstExpr(D->getInitializer(), TemplateArgs).get(); @@ -2808,8 +2820,9 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl( SubstInitializer) || (D->getInitializerKind() != OMPDeclareReductionDecl::CallInit && !SubstInitializer && !SubstInitializer)); - } else + } else { IsCorrect = false; + } (void)SemaRef.ActOnOpenMPDeclareReductionDirectiveEnd(/*S=*/nullptr, DRD, IsCorrect); @@ -4897,7 +4910,9 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, return D; if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D) || isa<TemplateTemplateParmDecl>(D) || - (ParentDC->isFunctionOrMethod() && ParentDC->isDependentContext()) || + ((ParentDC->isFunctionOrMethod() || + isa<OMPDeclareReductionDecl>(ParentDC)) && + ParentDC->isDependentContext()) || (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda())) { // D is a local of some kind. Look into the map of local // declarations to their instantiations. diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 82951074764..d06a6226af7 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2633,10 +2633,17 @@ void ASTDeclReader::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) { void ASTDeclReader::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) { VisitValueDecl(D); D->setLocation(ReadSourceLocation()); - D->setCombiner(Record.readExpr()); - D->setInitializer( - Record.readExpr(), - static_cast<OMPDeclareReductionDecl::InitKind>(Record.readInt())); + Expr *In = Record.readExpr(); + Expr *Out = Record.readExpr(); + D->setCombinerData(In, Out); + Expr *Combiner = Record.readExpr(); + D->setCombiner(Combiner); + Expr *Orig = Record.readExpr(); + Expr *Priv = Record.readExpr(); + D->setInitializerData(Orig, Priv); + Expr *Init = Record.readExpr(); + auto IK = static_cast<OMPDeclareReductionDecl::InitKind>(Record.readInt()); + D->setInitializer(Init, IK); D->PrevDeclInScope = ReadDeclID(); } diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 8eb6c61525d..d757f609ea2 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -1742,7 +1742,11 @@ void ASTDeclWriter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) { void ASTDeclWriter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) { VisitValueDecl(D); Record.AddSourceLocation(D->getBeginLoc()); + Record.AddStmt(D->getCombinerIn()); + Record.AddStmt(D->getCombinerOut()); Record.AddStmt(D->getCombiner()); + Record.AddStmt(D->getInitOrig()); + Record.AddStmt(D->getInitPriv()); Record.AddStmt(D->getInitializer()); Record.push_back(D->getInitializerKind()); Record.AddDeclRef(D->getPrevDeclInScope()); |

