diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/AnalysisBasedWarnings.cpp | 10 | ||||
-rw-r--r-- | lib/Sema/SemaCoroutine.cpp | 13 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 96 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 14 | ||||
-rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 97 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 60 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 72 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 13 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 13 |
13 files changed, 232 insertions, 176 deletions
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index 5953d020b4fb..a987a8ce0b31 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -56,6 +56,8 @@ using namespace clang; namespace { class UnreachableCodeHandler : public reachable_code::Callback { Sema &S; + SourceRange PreviousSilenceableCondVal; + public: UnreachableCodeHandler(Sema &s) : S(s) {} @@ -64,6 +66,14 @@ namespace { SourceRange SilenceableCondVal, SourceRange R1, SourceRange R2) override { + // Avoid reporting multiple unreachable code diagnostics that are + // triggered by the same conditional value. + if (PreviousSilenceableCondVal.isValid() && + SilenceableCondVal.isValid() && + PreviousSilenceableCondVal == SilenceableCondVal) + return; + PreviousSilenceableCondVal = SilenceableCondVal; + unsigned diag = diag::warn_unreachable; switch (UK) { case reachable_code::UK_Break: diff --git a/lib/Sema/SemaCoroutine.cpp b/lib/Sema/SemaCoroutine.cpp index 3109358df464..9814b4a84f29 100644 --- a/lib/Sema/SemaCoroutine.cpp +++ b/lib/Sema/SemaCoroutine.cpp @@ -187,7 +187,7 @@ static FunctionScopeInfo *checkCoroutineContext(Sema &S, SourceLocation Loc, S.Context.getTrivialTypeSourceInfo(T, Loc), SC_None); S.CheckVariableDeclarationType(ScopeInfo->CoroutinePromise); if (!ScopeInfo->CoroutinePromise->isInvalidDecl()) - S.ActOnUninitializedDecl(ScopeInfo->CoroutinePromise, false); + S.ActOnUninitializedDecl(ScopeInfo->CoroutinePromise); } return ScopeInfo; @@ -578,17 +578,6 @@ void Sema::CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body) { isa<CoyieldExpr>(First) ? 1 : 2); } - bool AnyCoawaits = false; - bool AnyCoyields = false; - for (auto *CoroutineStmt : Fn->CoroutineStmts) { - AnyCoawaits |= isa<CoawaitExpr>(CoroutineStmt); - AnyCoyields |= isa<CoyieldExpr>(CoroutineStmt); - } - - if (!AnyCoawaits && !AnyCoyields) - Diag(Fn->CoroutineStmts.front()->getLocStart(), - diag::ext_coroutine_without_co_await_co_yield); - SourceLocation Loc = FD->getLocation(); // Form a declaration statement for the promise declaration, so that AST diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index c32757565dd1..adcf2ee00e75 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1044,7 +1044,8 @@ Corrected: } // We can have a type template here if we're classifying a template argument. - if (isa<TemplateDecl>(FirstDecl) && !isa<FunctionTemplateDecl>(FirstDecl)) + if (isa<TemplateDecl>(FirstDecl) && !isa<FunctionTemplateDecl>(FirstDecl) && + !isa<VarTemplateDecl>(FirstDecl)) return NameClassification::TypeTemplate( TemplateName(cast<TemplateDecl>(FirstDecl))); @@ -4503,7 +4504,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, // trivial in almost all cases, except if a union member has an in-class // initializer: // union { int n = 0; }; - ActOnUninitializedDecl(Anon, /*TypeMayContainAuto=*/false); + ActOnUninitializedDecl(Anon); } Anon->setImplicit(); @@ -6425,9 +6426,10 @@ NamedDecl *Sema::ActOnVariableDeclarator( } } - // Diagnose shadowed variables before filtering for scope. - if (D.getCXXScopeSpec().isEmpty()) - CheckShadow(S, NewVD, Previous); + // Find the shadowed declaration before filtering for scope. + NamedDecl *ShadowedDecl = D.getCXXScopeSpec().isEmpty() + ? getShadowedDeclaration(NewVD, Previous) + : nullptr; // Don't consider existing declarations that are in a different // scope and are out-of-semantic-context declarations (if the new @@ -6522,6 +6524,10 @@ NamedDecl *Sema::ActOnVariableDeclarator( } } + // Diagnose shadowed variables iff this isn't a redeclaration. + if (ShadowedDecl && !D.isRedeclaration()) + CheckShadow(NewVD, ShadowedDecl, Previous); + ProcessPragmaWeak(S, NewVD); // If this is the first declaration of an extern C variable, update @@ -6595,33 +6601,40 @@ static SourceLocation getCaptureLocation(const LambdaScopeInfo *LSI, return SourceLocation(); } -/// \brief Diagnose variable or built-in function shadowing. Implements -/// -Wshadow. -/// -/// This method is called whenever a VarDecl is added to a "useful" -/// scope. -/// -/// \param S the scope in which the shadowing name is being declared -/// \param R the lookup of the name -/// -void Sema::CheckShadow(Scope *S, VarDecl *D, const LookupResult& R) { +/// \brief Return the declaration shadowed by the given variable \p D, or null +/// if it doesn't shadow any declaration or shadowing warnings are disabled. +NamedDecl *Sema::getShadowedDeclaration(const VarDecl *D, + const LookupResult &R) { // Return if warning is ignored. if (Diags.isIgnored(diag::warn_decl_shadow, R.getNameLoc())) - return; + return nullptr; // Don't diagnose declarations at file scope. if (D->hasGlobalStorage()) - return; - - DeclContext *NewDC = D->getDeclContext(); + return nullptr; // Only diagnose if we're shadowing an unambiguous field or variable. if (R.getResultKind() != LookupResult::Found) - return; + return nullptr; - NamedDecl* ShadowedDecl = R.getFoundDecl(); - if (!isa<VarDecl>(ShadowedDecl) && !isa<FieldDecl>(ShadowedDecl)) - return; + NamedDecl *ShadowedDecl = R.getFoundDecl(); + return isa<VarDecl>(ShadowedDecl) || isa<FieldDecl>(ShadowedDecl) + ? ShadowedDecl + : nullptr; +} + +/// \brief Diagnose variable or built-in function shadowing. Implements +/// -Wshadow. +/// +/// This method is called whenever a VarDecl is added to a "useful" +/// scope. +/// +/// \param ShadowedDecl the declaration that is shadowed by the given variable +/// \param R the lookup of the name +/// +void Sema::CheckShadow(VarDecl *D, NamedDecl *ShadowedDecl, + const LookupResult &R) { + DeclContext *NewDC = D->getDeclContext(); if (FieldDecl *FD = dyn_cast<FieldDecl>(ShadowedDecl)) { // Fields are not shadowed by variables in C++ static methods. @@ -6732,7 +6745,8 @@ void Sema::CheckShadow(Scope *S, VarDecl *D) { LookupResult R(*this, D->getDeclName(), D->getLocation(), Sema::LookupOrdinaryName, Sema::ForRedeclaration); LookupName(R, S); - CheckShadow(S, D, R); + if (NamedDecl *ShadowedDecl = getShadowedDeclaration(D, R)) + CheckShadow(D, ShadowedDecl, R); } /// Check if 'E', which is an expression that is about to be modified, refers @@ -9782,8 +9796,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl, /// AddInitializerToDecl - Adds the initializer Init to the /// declaration dcl. If DirectInit is true, this is C++ direct /// initialization rather than copy initialization. -void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, - bool DirectInit, bool TypeMayContainAuto) { +void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { // If there is no declaration, there was an error parsing it. Just ignore // the initializer. if (!RealDecl || RealDecl->isInvalidDecl()) { @@ -9808,7 +9821,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, } // C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for. - if (TypeMayContainAuto && VDecl->getType()->isUndeducedType()) { + if (VDecl->getType()->isUndeducedType()) { // Attempt typo correction early so that the type of the init expression can // be deduced based on the chosen correction if the original init contains a // TypoExpr. @@ -10280,8 +10293,7 @@ bool Sema::canInitializeWithParenthesizedList(QualType TargetType) { TargetType->getContainedAutoType(); } -void Sema::ActOnUninitializedDecl(Decl *RealDecl, - bool TypeMayContainAuto) { +void Sema::ActOnUninitializedDecl(Decl *RealDecl) { // If there is no declaration, there was an error parsing it. Just ignore it. if (!RealDecl) return; @@ -10297,7 +10309,7 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl, } // C++11 [dcl.spec.auto]p3 - if (TypeMayContainAuto && Type->getContainedAutoType()) { + if (Type->isUndeducedType()) { Diag(Var->getLocation(), diag::err_auto_var_requires_init) << Var->getDeclName() << Type; Var->setInvalidDecl(); @@ -11081,32 +11093,32 @@ Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, } } - return BuildDeclaratorGroup(Decls, DS.containsPlaceholderType()); + return BuildDeclaratorGroup(Decls); } /// BuildDeclaratorGroup - convert a list of declarations into a declaration /// group, performing any necessary semantic checking. Sema::DeclGroupPtrTy -Sema::BuildDeclaratorGroup(MutableArrayRef<Decl *> Group, - bool TypeMayContainAuto) { - // C++0x [dcl.spec.auto]p7: - // If the type deduced for the template parameter U is not the same in each +Sema::BuildDeclaratorGroup(MutableArrayRef<Decl *> Group) { + // C++14 [dcl.spec.auto]p7: (DR1347) + // If the type that replaces the placeholder type is not the same in each // deduction, the program is ill-formed. - // FIXME: When initializer-list support is added, a distinction is needed - // between the deduced type U and the deduced type which 'auto' stands for. - // auto a = 0, b = { 1, 2, 3 }; - // is legal because the deduced type U is 'int' in both cases. - if (TypeMayContainAuto && Group.size() > 1) { + if (Group.size() > 1) { QualType Deduced; CanQualType DeducedCanon; VarDecl *DeducedDecl = nullptr; for (unsigned i = 0, e = Group.size(); i != e; ++i) { if (VarDecl *D = dyn_cast<VarDecl>(Group[i])) { AutoType *AT = D->getType()->getContainedAutoType(); + // FIXME: DR1265: if we have a function pointer declaration, we can have + // an 'auto' from a trailing return type. In that case, the return type + // must match the various other uses of 'auto'. + if (!AT) + continue; // Don't reissue diagnostics when instantiating a template. - if (AT && D->isInvalidDecl()) + if (D->isInvalidDecl()) break; - QualType U = AT ? AT->getDeducedType() : QualType(); + QualType U = AT->getDeducedType(); if (!U.isNull()) { CanQualType UCanon = Context.getCanonicalType(U); if (Deduced.isNull()) { diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index d172c951e749..b43e5b9e3278 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -1712,7 +1712,7 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc, DeclsInGroup.push_back(PDecl); } - return BuildDeclaratorGroup(DeclsInGroup, false); + return BuildDeclaratorGroup(DeclsInGroup); } Decl *Sema:: @@ -2019,7 +2019,7 @@ Sema::ActOnFinishObjCImplementation(Decl *ObjCImpDecl, ArrayRef<Decl *> Decls) { DeclsInGroup.push_back(ObjCImpDecl); - return BuildDeclaratorGroup(DeclsInGroup, false); + return BuildDeclaratorGroup(DeclsInGroup); } void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, @@ -3043,7 +3043,7 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, DeclsInGroup.push_back(IDecl); } - return BuildDeclaratorGroup(DeclsInGroup, false); + return BuildDeclaratorGroup(DeclsInGroup); } static bool tryMatchRecordTypes(ASTContext &Context, diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 1379440e8a03..b2fb33f53432 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -1504,14 +1504,12 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, SourceLocation PlacementLParen, MultiExprArg PlacementArgs, SourceLocation PlacementRParen, SourceRange TypeIdParens, Declarator &D, Expr *Initializer) { - bool TypeContainsAuto = D.getDeclSpec().containsPlaceholderType(); - Expr *ArraySize = nullptr; // If the specified type is an array, unwrap it and save the expression. if (D.getNumTypeObjects() > 0 && D.getTypeObject(0).Kind == DeclaratorChunk::Array) { - DeclaratorChunk &Chunk = D.getTypeObject(0); - if (TypeContainsAuto) + DeclaratorChunk &Chunk = D.getTypeObject(0); + if (D.getDeclSpec().containsPlaceholderType()) return ExprError(Diag(Chunk.Loc, diag::err_new_array_of_auto) << D.getSourceRange()); if (Chunk.Arr.hasStatic) @@ -1588,8 +1586,7 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, TInfo, ArraySize, DirectInitRange, - Initializer, - TypeContainsAuto); + Initializer); } static bool isLegalArrayNewInitializer(CXXNewExpr::InitializationStyle Style, @@ -1621,8 +1618,7 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, TypeSourceInfo *AllocTypeInfo, Expr *ArraySize, SourceRange DirectInitRange, - Expr *Initializer, - bool TypeMayContainAuto) { + Expr *Initializer) { SourceRange TypeRange = AllocTypeInfo->getTypeLoc().getSourceRange(); SourceLocation StartLoc = Range.getBegin(); @@ -1648,7 +1644,7 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, } // C++11 [dcl.spec.auto]p6. Deduce the type which 'auto' stands in for. - if (TypeMayContainAuto && AllocType->isUndeducedType()) { + if (AllocType->isUndeducedType()) { if (initStyle == CXXNewExpr::NoInit || NumInits == 0) return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg) << AllocType << TypeRange); diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index edceb537df75..dcd19c8d817d 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -1089,7 +1089,7 @@ void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { auto *VDPrivate = buildVarDecl( *this, DE->getExprLoc(), Type.getUnqualifiedType(), VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr); - ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false); + ActOnUninitializedDecl(VDPrivate); if (VDPrivate->isInvalidDecl()) continue; PrivateCopies.push_back(buildDeclRefExpr( @@ -1701,7 +1701,8 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { case OMPD_teams_distribute_parallel_for: case OMPD_target_teams_distribute: case OMPD_target_teams_distribute_parallel_for: - case OMPD_target_teams_distribute_parallel_for_simd: { + case OMPD_target_teams_distribute_parallel_for_simd: + case OMPD_target_teams_distribute_simd: { QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); @@ -1761,8 +1762,7 @@ static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, if (!WithInit) CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange())); S.CurContext->addHiddenDecl(CED); - S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false, - /*TypeMayContainAuto=*/true); + S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); return CED; } @@ -2446,6 +2446,11 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( AllowedNameModifiers.push_back(OMPD_target); AllowedNameModifiers.push_back(OMPD_parallel); break; + case OMPD_target_teams_distribute_simd: + Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( + ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); + AllowedNameModifiers.push_back(OMPD_target); + break; case OMPD_declare_target: case OMPD_end_declare_target: case OMPD_threadprivate: @@ -3970,33 +3975,32 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, // Lower bound variable, initialized with zero. VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); - SemaRef.AddInitializerToDecl( - LBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), - /*DirectInit*/ false, /*TypeMayContainAuto*/ false); + SemaRef.AddInitializerToDecl(LBDecl, + SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), + /*DirectInit*/ false); // Upper bound variable, initialized with last iteration number. VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), - /*DirectInit*/ false, - /*TypeMayContainAuto*/ false); + /*DirectInit*/ false); // A 32-bit variable-flag where runtime returns 1 for the last iteration. // This will be used to implement clause 'lastprivate'. QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); - SemaRef.AddInitializerToDecl( - ILDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), - /*DirectInit*/ false, /*TypeMayContainAuto*/ false); + SemaRef.AddInitializerToDecl(ILDecl, + SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), + /*DirectInit*/ false); // Stride variable returned by runtime (we initialize it to 1 by default). VarDecl *STDecl = buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); - SemaRef.AddInitializerToDecl( - STDecl, SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), - /*DirectInit*/ false, /*TypeMayContainAuto*/ false); + SemaRef.AddInitializerToDecl(STDecl, + SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), + /*DirectInit*/ false); // Build expression: UB = min(UB, LastIteration) // It is necessary for CodeGen of directives with static scheduling. @@ -6428,6 +6432,39 @@ StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); } +StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { + if (!AStmt) + return StmtError(); + + auto *CS = cast<CapturedStmt>(AStmt); + // 1.2.2 OpenMP Language Terminology + // Structured block - An executable statement with a single entry at the + // top and a single exit at the bottom. + // The point of exit cannot be a branch out of the structured block. + // longjmp() and throw() must not violate the entry/exit criteria. + CS->getCapturedDecl()->setNothrow(); + + OMPLoopDirective::HelperExprs B; + // In presence of clause 'collapse' with number of loops, it will + // define the nested loops number. + auto NestedLoopCount = CheckOpenMPLoop( + OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), + nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, + VarsWithImplicitDSA, B); + if (NestedLoopCount == 0) + return StmtError(); + + assert((CurContext->isDependentContext() || B.builtAll()) && + "omp target teams distribute simd loop exprs were not built"); + + getCurFunction()->setHasBranchProtectedScope(); + return OMPTargetTeamsDistributeSimdDirective::Create( + Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); +} + OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, @@ -7448,10 +7485,13 @@ OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, // A list item cannot appear in both a map clause and a data-sharing // attribute clause on the same construct if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel || - CurrDir == OMPD_target_teams || + CurrDir == OMPD_target_teams || CurrDir == OMPD_target_teams_distribute || CurrDir == OMPD_target_teams_distribute_parallel_for || - CurrDir == OMPD_target_teams_distribute_parallel_for_simd) { + CurrDir == OMPD_target_teams_distribute_parallel_for_simd || + CurrDir == OMPD_target_teams_distribute_simd || + CurrDir == OMPD_target_parallel_for_simd || + CurrDir == OMPD_target_parallel_for) { OpenMPClauseKind ConflictKind; if (DSAStack->checkMappableExprComponentListsForDecl( VD, /*CurrentRegionOnly=*/true, @@ -7481,7 +7521,7 @@ OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, Type = Type.getUnqualifiedType(); auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), D->hasAttrs() ? &D->getAttrs() : nullptr); - ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false); + ActOnUninitializedDecl(VDPrivate); if (VDPrivate->isInvalidDecl()) continue; auto VDPrivateRefExpr = buildDeclRefExpr( @@ -7709,10 +7749,13 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, // A list item cannot appear in both a map clause and a data-sharing // attribute clause on the same construct if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel || - CurrDir == OMPD_target_teams || + CurrDir == OMPD_target_teams || CurrDir == OMPD_target_teams_distribute || CurrDir == OMPD_target_teams_distribute_parallel_for || - CurrDir == OMPD_target_teams_distribute_parallel_for_simd) { + CurrDir == OMPD_target_teams_distribute_parallel_for_simd || + CurrDir == OMPD_target_teams_distribute_simd || + CurrDir == OMPD_target_parallel_for_simd || + CurrDir == OMPD_target_parallel_for) { OpenMPClauseKind ConflictKind; if (DSAStack->checkMappableExprComponentListsForDecl( VD, /*CurrentRegionOnly=*/true, @@ -7784,7 +7827,7 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, RefExpr->getExprLoc()); AddInitializerToDecl(VDPrivate, DefaultLvalueConversion(VDInitRefExpr).get(), - /*DirectInit=*/false, /*TypeMayContainAuto=*/false); + /*DirectInit=*/false); } if (VDPrivate->isInvalidDecl()) { if (IsImplicitClause) { @@ -8634,10 +8677,9 @@ OMPClause *Sema::ActOnOpenMPReductionClause( } } if (Init && DeclareReductionRef.isUnset()) { - AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false, - /*TypeMayContainAuto=*/false); + AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); } else if (!Init) - ActOnUninitializedDecl(RHSVD, /*TypeMayContainAuto=*/false); + ActOnUninitializedDecl(RHSVD); if (RHSVD->isInvalidDecl()) continue; if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { @@ -8886,7 +8928,7 @@ OMPClause *Sema::ActOnOpenMPLinearClause( else InitExpr = VD ? SimpleRefExpr : Ref; AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), - /*DirectInit=*/false, /*TypeMayContainAuto=*/false); + /*DirectInit=*/false); auto InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); @@ -10231,7 +10273,8 @@ checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, if ((DKind == OMPD_target || DKind == OMPD_target_teams || DKind == OMPD_target_teams_distribute || DKind == OMPD_target_teams_distribute_parallel_for || - DKind == OMPD_target_teams_distribute_parallel_for_simd) && VD) { + DKind == OMPD_target_teams_distribute_parallel_for_simd || + DKind == OMPD_target_teams_distribute_simd) && VD) { auto DVar = DSAS->getTopDSA(VD, false); if (isOpenMPPrivate(DVar.CKind)) { SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) @@ -10963,7 +11006,7 @@ OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, RefExpr->getExprLoc()); AddInitializerToDecl(VDPrivate, DefaultLvalueConversion(VDInitRefExpr).get(), - /*DirectInit=*/false, /*TypeMayContainAuto=*/false); + /*DirectInit=*/false); // If required, build a capture to implement the privatization initialized // with the current list item value. diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 41f4fa746fc6..afdae4ed6d7d 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -6596,7 +6596,9 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, Candidate.Function = MethodTmpl->getTemplatedDecl(); Candidate.Viable = false; Candidate.IsSurrogate = false; - Candidate.IgnoreObjectArgument = false; + Candidate.IgnoreObjectArgument = + cast<CXXMethodDecl>(Candidate.Function)->isStatic() || + ObjectType.isNull(); Candidate.ExplicitCallArguments = Args.size(); if (Result == TDK_NonDependentConversionFailure) Candidate.FailureKind = ovl_fail_bad_conversion; @@ -6658,7 +6660,11 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, Candidate.Function = FunctionTemplate->getTemplatedDecl(); Candidate.Viable = false; Candidate.IsSurrogate = false; - Candidate.IgnoreObjectArgument = false; + // Ignore the object argument if there is one, since we don't have an object + // type. + Candidate.IgnoreObjectArgument = + isa<CXXMethodDecl>(Candidate.Function) && + !isa<CXXConstructorDecl>(Candidate.Function); Candidate.ExplicitCallArguments = Args.size(); if (Result == TDK_NonDependentConversionFailure) Candidate.FailureKind = ovl_fail_bad_conversion; @@ -10490,56 +10496,42 @@ static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand, // operation somehow. bool SuppressUserConversions = false; - const FunctionProtoType *Proto; - unsigned ArgIdx = 0; + unsigned ConvIdx = 0; + ArrayRef<QualType> ParamTypes; if (Cand->IsSurrogate) { QualType ConvType = Cand->Surrogate->getConversionType().getNonReferenceType(); if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>()) ConvType = ConvPtrType->getPointeeType(); - Proto = ConvType->getAs<FunctionProtoType>(); - ArgIdx = 1; + ParamTypes = ConvType->getAs<FunctionProtoType>()->getParamTypes(); + // Conversion 0 is 'this', which doesn't have a corresponding argument. + ConvIdx = 1; } else if (Cand->Function) { - Proto = Cand->Function->getType()->getAs<FunctionProtoType>(); + ParamTypes = + Cand->Function->getType()->getAs<FunctionProtoType>()->getParamTypes(); if (isa<CXXMethodDecl>(Cand->Function) && - !isa<CXXConstructorDecl>(Cand->Function)) - ArgIdx = 1; + !isa<CXXConstructorDecl>(Cand->Function)) { + // Conversion 0 is 'this', which doesn't have a corresponding argument. + ConvIdx = 1; + } } else { - // Builtin binary operator with a bad first conversion. + // Builtin operator. assert(ConvCount <= 3); - for (unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0); - ConvIdx != ConvCount; ++ConvIdx) { - if (Cand->Conversions[ConvIdx].isInitialized()) - continue; - if (Cand->BuiltinTypes.ParamTypes[ConvIdx]->isDependentType()) - Cand->Conversions[ConvIdx].setAsIdentityConversion( - Args[ConvIdx]->getType()); - else - Cand->Conversions[ConvIdx] = TryCopyInitialization( - S, Args[ConvIdx], Cand->BuiltinTypes.ParamTypes[ConvIdx], - SuppressUserConversions, - /*InOverloadResolution*/ true, - /*AllowObjCWritebackConversion=*/ - S.getLangOpts().ObjCAutoRefCount); - // FIXME: If the conversion is bad, try to fix it. - } - return; + ParamTypes = Cand->BuiltinTypes.ParamTypes; } // Fill in the rest of the conversions. - unsigned NumParams = Proto->getNumParams(); - for (unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0); - ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx) { + for (unsigned ArgIdx = 0; ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx) { if (Cand->Conversions[ConvIdx].isInitialized()) { - // Found the bad conversion. - } else if (ArgIdx < NumParams) { - if (Proto->getParamType(ArgIdx)->isDependentType()) + // We've already checked this conversion. + } else if (ArgIdx < ParamTypes.size()) { + if (ParamTypes[ArgIdx]->isDependentType()) Cand->Conversions[ConvIdx].setAsIdentityConversion( Args[ArgIdx]->getType()); else { Cand->Conversions[ConvIdx] = - TryCopyInitialization(S, Args[ArgIdx], Proto->getParamType(ArgIdx), + TryCopyInitialization(S, Args[ArgIdx], ParamTypes[ArgIdx], SuppressUserConversions, /*InOverloadResolution=*/true, /*AllowObjCWritebackConversion=*/ diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 50f0a22ff02b..a8832e9a1c54 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -1881,8 +1881,7 @@ static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init, SemaRef.inferObjCARCLifetime(Decl)) Decl->setInvalidDecl(); - SemaRef.AddInitializerToDecl(Decl, Init, /*DirectInit=*/false, - /*TypeMayContainAuto=*/false); + SemaRef.AddInitializerToDecl(Decl, Init, /*DirectInit=*/false); SemaRef.FinalizeDeclaration(Decl); SemaRef.CurContext->addHiddenDecl(Decl); return false; @@ -2005,8 +2004,7 @@ StmtResult Sema::ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc, // Claim the type doesn't contain auto: we've already done the checking. DeclGroupPtrTy RangeGroup = - BuildDeclaratorGroup(MutableArrayRef<Decl *>((Decl **)&RangeVar, 1), - /*TypeMayContainAuto=*/ false); + BuildDeclaratorGroup(MutableArrayRef<Decl *>((Decl **)&RangeVar, 1)); StmtResult RangeDecl = ActOnDeclStmt(RangeGroup, RangeLoc, RangeLoc); if (RangeDecl.isInvalid()) { LoopVar->setInvalidDecl(); @@ -2408,8 +2406,7 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc, // Attach *__begin as initializer for VD. Don't touch it if we're just // trying to determine whether this would be a valid range. if (!LoopVar->isInvalidDecl() && Kind != BFRK_Check) { - AddInitializerToDecl(LoopVar, DerefExpr.get(), /*DirectInit=*/false, - /*TypeMayContainAuto=*/true); + AddInitializerToDecl(LoopVar, DerefExpr.get(), /*DirectInit=*/false); if (LoopVar->isInvalidDecl()) NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin); } diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 795e6025d96f..8ad5b5951ea3 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -1224,9 +1224,17 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, } } + // If this is a templated friend in a dependent context we should not put it + // on the redecl chain. In some cases, the templated friend can be the most + // recent declaration tricking the template instantiator to make substitutions + // there. + // FIXME: Figure out how to combine with shouldLinkDependentDeclWithPrevious + bool ShouldAddRedecl + = !(TUK == TUK_Friend && CurContext->isDependentContext()); + CXXRecordDecl *NewClass = CXXRecordDecl::Create(Context, Kind, SemanticContext, KWLoc, NameLoc, Name, - PrevClassTemplate? + PrevClassTemplate && ShouldAddRedecl ? PrevClassTemplate->getTemplatedDecl() : nullptr, /*DelayTypeCreation=*/true); SetNestedNameSpecifier(NewClass, SS); @@ -1245,7 +1253,11 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, ClassTemplateDecl *NewTemplate = ClassTemplateDecl::Create(Context, SemanticContext, NameLoc, DeclarationName(Name), TemplateParams, - NewClass, PrevClassTemplate); + NewClass); + + if (ShouldAddRedecl) + NewTemplate->setPreviousDecl(PrevClassTemplate); + NewClass->setDescribedClassTemplate(NewTemplate); if (ModulePrivateLoc.isValid()) @@ -1653,6 +1665,7 @@ struct DependencyChecker : RecursiveASTVisitor<DependencyChecker> { typedef RecursiveASTVisitor<DependencyChecker> super; unsigned Depth; + bool FindLessThanDepth; // Whether we're looking for a use of a template parameter that makes the // overall construct type-dependent / a dependent type. This is strictly @@ -1663,25 +1676,16 @@ struct DependencyChecker : RecursiveASTVisitor<DependencyChecker> { bool Match; SourceLocation MatchLoc; - DependencyChecker(unsigned Depth, bool IgnoreNonTypeDependent) - : Depth(Depth), IgnoreNonTypeDependent(IgnoreNonTypeDependent), - Match(false) {} + DependencyChecker(unsigned Depth, bool IgnoreNonTypeDependent, + bool FindLessThanDepth = false) + : Depth(Depth), FindLessThanDepth(FindLessThanDepth), + IgnoreNonTypeDependent(IgnoreNonTypeDependent), Match(false) {} DependencyChecker(TemplateParameterList *Params, bool IgnoreNonTypeDependent) - : IgnoreNonTypeDependent(IgnoreNonTypeDependent), Match(false) { - NamedDecl *ND = Params->getParam(0); - if (TemplateTypeParmDecl *PD = dyn_cast<TemplateTypeParmDecl>(ND)) { - Depth = PD->getDepth(); - } else if (NonTypeTemplateParmDecl *PD = - dyn_cast<NonTypeTemplateParmDecl>(ND)) { - Depth = PD->getDepth(); - } else { - Depth = cast<TemplateTemplateParmDecl>(ND)->getDepth(); - } - } + : DependencyChecker(Params->getDepth(), IgnoreNonTypeDependent) {} bool Matches(unsigned ParmDepth, SourceLocation Loc = SourceLocation()) { - if (ParmDepth >= Depth) { + if (FindLessThanDepth ^ (ParmDepth >= Depth)) { Match = true; MatchLoc = Loc; return true; @@ -2336,15 +2340,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, // A<T, T> have identical types when A is declared as: // // template<typename T, typename U = T> struct A; - TemplateName CanonName = Context.getCanonicalTemplateName(Name); - CanonType = Context.getTemplateSpecializationType(CanonName, - Converted); - - // FIXME: CanonType is not actually the canonical type, and unfortunately - // it is a TemplateSpecializationType that we will never use again. - // In the future, we need to teach getTemplateSpecializationType to only - // build the canonical type and return that to us. - CanonType = Context.getCanonicalType(CanonType); + CanonType = Context.getCanonicalTemplateSpecializationType(Name, Converted); // This might work out to be a current instantiation, in which // case the canonical type needs to be the InjectedClassNameType. @@ -3452,7 +3448,7 @@ SubstDefaultTemplateArgument(Sema &SemaRef, SourceLocation TemplateLoc, SourceLocation RAngleLoc, TemplateTypeParmDecl *Param, - SmallVectorImpl<TemplateArgument> &Converted) { + SmallVectorImpl<TemplateArgument> &Converted) { TypeSourceInfo *ArgType = Param->getDefaultArgumentInfo(); // If the argument type is dependent, instantiate it now based @@ -5838,6 +5834,15 @@ Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg, return E; } +static bool isDependentOnOuter(NonTypeTemplateParmDecl *NTTP) { + if (NTTP->getDepth() == 0 || !NTTP->getType()->isDependentType()) + return false; + DependencyChecker Checker(NTTP->getDepth(), /*IgnoreNonTypeDependent*/ false, + /*FindLessThanDepth*/ true); + Checker.TraverseType(NTTP->getType()); + return Checker.Match; +} + /// \brief Match two template parameters within template parameter lists. static bool MatchTemplateParameterKind(Sema &S, NamedDecl *New, NamedDecl *Old, bool Complain, @@ -5894,11 +5899,10 @@ static bool MatchTemplateParameterKind(Sema &S, NamedDecl *New, NamedDecl *Old, // If we are matching a template template argument to a template // template parameter and one of the non-type template parameter types - // is dependent, then we must wait until template instantiation time - // to actually compare the arguments. + // is dependent on an outer template's parameter, then we must wait until + // template instantiation time to actually compare the arguments. if (Kind == Sema::TPL_TemplateTemplateArgumentMatch && - (OldNTTP->getType()->isDependentType() || - NewNTTP->getType()->isDependentType())) + (isDependentOnOuter(OldNTTP) || isDependentOnOuter(NewNTTP))) return true; if (!S.Context.hasSameType(OldNTTP->getType(), NewNTTP->getType())) { @@ -7785,6 +7789,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, Specialization->setTemplateKeywordLoc(TemplateLoc); Specialization->setBraceRange(SourceRange()); + bool PreviouslyDLLExported = Specialization->hasAttr<DLLExportAttr>(); if (Attr) ProcessDeclAttributeList(S, Specialization, Attr); @@ -7847,8 +7852,9 @@ Sema::ActOnExplicitInstantiation(Scope *S, // Fix a TSK_ImplicitInstantiation followed by a // TSK_ExplicitInstantiationDefinition - if (Old_TSK == TSK_ImplicitInstantiation && - Specialization->hasAttr<DLLExportAttr>() && + bool NewlyDLLExported = + !PreviouslyDLLExported && Specialization->hasAttr<DLLExportAttr>(); + if (Old_TSK == TSK_ImplicitInstantiation && NewlyDLLExported && (Context.getTargetInfo().getCXXABI().isMicrosoft() || Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment())) { // In the MS ABI, an explicit instantiation definition can add a dll diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index ba4a5b7bc0d7..9f744a1dc1b2 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -2264,9 +2264,6 @@ bool Sema::InstantiateInClassInitializer( if (auto *L = getASTMutationListener()) L->DefaultMemberInitializerInstantiated(Instantiation); - // Exit the scope of this instantiation. - SavedContext.pop(); - // Return true if the in-class initializer is still missing. return !Instantiation->getInClassInitializer(); } diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index d2a5e5cb5312..48d8b94af153 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1219,8 +1219,10 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { ClassTemplateDecl *Inst = ClassTemplateDecl::Create(SemaRef.Context, DC, D->getLocation(), - D->getIdentifier(), InstParams, RecordInst, - PrevClassTemplate); + D->getIdentifier(), InstParams, RecordInst); + assert(!(isFriend && Owner->isDependentContext())); + Inst->setPreviousDecl(PrevClassTemplate); + RecordInst->setDescribedClassTemplate(Inst); if (isFriend) { @@ -4085,7 +4087,6 @@ void Sema::InstantiateVariableInitializer( } if (!Init.isInvalid()) { - bool TypeMayContainAuto = true; Expr *InitExpr = Init.get(); if (Var->hasAttr<DLLImportAttr>() && @@ -4094,9 +4095,9 @@ void Sema::InstantiateVariableInitializer( // Do not dynamically initialize dllimport variables. } else if (InitExpr) { bool DirectInit = OldVar->isDirectInit(); - AddInitializerToDecl(Var, InitExpr, DirectInit, TypeMayContainAuto); + AddInitializerToDecl(Var, InitExpr, DirectInit); } else - ActOnUninitializedDecl(Var, TypeMayContainAuto); + ActOnUninitializedDecl(Var); } else { // FIXME: Not too happy about invalidating the declaration // because of a bogus initializer. @@ -4119,7 +4120,7 @@ void Sema::InstantiateVariableInitializer( if (Var->isCXXForRangeDecl()) return; - ActOnUninitializedDecl(Var, false); + ActOnUninitializedDecl(Var); } } diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index ae9a3ee790e1..29b21426790e 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -5263,7 +5263,7 @@ namespace { ParmVarDecl *Param = cast<ParmVarDecl>(FTI.Params[i].Param); TL.setParam(tpi++, Param); } - // FIXME: exception specs + TL.setExceptionSpecRange(FTI.getExceptionSpecRange()); } void VisitParenTypeLoc(ParenTypeLoc TL) { assert(Chunk.Kind == DeclaratorChunk::Paren); diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 66892936e573..c2aa3fef67c8 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -5023,6 +5023,7 @@ QualType TreeTransform<Derived>::TransformFunctionProtoType( NewTL.setLocalRangeBegin(TL.getLocalRangeBegin()); NewTL.setLParenLoc(TL.getLParenLoc()); NewTL.setRParenLoc(TL.getRParenLoc()); + NewTL.setExceptionSpecRange(TL.getExceptionSpecRange()); NewTL.setLocalRangeEnd(TL.getLocalRangeEnd()); for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i) NewTL.setParam(i, ParamDecls[i]); @@ -7779,6 +7780,18 @@ StmtResult TreeTransform<Derived>:: return Res; } +template <typename Derived> +StmtResult +TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective( + OMPTargetTeamsDistributeSimdDirective *D) { + DeclarationNameInfo DirName; + getDerived().getSema().StartOpenMPDSABlock( + OMPD_target_teams_distribute_simd, DirName, nullptr, D->getLocStart()); + auto Res = getDerived().TransformOMPExecutableDirective(D); + getDerived().getSema().EndOpenMPDSABlock(Res.get()); + return Res; +} + //===----------------------------------------------------------------------===// // OpenMP clause transformation |