Author: dim Date: Fri Nov 25 19:07:40 2016 New Revision: 309154 URL: https://svnweb.freebsd.org/changeset/base/309154
Log: Vendor import of clang release_39 branch r287912: https://llvm.org/svn/llvm-project/cfe/branches/release_39@287912 Added: vendor/clang/dist/test/CodeGenCXX/PR28523.cpp (contents, props changed) vendor/clang/dist/test/CodeGenOpenCL/kernel-arg-info-single-as.cl vendor/clang/dist/test/Modules/Inputs/static_assert/ vendor/clang/dist/test/Modules/Inputs/static_assert/a.h (contents, props changed) vendor/clang/dist/test/Modules/Inputs/static_assert/module.modulemap vendor/clang/dist/test/Modules/static_assert.cpp (contents, props changed) vendor/clang/dist/test/OpenMP/debug-info-openmp-array.cpp (contents, props changed) Modified: vendor/clang/dist/include/clang/AST/DeclTemplate.h vendor/clang/dist/include/clang/Basic/DiagnosticDriverKinds.td vendor/clang/dist/include/clang/Basic/DiagnosticSemaKinds.td vendor/clang/dist/include/clang/Sema/Sema.h vendor/clang/dist/lib/Basic/Targets.cpp vendor/clang/dist/lib/Basic/Version.cpp vendor/clang/dist/lib/CodeGen/CGExpr.cpp vendor/clang/dist/lib/CodeGen/CGStmt.cpp vendor/clang/dist/lib/CodeGen/CGStmtOpenMP.cpp vendor/clang/dist/lib/CodeGen/CodeGenFunction.cpp vendor/clang/dist/lib/CodeGen/CodeGenFunction.h vendor/clang/dist/lib/Driver/ToolChains.cpp vendor/clang/dist/lib/Driver/Tools.cpp vendor/clang/dist/lib/Sema/Sema.cpp vendor/clang/dist/lib/Sema/SemaCXXScopeSpec.cpp vendor/clang/dist/lib/Sema/SemaDecl.cpp vendor/clang/dist/lib/Sema/SemaExpr.cpp vendor/clang/dist/lib/Sema/SemaExprCXX.cpp vendor/clang/dist/lib/Sema/SemaLambda.cpp vendor/clang/dist/lib/Sema/SemaOpenMP.cpp vendor/clang/dist/lib/Sema/SemaTemplate.cpp vendor/clang/dist/lib/Sema/SemaTemplateInstantiate.cpp vendor/clang/dist/lib/Sema/SemaTemplateInstantiateDecl.cpp vendor/clang/dist/lib/Serialization/ASTReaderDecl.cpp vendor/clang/dist/test/CodeGenCXX/captured-statements.cpp vendor/clang/dist/test/CodeGenCXX/switch-case-folding-2.cpp vendor/clang/dist/test/Driver/darwin-ld-lto.c vendor/clang/dist/test/Frontend/darwin-version.c vendor/clang/dist/test/OpenMP/atomic_write_codegen.c vendor/clang/dist/test/OpenMP/cancel_codegen.cpp vendor/clang/dist/test/OpenMP/distribute_parallel_for_reduction_messages.cpp vendor/clang/dist/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp vendor/clang/dist/test/OpenMP/distribute_simd_reduction_messages.cpp vendor/clang/dist/test/OpenMP/for_lastprivate_codegen.cpp vendor/clang/dist/test/OpenMP/for_reduction_codegen.cpp vendor/clang/dist/test/OpenMP/for_reduction_codegen_UDR.cpp vendor/clang/dist/test/OpenMP/for_reduction_messages.cpp vendor/clang/dist/test/OpenMP/for_simd_reduction_messages.cpp vendor/clang/dist/test/OpenMP/parallel_codegen.cpp vendor/clang/dist/test/OpenMP/parallel_for_reduction_messages.cpp vendor/clang/dist/test/OpenMP/parallel_for_simd_reduction_messages.cpp vendor/clang/dist/test/OpenMP/parallel_reduction_messages.cpp vendor/clang/dist/test/OpenMP/parallel_sections_reduction_messages.cpp vendor/clang/dist/test/OpenMP/sections_reduction_messages.cpp vendor/clang/dist/test/OpenMP/simd_reduction_messages.cpp vendor/clang/dist/test/OpenMP/target_firstprivate_codegen.cpp vendor/clang/dist/test/OpenMP/target_map_codegen.cpp vendor/clang/dist/test/OpenMP/target_map_messages.cpp vendor/clang/dist/test/OpenMP/target_parallel_for_map_messages.cpp vendor/clang/dist/test/OpenMP/target_parallel_for_reduction_messages.cpp vendor/clang/dist/test/OpenMP/target_parallel_for_simd_map_messages.cpp vendor/clang/dist/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp vendor/clang/dist/test/OpenMP/target_parallel_map_messages.cpp vendor/clang/dist/test/OpenMP/target_parallel_reduction_messages.cpp vendor/clang/dist/test/OpenMP/teams_reduction_messages.cpp vendor/clang/dist/test/Preprocessor/init.c vendor/clang/dist/test/SemaCXX/cxx0x-defaulted-functions.cpp vendor/clang/dist/test/SemaCXX/nested-name-spec.cpp vendor/clang/dist/test/SemaTemplate/instantiate-self.cpp vendor/clang/dist/test/SemaTemplate/instantiation-depth-exception-spec.cpp vendor/clang/dist/test/SemaTemplate/instantiation-depth.cpp vendor/clang/dist/tools/libclang/CIndex.cpp Modified: vendor/clang/dist/include/clang/AST/DeclTemplate.h ============================================================================== --- vendor/clang/dist/include/clang/AST/DeclTemplate.h Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/include/clang/AST/DeclTemplate.h Fri Nov 25 19:07:40 2016 (r309154) @@ -44,6 +44,8 @@ class VarTemplatePartialSpecializationDe typedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*, TemplateTemplateParmDecl*> TemplateParameter; +NamedDecl *getAsNamedDecl(TemplateParameter P); + /// \brief Stores a list of template parameters for a TemplateDecl and its /// derived classes. class TemplateParameterList final @@ -2912,6 +2914,14 @@ public: friend class ASTDeclWriter; }; +inline NamedDecl *getAsNamedDecl(TemplateParameter P) { + if (auto *PD = P.dyn_cast<TemplateTypeParmDecl*>()) + return PD; + if (auto *PD = P.dyn_cast<NonTypeTemplateParmDecl*>()) + return PD; + return P.get<TemplateTemplateParmDecl*>(); +} + } /* end of namespace clang */ #endif Modified: vendor/clang/dist/include/clang/Basic/DiagnosticDriverKinds.td ============================================================================== --- vendor/clang/dist/include/clang/Basic/DiagnosticDriverKinds.td Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/include/clang/Basic/DiagnosticDriverKinds.td Fri Nov 25 19:07:40 2016 (r309154) @@ -159,8 +159,6 @@ def err_drv_bitcode_unsupported_on_toolc "-fembed-bitcode is not supported on versions of iOS prior to 6.0">; def warn_O4_is_O3 : Warning<"-O4 is equivalent to -O3">, InGroup<Deprecated>; -def warn_drv_lto_libpath : Warning<"libLTO.dylib relative to clang installed dir not found; using 'ld' default search path instead">, - InGroup<LibLTO>; def warn_drv_optimization_value : Warning<"optimization level '%0' is not supported; using '%1%2' instead">, InGroup<InvalidCommandLineArgument>; def warn_ignored_gcc_optimization : Warning<"optimization flag '%0' is not supported">, Modified: vendor/clang/dist/include/clang/Basic/DiagnosticSemaKinds.td ============================================================================== --- vendor/clang/dist/include/clang/Basic/DiagnosticSemaKinds.td Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/include/clang/Basic/DiagnosticSemaKinds.td Fri Nov 25 19:07:40 2016 (r309154) @@ -4291,7 +4291,7 @@ def err_definition_of_implicitly_declare def err_definition_of_explicitly_defaulted_member : Error< "definition of explicitly defaulted %select{default constructor|copy " "constructor|move constructor|copy assignment operator|move assignment " - "operator|destructor}0">; + "operator|destructor|function}0">; def err_redefinition_extern_inline : Error< "redefinition of a 'extern inline' function %0 is not supported in " "%select{C99 mode|C++}1">; @@ -6917,6 +6917,10 @@ def err_in_class_initializer_not_yet_par def err_in_class_initializer_not_yet_parsed_outer_class : Error<"cannot use defaulted default constructor of %0 within " "%1 outside of member functions because %2 has an initializer">; +def err_in_class_initializer_cycle + : Error<"default member initializer for %0 uses itself">; +def err_exception_spec_cycle + : Error<"exception specification of %0 uses itself">; def ext_in_class_initializer_non_constant : Extension< "in-class initializer for static data member is not a constant expression; " Modified: vendor/clang/dist/include/clang/Sema/Sema.h ============================================================================== --- vendor/clang/dist/include/clang/Sema/Sema.h Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/include/clang/Sema/Sema.h Fri Nov 25 19:07:40 2016 (r309154) @@ -18,6 +18,7 @@ #include "clang/AST/Attr.h" #include "clang/AST/Availability.h" #include "clang/AST/DeclarationName.h" +#include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/ExternalASTSource.h" @@ -1217,8 +1218,10 @@ public: /// \brief Retrieve the current block, if any. sema::BlockScopeInfo *getCurBlock(); - /// \brief Retrieve the current lambda scope info, if any. - sema::LambdaScopeInfo *getCurLambda(); + /// Retrieve the current lambda scope info, if any. + /// \param IgnoreCapturedRegions true if should find the top-most lambda scope + /// info ignoring all inner captured regions scope infos. + sema::LambdaScopeInfo *getCurLambda(bool IgnoreCapturedRegions = false); /// \brief Retrieve the current generic lambda info, if any. sema::LambdaScopeInfo *getCurGenericLambda(); @@ -6613,10 +6616,10 @@ public: TemplateInstantiation, /// We are instantiating a default argument for a template - /// parameter. The Entity is the template, and - /// TemplateArgs/NumTemplateArguments provides the template - /// arguments as specified. - /// FIXME: Use a TemplateArgumentList + /// parameter. The Entity is the template parameter whose argument is + /// being instantiated, the Template is the template, and the + /// TemplateArgs/NumTemplateArguments provide the template arguments as + /// specified. DefaultTemplateArgumentInstantiation, /// We are instantiating a default argument for a function. @@ -6731,6 +6734,9 @@ public: SmallVector<ActiveTemplateInstantiation, 16> ActiveTemplateInstantiations; + /// Specializations whose definitions are currently being instantiated. + llvm::DenseSet<std::pair<Decl *, unsigned>> InstantiatingSpecializations; + /// \brief Extra modules inspected when performing a lookup during a template /// instantiation. Computed lazily. SmallVector<Module*, 16> ActiveTemplateInstantiationLookupModules; @@ -6837,12 +6843,12 @@ public: /// \brief Note that we are instantiating a default argument in a /// template-id. InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - TemplateDecl *Template, + TemplateParameter Param, TemplateDecl *Template, ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange = SourceRange()); - /// \brief Note that we are instantiating a default argument in a - /// template-id. + /// \brief Note that we are substituting either explicitly-specified or + /// deduced template arguments during function template argument deduction. InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, FunctionTemplateDecl *FunctionTemplate, ArrayRef<TemplateArgument> TemplateArgs, @@ -6909,9 +6915,14 @@ public: /// recursive template instantiations. bool isInvalid() const { return Invalid; } + /// \brief Determine whether we are already instantiating this + /// specialization in some surrounding active instantiation. + bool isAlreadyInstantiating() const { return AlreadyInstantiating; } + private: Sema &SemaRef; bool Invalid; + bool AlreadyInstantiating; bool SavedInNonInstantiationSFINAEContext; bool CheckInstantiationDepth(SourceLocation PointOfInstantiation, SourceRange InstantiationRange); Modified: vendor/clang/dist/lib/Basic/Targets.cpp ============================================================================== --- vendor/clang/dist/lib/Basic/Targets.cpp Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/lib/Basic/Targets.cpp Fri Nov 25 19:07:40 2016 (r309154) @@ -158,14 +158,25 @@ static void getDarwinDefines(MacroBuilde // Set the appropriate OS version define. if (Triple.isiOS()) { - assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!"); - char Str[6]; - Str[0] = '0' + Maj; - Str[1] = '0' + (Min / 10); - Str[2] = '0' + (Min % 10); - Str[3] = '0' + (Rev / 10); - Str[4] = '0' + (Rev % 10); - Str[5] = '\0'; + assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!"); + char Str[7]; + if (Maj < 10) { + Str[0] = '0' + Maj; + Str[1] = '0' + (Min / 10); + Str[2] = '0' + (Min % 10); + Str[3] = '0' + (Rev / 10); + Str[4] = '0' + (Rev % 10); + Str[5] = '\0'; + } else { + // Handle versions >= 10. + Str[0] = '0' + (Maj / 10); + Str[1] = '0' + (Maj % 10); + Str[2] = '0' + (Min / 10); + Str[3] = '0' + (Min % 10); + Str[4] = '0' + (Rev / 10); + Str[5] = '0' + (Rev % 10); + Str[6] = '\0'; + } if (Triple.isTvOS()) Builder.defineMacro("__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__", Str); else @@ -8170,6 +8181,8 @@ static TargetInfo *AllocateTarget(const return new DarwinARMTargetInfo(Triple, Opts); switch (os) { + case llvm::Triple::CloudABI: + return new CloudABITargetInfo<ARMleTargetInfo>(Triple, Opts); case llvm::Triple::Linux: return new LinuxTargetInfo<ARMleTargetInfo>(Triple, Opts); case llvm::Triple::FreeBSD: Modified: vendor/clang/dist/lib/Basic/Version.cpp ============================================================================== --- vendor/clang/dist/lib/Basic/Version.cpp Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/lib/Basic/Version.cpp Fri Nov 25 19:07:40 2016 (r309154) @@ -36,7 +36,7 @@ std::string getClangRepositoryPath() { // If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us // pick up a tag in an SVN export, for example. - StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_390/final/lib/Basic/Version.cpp $"); + StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/branches/release_39/lib/Basic/Version.cpp $"); if (URL.empty()) { URL = SVNRepository.slice(SVNRepository.find(':'), SVNRepository.find("/lib/Basic")); Modified: vendor/clang/dist/lib/CodeGen/CGExpr.cpp ============================================================================== --- vendor/clang/dist/lib/CodeGen/CGExpr.cpp Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/lib/CodeGen/CGExpr.cpp Fri Nov 25 19:07:40 2016 (r309154) @@ -2105,12 +2105,11 @@ LValue CodeGenFunction::EmitDeclRefLValu if (auto *FD = LambdaCaptureFields.lookup(VD)) return EmitCapturedFieldLValue(*this, FD, CXXABIThisValue); else if (CapturedStmtInfo) { - auto it = LocalDeclMap.find(VD); - if (it != LocalDeclMap.end()) { - if (auto RefTy = VD->getType()->getAs<ReferenceType>()) { - return EmitLoadOfReferenceLValue(it->second, RefTy); - } - return MakeAddrLValue(it->second, T); + auto I = LocalDeclMap.find(VD); + if (I != LocalDeclMap.end()) { + if (auto RefTy = VD->getType()->getAs<ReferenceType>()) + return EmitLoadOfReferenceLValue(I->second, RefTy); + return MakeAddrLValue(I->second, T); } LValue CapLVal = EmitCapturedFieldLValue(*this, CapturedStmtInfo->lookup(VD), @@ -2249,13 +2248,15 @@ LValue CodeGenFunction::EmitUnaryOpLValu return LV; } - assert(E->getSubExpr()->getType()->isAnyComplexType()); + QualType T = ExprTy->castAs<ComplexType>()->getElementType(); Address Component = (E->getOpcode() == UO_Real ? emitAddrOfRealComponent(LV.getAddress(), LV.getType()) : emitAddrOfImagComponent(LV.getAddress(), LV.getType())); - return MakeAddrLValue(Component, ExprTy, LV.getAlignmentSource()); + LValue ElemLV = MakeAddrLValue(Component, T, LV.getAlignmentSource()); + ElemLV.getQuals().addQualifiers(LV.getQuals()); + return ElemLV; } case UO_PreInc: case UO_PreDec: { Modified: vendor/clang/dist/lib/CodeGen/CGStmt.cpp ============================================================================== --- vendor/clang/dist/lib/CodeGen/CGStmt.cpp Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/lib/CodeGen/CGStmt.cpp Fri Nov 25 19:07:40 2016 (r309154) @@ -1323,6 +1323,10 @@ static CSFC_Result CollectStatementsForC // Handle this as two cases: we might be looking for the SwitchCase (if so // the skipped statements must be skippable) or we might already have it. CompoundStmt::const_body_iterator I = CS->body_begin(), E = CS->body_end(); + bool StartedInLiveCode = FoundCase; + unsigned StartSize = ResultStmts.size(); + + // If we've not found the case yet, scan through looking for it. if (Case) { // Keep track of whether we see a skipped declaration. The code could be // using the declaration even if it is skipped, so we can't optimize out @@ -1332,7 +1336,7 @@ static CSFC_Result CollectStatementsForC // If we're looking for the case, just see if we can skip each of the // substatements. for (; Case && I != E; ++I) { - HadSkippedDecl |= isa<DeclStmt>(*I); + HadSkippedDecl |= CodeGenFunction::mightAddDeclToScope(*I); switch (CollectStatementsForCase(*I, Case, FoundCase, ResultStmts)) { case CSFC_Failure: return CSFC_Failure; @@ -1368,11 +1372,19 @@ static CSFC_Result CollectStatementsForC break; } } + + if (!FoundCase) + return CSFC_Success; + + assert(!HadSkippedDecl && "fallthrough after skipping decl"); } // If we have statements in our range, then we know that the statements are // live and need to be added to the set of statements we're tracking. + bool AnyDecls = false; for (; I != E; ++I) { + AnyDecls |= CodeGenFunction::mightAddDeclToScope(*I); + switch (CollectStatementsForCase(*I, nullptr, FoundCase, ResultStmts)) { case CSFC_Failure: return CSFC_Failure; case CSFC_FallThrough: @@ -1390,7 +1402,24 @@ static CSFC_Result CollectStatementsForC } } - return Case ? CSFC_Success : CSFC_FallThrough; + // If we're about to fall out of a scope without hitting a 'break;', we + // can't perform the optimization if there were any decls in that scope + // (we'd lose their end-of-lifetime). + if (AnyDecls) { + // If the entire compound statement was live, there's one more thing we + // can try before giving up: emit the whole thing as a single statement. + // We can do that unless the statement contains a 'break;'. + // FIXME: Such a break must be at the end of a construct within this one. + // We could emit this by just ignoring the BreakStmts entirely. + if (StartedInLiveCode && !CodeGenFunction::containsBreak(S)) { + ResultStmts.resize(StartSize); + ResultStmts.push_back(S); + } else { + return CSFC_Failure; + } + } + + return CSFC_FallThrough; } // Okay, this is some other statement that we don't handle explicitly, like a Modified: vendor/clang/dist/lib/CodeGen/CGStmtOpenMP.cpp ============================================================================== --- vendor/clang/dist/lib/CodeGen/CGStmtOpenMP.cpp Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/lib/CodeGen/CGStmtOpenMP.cpp Fri Nov 25 19:07:40 2016 (r309154) @@ -232,8 +232,15 @@ CodeGenFunction::GenerateOpenMPCapturedS assert(I->capturesVariableArrayType()); II = &getContext().Idents.get("vla"); } - if (ArgType->isVariablyModifiedType()) - ArgType = getContext().getVariableArrayDecayedType(ArgType); + if (ArgType->isVariablyModifiedType()) { + bool IsReference = ArgType->isLValueReferenceType(); + ArgType = + getContext().getCanonicalParamType(ArgType.getNonReferenceType()); + if (IsReference && !ArgType->isPointerType()) { + ArgType = getContext().getLValueReferenceType( + ArgType, /*SpelledAsLValue=*/false); + } + } Args.push_back(ImplicitParamDecl::Create(getContext(), nullptr, FD->getLocation(), II, ArgType)); ++I; @@ -287,8 +294,14 @@ CodeGenFunction::GenerateOpenMPCapturedS QualType VarTy = Var->getType(); Address ArgAddr = ArgLVal.getAddress(); if (!VarTy->isReferenceType()) { - ArgAddr = EmitLoadOfReference( - ArgAddr, ArgLVal.getType()->castAs<ReferenceType>()); + if (ArgLVal.getType()->isLValueReferenceType()) { + ArgAddr = EmitLoadOfReference( + ArgAddr, ArgLVal.getType()->castAs<ReferenceType>()); + } else if (!VarTy->isVariablyModifiedType() || !VarTy->isPointerType()) { + assert(ArgLVal.getType()->isPointerType()); + ArgAddr = EmitLoadOfPointer( + ArgAddr, ArgLVal.getType()->castAs<PointerType>()); + } } setAddrOfLocalVar( Var, Address(ArgAddr.getPointer(), getContext().getDeclAlign(Var))); @@ -1754,9 +1767,17 @@ void CodeGenFunction::EmitOMPOuterLoop(b EmitBlock(LoopExit.getBlock()); // Tell the runtime we are done. - if (!DynamicOrOrdered) - RT.emitForStaticFinish(*this, S.getLocEnd()); - + SourceLocation ELoc = S.getLocEnd(); + auto &&CodeGen = [DynamicOrOrdered, ELoc](CodeGenFunction &CGF) { + if (!DynamicOrOrdered) + CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, ELoc); + }; + CodeGen(*this); + + OpenMPDirectiveKind DKind = S.getDirectiveKind(); + if (DKind == OMPD_for || DKind == OMPD_parallel_for || + DKind == OMPD_distribute_parallel_for) + OMPCancelStack.back().CodeGen = CodeGen; } void CodeGenFunction::EmitOMPForOuterLoop( @@ -1868,6 +1889,7 @@ void CodeGenFunction::EmitOMPDistributeO void CodeGenFunction::EmitOMPDistributeParallelForDirective( const OMPDistributeParallelForDirective &S) { OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); + OMPCancelStackRAII CancelRegion(*this); CGM.getOpenMPRuntime().emitInlinedDirective( *this, OMPD_distribute_parallel_for, [&S](CodeGenFunction &CGF, PrePostActionTy &) { @@ -2060,7 +2082,15 @@ bool CodeGenFunction::EmitOMPWorksharing [](CodeGenFunction &) {}); EmitBlock(LoopExit.getBlock()); // Tell the runtime we are done. - RT.emitForStaticFinish(*this, S.getLocStart()); + SourceLocation ELoc = S.getLocEnd(); + auto &&CodeGen = [ELoc](CodeGenFunction &CGF) { + CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, ELoc); + }; + CodeGen(*this); + OpenMPDirectiveKind DKind = S.getDirectiveKind(); + if (DKind == OMPD_for || DKind == OMPD_parallel_for || + DKind == OMPD_distribute_parallel_for) + OMPCancelStack.back().CodeGen = CodeGen; } else { const bool IsMonotonic = Ordered || ScheduleKind.Schedule == OMPC_SCHEDULE_static || @@ -2114,6 +2144,7 @@ void CodeGenFunction::EmitOMPForDirectiv }; { OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); + OMPCancelStackRAII CancelRegion(*this); CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen, S.hasCancel()); } @@ -2156,6 +2187,7 @@ void CodeGenFunction::EmitSections(const bool HasLastprivates = false; auto &&CodeGen = [&S, Stmt, CS, &HasLastprivates](CodeGenFunction &CGF, PrePostActionTy &) { + OMPCancelStackRAII CancelRegion(CGF); auto &C = CGF.CGM.getContext(); auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1); // Emit helper vars inits. @@ -2250,7 +2282,12 @@ void CodeGenFunction::EmitSections(const CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, &Cond, &Inc, BodyGen, [](CodeGenFunction &) {}); // Tell the runtime we are done. - CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocStart()); + SourceLocation ELoc = S.getLocEnd(); + auto &&FinalCodeGen = [ELoc](CodeGenFunction &CGF) { + CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, ELoc); + }; + FinalCodeGen(CGF); + CGF.OMPCancelStack.back().CodeGen = FinalCodeGen; CGF.EmitOMPReductionClauseFinal(S); // Emit post-update of the reduction variables if IsLastIter != 0. emitPostUpdateForReductionClause( @@ -2375,6 +2412,7 @@ void CodeGenFunction::EmitOMPParallelFor // Emit directive as a combined directive that consists of two implicit // directives: 'parallel' with 'for' directive. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { + OMPCancelStackRAII CancelRegion(CGF); CGF.EmitOMPWorksharingLoop(S); }; emitCommonOMPParallelDirective(*this, S, OMPD_for, CodeGen); @@ -3377,8 +3415,11 @@ CodeGenFunction::getOMPCancelDestination if (Kind == OMPD_parallel || Kind == OMPD_task) return ReturnBlock; assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections || - Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for); - return BreakContinueStack.back().BreakBlock; + Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for || + Kind == OMPD_distribute_parallel_for); + if (!OMPCancelStack.back().ExitBlock.isValid()) + OMPCancelStack.back().ExitBlock = getJumpDestInCurrentScope("cancel.exit"); + return OMPCancelStack.back().ExitBlock; } // Generate the instructions for '#pragma omp target data' directive. Modified: vendor/clang/dist/lib/CodeGen/CodeGenFunction.cpp ============================================================================== --- vendor/clang/dist/lib/CodeGen/CodeGenFunction.cpp Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/lib/CodeGen/CodeGenFunction.cpp Fri Nov 25 19:07:40 2016 (r309154) @@ -25,6 +25,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/StmtCXX.h" +#include "clang/AST/StmtObjC.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/TargetInfo.h" #include "clang/CodeGen/CGFunctionInfo.h" @@ -436,6 +437,23 @@ void CodeGenFunction::EmitMCountInstrume EmitNounwindRuntimeCall(MCountFn); } +// Returns the address space id that should be produced to the +// kernel_arg_addr_space metadata. This is always fixed to the ids +// as specified in the SPIR 2.0 specification in order to differentiate +// for example in clGetKernelArgInfo() implementation between the address +// spaces with targets without unique mapping to the OpenCL address spaces +// (basically all single AS CPUs). +static unsigned ArgInfoAddressSpace(unsigned LangAS) { + switch (LangAS) { + case LangAS::opencl_global: return 1; + case LangAS::opencl_constant: return 2; + case LangAS::opencl_local: return 3; + case LangAS::opencl_generic: return 4; // Not in SPIR 2.0 specs. + default: + return 0; // Assume private. + } +} + // OpenCL v1.2 s5.6.4.6 allows the compiler to store kernel argument // information in the program executable. The argument information stored // includes the argument name, its type, the address and access qualifiers used. @@ -476,7 +494,7 @@ static void GenOpenCLArgMetadata(const F // Get address qualifier. addressQuals.push_back(llvm::ConstantAsMetadata::get(Builder.getInt32( - ASTCtx.getTargetAddressSpace(pointeeTy.getAddressSpace())))); + ArgInfoAddressSpace(pointeeTy.getAddressSpace())))); // Get argument type name. std::string typeName = @@ -513,8 +531,7 @@ static void GenOpenCLArgMetadata(const F uint32_t AddrSpc = 0; bool isPipe = ty->isPipeType(); if (ty->isImageType() || isPipe) - AddrSpc = - CGM.getContext().getTargetAddressSpace(LangAS::opencl_global); + AddrSpc = ArgInfoAddressSpace(LangAS::opencl_global); addressQuals.push_back( llvm::ConstantAsMetadata::get(Builder.getInt32(AddrSpc))); @@ -1143,6 +1160,28 @@ bool CodeGenFunction::containsBreak(cons return false; } +bool CodeGenFunction::mightAddDeclToScope(const Stmt *S) { + if (!S) return false; + + // Some statement kinds add a scope and thus never add a decl to the current + // scope. Note, this list is longer than the list of statements that might + // have an unscoped decl nested within them, but this way is conservatively + // correct even if more statement kinds are added. + if (isa<IfStmt>(S) || isa<SwitchStmt>(S) || isa<WhileStmt>(S) || + isa<DoStmt>(S) || isa<ForStmt>(S) || isa<CompoundStmt>(S) || + isa<CXXForRangeStmt>(S) || isa<CXXTryStmt>(S) || + isa<ObjCForCollectionStmt>(S) || isa<ObjCAtTryStmt>(S)) + return false; + + if (isa<DeclStmt>(S)) + return true; + + for (const Stmt *SubStmt : S->children()) + if (mightAddDeclToScope(SubStmt)) + return true; + + return false; +} /// ConstantFoldsToSimpleInteger - If the specified expression does not fold /// to a constant, or if it does but contains a label, return false. If it Modified: vendor/clang/dist/lib/CodeGen/CodeGenFunction.h ============================================================================== --- vendor/clang/dist/lib/CodeGen/CodeGenFunction.h Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/lib/CodeGen/CodeGenFunction.h Fri Nov 25 19:07:40 2016 (r309154) @@ -965,6 +965,35 @@ private: }; SmallVector<BreakContinue, 8> BreakContinueStack; + /// Data for exit block for proper support of OpenMP cancellation constructs. + struct OMPCancel { + JumpDest ExitBlock; + llvm::function_ref<void(CodeGenFunction &CGF)> CodeGen; + OMPCancel() : CodeGen([](CodeGenFunction &CGF) {}) {} + }; + SmallVector<OMPCancel, 8> OMPCancelStack; + + /// Controls insertion of cancellation exit blocks in worksharing constructs. + class OMPCancelStackRAII { + CodeGenFunction &CGF; + + public: + OMPCancelStackRAII(CodeGenFunction &CGF) : CGF(CGF) { + CGF.OMPCancelStack.push_back({}); + } + ~OMPCancelStackRAII() { + if (CGF.HaveInsertPoint() && + CGF.OMPCancelStack.back().ExitBlock.isValid()) { + auto CJD = CGF.getJumpDestInCurrentScope("cancel.cont"); + CGF.EmitBranchThroughCleanup(CJD); + CGF.EmitBlock(CGF.OMPCancelStack.back().ExitBlock.getBlock()); + CGF.OMPCancelStack.back().CodeGen(CGF); + CGF.EmitBranchThroughCleanup(CJD); + CGF.EmitBlock(CJD.getBlock()); + } + } + }; + CodeGenPGO PGO; /// Calculate branch weights appropriate for PGO data @@ -3163,6 +3192,10 @@ public: /// If the statement (recursively) contains a switch or loop with a break /// inside of it, this is fine. static bool containsBreak(const Stmt *S); + + /// Determine if the given statement might introduce a declaration into the + /// current scope, by being a (possibly-labelled) DeclStmt. + static bool mightAddDeclToScope(const Stmt *S); /// ConstantFoldsToSimpleInteger - If the specified expression does not fold /// to a constant, or if it does but contains a label, return false. If it Modified: vendor/clang/dist/lib/Driver/ToolChains.cpp ============================================================================== --- vendor/clang/dist/lib/Driver/ToolChains.cpp Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/lib/Driver/ToolChains.cpp Fri Nov 25 19:07:40 2016 (r309154) @@ -688,13 +688,13 @@ void Darwin::AddDeploymentTarget(Derived assert(iOSVersion && "Unknown target platform!"); if (!Driver::GetReleaseVersion(iOSVersion->getValue(), Major, Minor, Micro, HadExtra) || - HadExtra || Major >= 10 || Minor >= 100 || Micro >= 100) + HadExtra || Major >= 100 || Minor >= 100 || Micro >= 100) getDriver().Diag(diag::err_drv_invalid_version_number) << iOSVersion->getAsString(Args); } else if (Platform == TvOS) { if (!Driver::GetReleaseVersion(TvOSVersion->getValue(), Major, Minor, Micro, HadExtra) || HadExtra || - Major >= 10 || Minor >= 100 || Micro >= 100) + Major >= 100 || Minor >= 100 || Micro >= 100) getDriver().Diag(diag::err_drv_invalid_version_number) << TvOSVersion->getAsString(Args); } else if (Platform == WatchOS) { Modified: vendor/clang/dist/lib/Driver/Tools.cpp ============================================================================== --- vendor/clang/dist/lib/Driver/Tools.cpp Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/lib/Driver/Tools.cpp Fri Nov 25 19:07:40 2016 (r309154) @@ -7637,23 +7637,23 @@ void darwin::Linker::AddLinkArgs(Compila CmdArgs.push_back("-object_path_lto"); CmdArgs.push_back(TmpPath); } + } - // Use -lto_library option to specify the libLTO.dylib path. Try to find - // it in clang installed libraries. If not found, the option is not used - // and 'ld' will use its default mechanism to search for libLTO.dylib. - if (Version[0] >= 133) { - // Search for libLTO in <InstalledDir>/../lib/libLTO.dylib - StringRef P = llvm::sys::path::parent_path(D.getInstalledDir()); - SmallString<128> LibLTOPath(P); - llvm::sys::path::append(LibLTOPath, "lib"); - llvm::sys::path::append(LibLTOPath, "libLTO.dylib"); - if (llvm::sys::fs::exists(LibLTOPath)) { - CmdArgs.push_back("-lto_library"); - CmdArgs.push_back(C.getArgs().MakeArgString(LibLTOPath)); - } else { - D.Diag(diag::warn_drv_lto_libpath); - } - } + // Use -lto_library option to specify the libLTO.dylib path. Try to find + // it in clang installed libraries. ld64 will only look at this argument + // when it actually uses LTO, so libLTO.dylib only needs to exist at link + // time if ld64 decides that it needs to use LTO. + // Since this is passed unconditionally, ld64 will never look for libLTO.dylib + // next to it. That's ok since ld64 using a libLTO.dylib not matching the + // clang version won't work anyways. + if (Version[0] >= 133) { + // Search for libLTO in <InstalledDir>/../lib/libLTO.dylib + StringRef P = llvm::sys::path::parent_path(D.Dir); + SmallString<128> LibLTOPath(P); + llvm::sys::path::append(LibLTOPath, "lib"); + llvm::sys::path::append(LibLTOPath, "libLTO.dylib"); + CmdArgs.push_back("-lto_library"); + CmdArgs.push_back(C.getArgs().MakeArgString(LibLTOPath)); } // Derived from the "link" spec. Modified: vendor/clang/dist/lib/Sema/Sema.cpp ============================================================================== --- vendor/clang/dist/lib/Sema/Sema.cpp Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/lib/Sema/Sema.cpp Fri Nov 25 19:07:40 2016 (r309154) @@ -1197,11 +1197,19 @@ BlockScopeInfo *Sema::getCurBlock() { return CurBSI; } -LambdaScopeInfo *Sema::getCurLambda() { +LambdaScopeInfo *Sema::getCurLambda(bool IgnoreCapturedRegions) { if (FunctionScopes.empty()) return nullptr; - auto CurLSI = dyn_cast<LambdaScopeInfo>(FunctionScopes.back()); + auto I = FunctionScopes.rbegin(); + if (IgnoreCapturedRegions) { + auto E = FunctionScopes.rend(); + while (I != E && isa<CapturedRegionScopeInfo>(*I)) + ++I; + if (I == E) + return nullptr; + } + auto *CurLSI = dyn_cast<LambdaScopeInfo>(*I); if (CurLSI && CurLSI->Lambda && !CurLSI->Lambda->Encloses(CurContext)) { // We have switched contexts due to template instantiation. Modified: vendor/clang/dist/lib/Sema/SemaCXXScopeSpec.cpp ============================================================================== --- vendor/clang/dist/lib/Sema/SemaCXXScopeSpec.cpp Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/lib/Sema/SemaCXXScopeSpec.cpp Fri Nov 25 19:07:40 2016 (r309154) @@ -806,7 +806,7 @@ bool Sema::BuildCXXNestedNameSpecifier(S if (!Found.empty()) { if (TypeDecl *TD = Found.getAsSingle<TypeDecl>()) Diag(IdentifierLoc, diag::err_expected_class_or_namespace) - << QualType(TD->getTypeForDecl(), 0) << getLangOpts().CPlusPlus; + << Context.getTypeDeclType(TD) << getLangOpts().CPlusPlus; else { Diag(IdentifierLoc, diag::err_expected_class_or_namespace) << &Identifier << getLangOpts().CPlusPlus; Modified: vendor/clang/dist/lib/Sema/SemaDecl.cpp ============================================================================== --- vendor/clang/dist/lib/Sema/SemaDecl.cpp Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/lib/Sema/SemaDecl.cpp Fri Nov 25 19:07:40 2016 (r309154) @@ -9615,7 +9615,8 @@ void Sema::AddInitializerToDecl(Decl *Re } VarDecl *Def; - if ((Def = VDecl->getDefinition()) && Def != VDecl) { + if ((Def = VDecl->getDefinition()) && Def != VDecl && + (!VDecl->isStaticDataMember() || VDecl->isOutOfLine())) { NamedDecl *Hidden = nullptr; if (!hasVisibleDefinition(Def, &Hidden) && (VDecl->getFormalLinkage() == InternalLinkage || Modified: vendor/clang/dist/lib/Sema/SemaExpr.cpp ============================================================================== --- vendor/clang/dist/lib/Sema/SemaExpr.cpp Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/lib/Sema/SemaExpr.cpp Fri Nov 25 19:07:40 2016 (r309154) @@ -4522,6 +4522,11 @@ ExprResult Sema::BuildCXXDefaultArgExpr( MutiLevelArgList.getInnermost()); if (Inst.isInvalid()) return ExprError(); + if (Inst.isAlreadyInstantiating()) { + Diag(Param->getLocStart(), diag::err_recursive_default_argument) << FD; + Param->setInvalidDecl(); + return ExprError(); + } ExprResult Result; { @@ -13880,7 +13885,8 @@ static void DoMarkVarDeclReferenced(Sema (SemaRef.CurContext != Var->getDeclContext() && Var->getDeclContext()->isFunctionOrMethod() && Var->hasLocalStorage()); if (RefersToEnclosingScope) { - if (LambdaScopeInfo *const LSI = SemaRef.getCurLambda()) { + if (LambdaScopeInfo *const LSI = + SemaRef.getCurLambda(/*IgnoreCapturedRegions=*/true)) { // If a variable could potentially be odr-used, defer marking it so // until we finish analyzing the full expression for any // lvalue-to-rvalue Modified: vendor/clang/dist/lib/Sema/SemaExprCXX.cpp ============================================================================== --- vendor/clang/dist/lib/Sema/SemaExprCXX.cpp Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/lib/Sema/SemaExprCXX.cpp Fri Nov 25 19:07:40 2016 (r309154) @@ -6582,10 +6582,16 @@ static inline bool VariableCanNeverBeACo static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures( Expr *const FE, LambdaScopeInfo *const CurrentLSI, Sema &S) { - assert(!S.isUnevaluatedContext()); - assert(S.CurContext->isDependentContext()); - assert(CurrentLSI->CallOperator == S.CurContext && + assert(!S.isUnevaluatedContext()); + assert(S.CurContext->isDependentContext()); +#ifndef NDEBUG + DeclContext *DC = S.CurContext; + while (DC && isa<CapturedDecl>(DC)) + DC = DC->getParent(); + assert( + CurrentLSI->CallOperator == DC && "The current call operator must be synchronized with Sema's CurContext"); +#endif // NDEBUG const bool IsFullExprInstantiationDependent = FE->isInstantiationDependent(); @@ -7051,7 +7057,8 @@ ExprResult Sema::ActOnFinishFullExpr(Exp // and then the full-expression +n + ({ 0; }); ends, but it's too late // for us to see that we need to capture n after all. - LambdaScopeInfo *const CurrentLSI = getCurLambda(); + LambdaScopeInfo *const CurrentLSI = + getCurLambda(/*IgnoreCapturedRegions=*/true); // FIXME: PR 17877 showed that getCurLambda() can return a valid pointer // even if CurContext is not a lambda call operator. Refer to that Bug Report // for an example of the code that might cause this asynchrony. @@ -7066,7 +7073,10 @@ ExprResult Sema::ActOnFinishFullExpr(Exp // constructor/destructor. // - Teach the handful of places that iterate over FunctionScopes to // stop at the outermost enclosing lexical scope." - const bool IsInLambdaDeclContext = isLambdaCallOperator(CurContext); + DeclContext *DC = CurContext; + while (DC && isa<CapturedDecl>(DC)) + DC = DC->getParent(); + const bool IsInLambdaDeclContext = isLambdaCallOperator(DC); if (IsInLambdaDeclContext && CurrentLSI && CurrentLSI->hasPotentialCaptures() && !FullExpr.isInvalid()) CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(FE, CurrentLSI, Modified: vendor/clang/dist/lib/Sema/SemaLambda.cpp ============================================================================== --- vendor/clang/dist/lib/Sema/SemaLambda.cpp Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/lib/Sema/SemaLambda.cpp Fri Nov 25 19:07:40 2016 (r309154) @@ -66,17 +66,20 @@ getStackIndexOfNearestEnclosingCaptureRe // Label failure to capture. const Optional<unsigned> NoLambdaIsCaptureReady; + // Ignore all inner captured regions. + unsigned CurScopeIndex = FunctionScopes.size() - 1; + while (CurScopeIndex > 0 && isa<clang::sema::CapturedRegionScopeInfo>( + FunctionScopes[CurScopeIndex])) + --CurScopeIndex; assert( - isa<clang::sema::LambdaScopeInfo>( - FunctionScopes[FunctionScopes.size() - 1]) && + isa<clang::sema::LambdaScopeInfo>(FunctionScopes[CurScopeIndex]) && "The function on the top of sema's function-info stack must be a lambda"); - + // If VarToCapture is null, we are attempting to capture 'this'. const bool IsCapturingThis = !VarToCapture; const bool IsCapturingVariable = !IsCapturingThis; // Start with the current lambda at the top of the stack (highest index). - unsigned CurScopeIndex = FunctionScopes.size() - 1; DeclContext *EnclosingDC = cast<sema::LambdaScopeInfo>(FunctionScopes[CurScopeIndex])->CallOperator; @@ -311,18 +314,21 @@ Sema::getCurrentMangleNumberContext(cons bool IsInNonspecializedTemplate = !ActiveTemplateInstantiations.empty() || CurContext->isDependentContext(); switch (Kind) { - case Normal: + case Normal: { // -- the bodies of non-exported nonspecialized template functions // -- the bodies of inline functions if ((IsInNonspecializedTemplate && !(ManglingContextDecl && isa<ParmVarDecl>(ManglingContextDecl))) || isInInlineFunction(CurContext)) { ManglingContextDecl = nullptr; + while (auto *CD = dyn_cast<CapturedDecl>(DC)) + DC = CD->getParent(); return &Context.getManglingNumberContext(DC); } ManglingContextDecl = nullptr; return nullptr; + } case StaticDataMember: // -- the initializers of nonspecialized static members of template classes Modified: vendor/clang/dist/lib/Sema/SemaOpenMP.cpp ============================================================================== --- vendor/clang/dist/lib/Sema/SemaOpenMP.cpp Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/lib/Sema/SemaOpenMP.cpp Fri Nov 25 19:07:40 2016 (r309154) @@ -9133,7 +9133,7 @@ OMPClause *Sema::ActOnOpenMPReductionCla // for all threads of the team. if (!ASE && !OASE && VD) { VarDecl *VDDef = VD->getDefinition(); - if (VD->getType()->isReferenceType() && VDDef) { + if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { DSARefChecker Check(DSAStack); if (Check.Visit(VDDef->getInit())) { Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange; @@ -10680,6 +10680,25 @@ static bool CheckMapConflicts( if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) break; } + // Check if the extra components of the expressions in the enclosing + // data environment are redundant for the current base declaration. + // If they are, the maps completely overlap, which is legal. + for (; SI != SE; ++SI) { + QualType Type; + if (auto *ASE = + dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { + Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); + } else if (auto *OASE = + dyn_cast<OMPArraySectionExpr>(SI->getAssociatedExpression())) { + auto *E = OASE->getBase()->IgnoreParenImpCasts(); + Type = + OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); + } + if (Type.isNull() || Type->isAnyPointerType() || + CheckArrayExpressionDoesNotReferToWholeSize( + SemaRef, SI->getAssociatedExpression(), Type)) + break; + } // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] // List items of map clauses in the same construct must not share Modified: vendor/clang/dist/lib/Sema/SemaTemplate.cpp ============================================================================== --- vendor/clang/dist/lib/Sema/SemaTemplate.cpp Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/lib/Sema/SemaTemplate.cpp Fri Nov 25 19:07:40 2016 (r309154) @@ -3256,7 +3256,7 @@ SubstDefaultTemplateArgument(Sema &SemaR // on the previously-computed template arguments. if (ArgType->getType()->isDependentType()) { Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, - Template, Converted, + Param, Template, Converted, SourceRange(TemplateLoc, RAngleLoc)); if (Inst.isInvalid()) return nullptr; @@ -3308,7 +3308,7 @@ SubstDefaultTemplateArgument(Sema &SemaR NonTypeTemplateParmDecl *Param, SmallVectorImpl<TemplateArgument> &Converted) { Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, - Template, Converted, + Param, Template, Converted, SourceRange(TemplateLoc, RAngleLoc)); if (Inst.isInvalid()) return ExprError(); @@ -3359,8 +3359,9 @@ SubstDefaultTemplateArgument(Sema &SemaR TemplateTemplateParmDecl *Param, SmallVectorImpl<TemplateArgument> &Converted, NestedNameSpecifierLoc &QualifierLoc) { - Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, Template, Converted, - SourceRange(TemplateLoc, RAngleLoc)); + Sema::InstantiatingTemplate Inst( + SemaRef, TemplateLoc, TemplateParameter(Param), Template, Converted, + SourceRange(TemplateLoc, RAngleLoc)); if (Inst.isInvalid()) return TemplateName(); @@ -3981,7 +3982,9 @@ bool Sema::CheckTemplateArgumentList(Tem } // Introduce an instantiation record that describes where we are using - // the default template argument. + // the default template argument. We're not actually instantiating a + // template here, we just create this object to put a note into the + // context stack. InstantiatingTemplate Inst(*this, RAngleLoc, Template, *Param, Converted, SourceRange(TemplateLoc, RAngleLoc)); if (Inst.isInvalid()) Modified: vendor/clang/dist/lib/Sema/SemaTemplateInstantiate.cpp ============================================================================== --- vendor/clang/dist/lib/Sema/SemaTemplateInstantiate.cpp Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/lib/Sema/SemaTemplateInstantiate.cpp Fri Nov 25 19:07:40 2016 (r309154) @@ -225,6 +225,10 @@ Sema::InstantiatingTemplate::Instantiati Inst.NumTemplateArgs = TemplateArgs.size(); Inst.DeductionInfo = DeductionInfo; Inst.InstantiationRange = InstantiationRange; + AlreadyInstantiating = + !SemaRef.InstantiatingSpecializations + .insert(std::make_pair(Inst.Entity->getCanonicalDecl(), Inst.Kind)) + .second; SemaRef.InNonInstantiationSFINAEContext = false; SemaRef.ActiveTemplateInstantiations.push_back(Inst); if (!Inst.isInstantiationRecord()) @@ -247,13 +251,14 @@ Sema::InstantiatingTemplate::Instantiati PointOfInstantiation, InstantiationRange, Entity) {} Sema::InstantiatingTemplate::InstantiatingTemplate( - Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateDecl *Template, - ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange) + Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateParameter Param, + TemplateDecl *Template, ArrayRef<TemplateArgument> TemplateArgs, + SourceRange InstantiationRange) : InstantiatingTemplate( SemaRef, ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation, - PointOfInstantiation, InstantiationRange, Template, nullptr, - TemplateArgs) {} + PointOfInstantiation, InstantiationRange, getAsNamedDecl(Param), + Template, TemplateArgs) {} Sema::InstantiatingTemplate::InstantiatingTemplate( Sema &SemaRef, SourceLocation PointOfInstantiation, @@ -263,7 +268,11 @@ Sema::InstantiatingTemplate::Instantiati sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange) : InstantiatingTemplate(SemaRef, Kind, PointOfInstantiation, InstantiationRange, FunctionTemplate, nullptr, - TemplateArgs, &DeductionInfo) {} + TemplateArgs, &DeductionInfo) { + assert( + Kind == ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution || + Kind == ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution); +} Sema::InstantiatingTemplate::InstantiatingTemplate( Sema &SemaRef, SourceLocation PointOfInstantiation, @@ -327,7 +336,8 @@ Sema::InstantiatingTemplate::Instantiati void Sema::InstantiatingTemplate::Clear() { if (!Invalid) { - if (!SemaRef.ActiveTemplateInstantiations.back().isInstantiationRecord()) { + auto &Active = SemaRef.ActiveTemplateInstantiations.back(); + if (!Active.isInstantiationRecord()) { assert(SemaRef.NonInstantiationEntries > 0); --SemaRef.NonInstantiationEntries; } @@ -345,6 +355,10 @@ void Sema::InstantiatingTemplate::Clear( SemaRef.ActiveTemplateInstantiationLookupModules.pop_back(); } + if (!AlreadyInstantiating) + SemaRef.InstantiatingSpecializations.erase( + std::make_pair(Active.Entity, Active.Kind)); + SemaRef.ActiveTemplateInstantiations.pop_back(); Invalid = true; } @@ -443,7 +457,7 @@ void Sema::PrintInstantiationStack() { } case ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation: { - TemplateDecl *Template = cast<TemplateDecl>(Active->Entity); + TemplateDecl *Template = cast<TemplateDecl>(Active->Template); SmallVector<char, 128> TemplateArgsStr; llvm::raw_svector_ostream OS(TemplateArgsStr); Template->printName(OS); @@ -1950,6 +1964,7 @@ Sema::InstantiateClass(SourceLocation Po InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation); if (Inst.isInvalid()) return true; + assert(!Inst.isAlreadyInstantiating() && "should have been caught by caller"); PrettyDeclStackTraceEntry CrashInfo(*this, Instantiation, SourceLocation(), "instantiating class definition"); @@ -2175,6 +2190,8 @@ bool Sema::InstantiateEnum(SourceLocatio InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation); if (Inst.isInvalid()) return true; + if (Inst.isAlreadyInstantiating()) + return false; PrettyDeclStackTraceEntry CrashInfo(*this, Instantiation, SourceLocation(), "instantiating enum definition"); @@ -2249,6 +2266,12 @@ bool Sema::InstantiateInClassInitializer InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation); if (Inst.isInvalid()) return true; + if (Inst.isAlreadyInstantiating()) { + // Error out if we hit an instantiation cycle for this initializer. + Diag(PointOfInstantiation, diag::err_in_class_initializer_cycle) + << Instantiation; + return true; + } PrettyDeclStackTraceEntry CrashInfo(*this, Instantiation, SourceLocation(), "instantiating default member init"); Modified: vendor/clang/dist/lib/Sema/SemaTemplateInstantiateDecl.cpp ============================================================================== --- vendor/clang/dist/lib/Sema/SemaTemplateInstantiateDecl.cpp Fri Nov 25 19:06:24 2016 (r309153) +++ vendor/clang/dist/lib/Sema/SemaTemplateInstantiateDecl.cpp Fri Nov 25 19:07:40 2016 (r309154) @@ -3360,6 +3360,13 @@ void Sema::InstantiateExceptionSpec(Sour UpdateExceptionSpec(Decl, EST_None); return; } + if (Inst.isAlreadyInstantiating()) { + // This exception specification indirectly depends on itself. Reject. + // FIXME: Corresponding rule in the standard? + Diag(PointOfInstantiation, diag::err_exception_spec_cycle) << Decl; + UpdateExceptionSpec(Decl, EST_None); + return; + } // Enter the scope of this instantiation. We don't use // PushDeclContext because we don't have a scope. @@ -3619,7 +3626,7 @@ void Sema::InstantiateFunctionDefinition } InstantiatingTemplate Inst(*this, PointOfInstantiation, Function); - if (Inst.isInvalid()) + if (Inst.isInvalid() || Inst.isAlreadyInstantiating()) return; PrettyDeclStackTraceEntry CrashInfo(*this, Function, SourceLocation(), *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"