diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-11-25 19:07:40 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-11-25 19:07:40 +0000 |
commit | 17c7957f023f02fc2c88f51f8908c19b52609275 (patch) | |
tree | c654618ff2d38e26916b49614d89fe01f4a4818d | |
parent | c477790a57f44875b9de2043f2eb47dff2d20133 (diff) |
Vendor import of clang release_39 branch r287912:vendor/clang/clang-release_39-r287912
Notes
Notes:
svn path=/vendor/clang/dist/; revision=309154
svn path=/vendor/clang/clang-release_39-r287912/; revision=309155; tag=vendor/clang/clang-release_39-r287912
68 files changed, 848 insertions, 185 deletions
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 4ac8cdc9beeb..d553e739c388 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -44,6 +44,8 @@ class VarTemplatePartialSpecializationDecl; 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 diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td index 6b8db6963daa..0a9b34827dc2 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.td +++ b/include/clang/Basic/DiagnosticDriverKinds.td @@ -159,8 +159,6 @@ def err_drv_bitcode_unsupported_on_toolchain : Error< "-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">, diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 1203fe765b52..3963f7581880 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -4291,7 +4291,7 @@ def err_definition_of_implicitly_declared_member : Error< 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_parsed 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; " diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 10a8a5ac538a..0d1c8fa48cdc 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -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); diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 7ec06bb17e3f..643e191fb01a 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -158,14 +158,25 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, // 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 llvm::Triple &Triple, 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: diff --git a/lib/Basic/Version.cpp b/lib/Basic/Version.cpp index c89e5d9b4bde..20050d2e4fae 100644 --- a/lib/Basic/Version.cpp +++ b/lib/Basic/Version.cpp @@ -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")); diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 3e1ae3604f94..5f3b290d8eb1 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -2105,12 +2105,11 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { 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::EmitUnaryOpLValue(const UnaryOperator *E) { 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: { diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index 77879021f9af..d815863e929d 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -1323,6 +1323,10 @@ static CSFC_Result CollectStatementsForCase(const Stmt *S, // 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 CollectStatementsForCase(const Stmt *S, // 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 CollectStatementsForCase(const Stmt *S, 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 CollectStatementsForCase(const Stmt *S, } } - 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 diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp index 26f780fdd7de..8937685fdc7b 100644 --- a/lib/CodeGen/CGStmtOpenMP.cpp +++ b/lib/CodeGen/CGStmtOpenMP.cpp @@ -232,8 +232,15 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) { 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::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) { 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(bool DynamicOrOrdered, bool IsMonotonic, 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::EmitOMPDistributeOuterLoop( 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::EmitOMPWorksharingLoop(const OMPLoopDirective &S) { [](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::EmitOMPForDirective(const OMPForDirective &S) { }; { 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 OMPExecutableDirective &S) { 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 OMPExecutableDirective &S) { 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::EmitOMPParallelForDirective( // 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(OpenMPDirectiveKind Kind) { 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. diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 183ee12ea232..11e4ad9ecefa 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -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::EmitMCountInstrumentation() { 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 FunctionDecl *FD, llvm::Function *Fn, // 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 FunctionDecl *FD, llvm::Function *Fn, 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(const Stmt *S) { 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 diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 45068fa55444..f61ba69e3a0c 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -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 diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 347aa29fde53..1b02f467c141 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -688,13 +688,13 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { 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) { diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 31d436018450..270ed0a4e756 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -7637,23 +7637,23 @@ void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args, 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. diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index a242ace9f64e..777747606304 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -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. diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp index ab0e709a97e7..949263d24897 100644 --- a/lib/Sema/SemaCXXScopeSpec.cpp +++ b/lib/Sema/SemaCXXScopeSpec.cpp @@ -806,7 +806,7 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *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; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index ea276a995d81..41719d4e7b08 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -9615,7 +9615,8 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, } 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 || diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index adcc38cbc4fd..719e1e3502ca 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -4522,6 +4522,11 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, 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, SourceLocation Loc, (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 diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index b7a968e09d4d..56f4019bfbb6 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -6582,10 +6582,16 @@ static inline bool VariableCanNeverBeAConstantExpression(VarDecl *Var, 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(Expr *FE, SourceLocation CC, // 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(Expr *FE, SourceLocation CC, // 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, diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp index 8a2bf929dfc0..0b3af262cd61 100644 --- a/lib/Sema/SemaLambda.cpp +++ b/lib/Sema/SemaLambda.cpp @@ -66,17 +66,20 @@ getStackIndexOfNearestEnclosingCaptureReadyLambda( // 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(const DeclContext *DC, 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 diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 3c8554893b43..b7ac48583e1a 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -9133,7 +9133,7 @@ OMPClause *Sema::ActOnOpenMPReductionClause( // 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 diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 7fc5db82d32c..72e499342f8f 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -3256,7 +3256,7 @@ SubstDefaultTemplateArgument(Sema &SemaRef, // 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 &SemaRef, 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 &SemaRef, 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(TemplateDecl *Template, } // 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()) diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 48c6a506ee36..65a5633bf0d5 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -225,6 +225,10 @@ Sema::InstantiatingTemplate::InstantiatingTemplate( 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::InstantiatingTemplate( 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::InstantiatingTemplate( 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::InstantiatingTemplate( 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 PointOfInstantiation, 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(SourceLocation PointOfInstantiation, 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"); diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 6a213953ec9a..dd3748fb5337 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -3360,6 +3360,13 @@ void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation, 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(SourceLocation PointOfInstantiation, } InstantiatingTemplate Inst(*this, PointOfInstantiation, Function); - if (Inst.isInvalid()) + if (Inst.isInvalid() || Inst.isAlreadyInstantiating()) return; PrettyDeclStackTraceEntry CrashInfo(*this, Function, SourceLocation(), "instantiating function definition"); @@ -3882,10 +3889,6 @@ void Sema::InstantiateVariableInitializer( else if (OldVar->isInline()) Var->setImplicitlyInline(); - if (Var->getAnyInitializer()) - // We already have an initializer in the class. - return; - if (OldVar->getInit()) { if (Var->isStaticDataMember() && !OldVar->isOutOfLine()) PushExpressionEvaluationContext(Sema::ConstantEvaluated, OldVar); @@ -3921,9 +3924,23 @@ void Sema::InstantiateVariableInitializer( } PopExpressionEvaluationContext(); - } else if ((!Var->isStaticDataMember() || Var->isOutOfLine()) && - !Var->isCXXForRangeDecl()) + } else { + if (Var->isStaticDataMember()) { + if (!Var->isOutOfLine()) + return; + + // If the declaration inside the class had an initializer, don't add + // another one to the out-of-line definition. + if (OldVar->getFirstDecl()->hasInit()) + return; + } + + // We'll add an initializer to a for-range declaration later. + if (Var->isCXXForRangeDecl()) + return; + ActOnUninitializedDecl(Var, false); + } } /// \brief Instantiate the definition of the given variable from its @@ -4013,7 +4030,7 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation, // FIXME: Factor out the duplicated instantiation context setup/tear down // code here. InstantiatingTemplate Inst(*this, PointOfInstantiation, Var); - if (Inst.isInvalid()) + if (Inst.isInvalid() || Inst.isAlreadyInstantiating()) return; PrettyDeclStackTraceEntry CrashInfo(*this, Var, SourceLocation(), "instantiating variable initializer"); @@ -4142,7 +4159,7 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation, } InstantiatingTemplate Inst(*this, PointOfInstantiation, Var); - if (Inst.isInvalid()) + if (Inst.isInvalid() || Inst.isAlreadyInstantiating()) return; PrettyDeclStackTraceEntry CrashInfo(*this, Var, SourceLocation(), "instantiating variable definition"); diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index d38a701c04b5..35da8f3ebcfe 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -2220,7 +2220,7 @@ void ASTDeclReader::VisitStaticAssertDecl(StaticAssertDecl *D) { VisitDecl(D); D->AssertExprAndFailed.setPointer(Reader.ReadExpr(F)); D->AssertExprAndFailed.setInt(Record[Idx++]); - D->Message = cast<StringLiteral>(Reader.ReadExpr(F)); + D->Message = cast_or_null<StringLiteral>(Reader.ReadExpr(F)); D->RParenLoc = ReadSourceLocation(Record, Idx); } diff --git a/test/CodeGenCXX/PR28523.cpp b/test/CodeGenCXX/PR28523.cpp new file mode 100644 index 000000000000..4c3a81c8b854 --- /dev/null +++ b/test/CodeGenCXX/PR28523.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -std=c++14 -verify -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s +// expected-no-diagnostics + +template <class F> void parallel_loop(F &&f) { f(0); } + +//CHECK-LABEL: @main +int main() { +// CHECK: [[X_ADDR:%.+]] = alloca i32, + int x; +// CHECK: getelementptr inbounds +// CHECK: store i32* [[X_ADDR]], i32** % +// CHECK: call + parallel_loop([&](auto y) { +#pragma clang __debug captured + { + x = y; + }; + }); +} diff --git a/test/CodeGenCXX/captured-statements.cpp b/test/CodeGenCXX/captured-statements.cpp index fdda24fcf301..4b95503ad7b3 100644 --- a/test/CodeGenCXX/captured-statements.cpp +++ b/test/CodeGenCXX/captured-statements.cpp @@ -78,6 +78,7 @@ void test3(int x) { { x = [=]() { return x + 1; } (); } + x = [=]() { return x + 1; }(); // CHECK-3: %[[Capture:struct\.anon[\.0-9]*]] = type { i32* } diff --git a/test/CodeGenCXX/switch-case-folding-2.cpp b/test/CodeGenCXX/switch-case-folding-2.cpp index 558ca3c87d9b..cfb8447ee326 100644 --- a/test/CodeGenCXX/switch-case-folding-2.cpp +++ b/test/CodeGenCXX/switch-case-folding-2.cpp @@ -1,12 +1,14 @@ // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s -// CHECK that we don't crash. extern int printf(const char*, ...); + +// CHECK-LABEL: @_Z4testi( int test(int val){ switch (val) { case 4: do { switch (6) { + // CHECK: call i32 (i8*, ...) @_Z6printfPKcz case 6: do { case 5: printf("bad\n"); } while (0); }; } while (0); @@ -18,6 +20,7 @@ int main(void) { return test(5); } +// CHECK-LABEL: @_Z10other_testv( void other_test() { switch(0) { case 0: @@ -27,4 +30,79 @@ void other_test() { } } -// CHECK: call i32 (i8*, ...) @_Z6printfPKcz +struct X { X(); ~X(); }; + +void dont_call(); +void foo(); + +// CHECK-LABEL: @_Z13nested_scopesv( +void nested_scopes() { + switch (1) { + case 0: + // CHECK-NOT: @_Z9dont_callv( + dont_call(); + break; + + default: + // CHECK: call {{.*}} @_ZN1XC1Ev( + // CHECK: call {{.*}} @_Z3foov( + // CHECK-NOT: call {{.*}} @_Z3foov( + // CHECK: call {{.*}} @_ZN1XD1Ev( + { X x; foo(); } + + // CHECK: call {{.*}} @_ZN1XC1Ev( + // CHECK: call {{.*}} @_Z3foov( + // CHECK: call {{.*}} @_ZN1XD1Ev( + { X x; foo(); } + + // CHECK: call {{.*}} @_ZN1XC1Ev( + // CHECK: call {{.*}} @_Z3foov( + // CHECK: call {{.*}} @_ZN1XD1Ev( + { X x; foo(); } + break; + } +} + +// CHECK-LABEL: @_Z17scope_fallthroughv( +void scope_fallthrough() { + switch (1) { + // CHECK: call {{.*}} @_ZN1XC1Ev( + // CHECK-NOT: call {{.*}} @_Z3foov( + // CHECK: call {{.*}} @_ZN1XD1Ev( + { default: X x; } + // CHECK: call {{.*}} @_Z3foov( + foo(); + break; + } +} + +// CHECK-LABEL: @_Z12hidden_breakb( +void hidden_break(bool b) { + switch (1) { + default: + // CHECK: br + if (b) + break; + // CHECK: call {{.*}} @_Z3foov( + foo(); + break; + } +} + +// CHECK-LABEL: @_Z10hidden_varv( +int hidden_var() { + switch (1) { + // CHECK: %[[N:.*]] = alloca i32 + case 0: int n; + // CHECK: store i32 0, i32* %[[N]] + // CHECK: load i32, i32* %[[N]] + // CHECK: ret + default: n = 0; return n; + } +} + +// CHECK-LABEL: @_Z13case_in_labelv( +void case_in_label() { + // CHECK: br label % + switch (1) case 1: foo: case 0: goto foo; +} diff --git a/test/CodeGenOpenCL/kernel-arg-info-single-as.cl b/test/CodeGenOpenCL/kernel-arg-info-single-as.cl new file mode 100644 index 000000000000..595c97464e3a --- /dev/null +++ b/test/CodeGenOpenCL/kernel-arg-info-single-as.cl @@ -0,0 +1,9 @@ +// Test that the kernel argument info always refers to SPIR address spaces, +// even if the target has only one address space like x86_64 does. +// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -triple x86_64-unknown-unknown -cl-kernel-arg-info | FileCheck %s + +kernel void foo(__global int * G, __constant int *C, __local int *L) { + *G = *C + *L; +} +// CHECK: !kernel_arg_addr_space ![[MD123:[0-9]+]] +// CHECK: ![[MD123]] = !{i32 1, i32 2, i32 3} diff --git a/test/Driver/darwin-ld-lto.c b/test/Driver/darwin-ld-lto.c index 23e006a01850..6b9b79bd011a 100644 --- a/test/Driver/darwin-ld-lto.c +++ b/test/Driver/darwin-ld-lto.c @@ -1,25 +1,16 @@ // REQUIRES: system-darwin -// Check that ld gets "-lto_library" and warnings about libLTO.dylib path. +// Check that ld gets "-lto_library". // RUN: %clang -target x86_64-apple-darwin10 -### %s \ -// RUN: -mlinker-version=133 -flto 2> %t.log -// RUN: cat %t.log -// RUN: FileCheck -check-prefix=LINK_LTOLIB_PATH %s < %t.log +// RUN: -ccc-install-dir %T/bin -mlinker-version=133 2> %t.log +// RUN: FileCheck -check-prefix=LINK_LTOLIB_PATH %s -input-file %t.log // // LINK_LTOLIB_PATH: {{ld(.exe)?"}} // LINK_LTOLIB_PATH: "-lto_library" +// Also pass -lto_library even if the file doesn't exist; if it's needed at +// link time, ld will complain instead. // RUN: %clang -target x86_64-apple-darwin10 -### %s \ -// RUN: -ccc-install-dir %S/dummytestdir -mlinker-version=133 -flto 2> %t.log -// RUN: cat %t.log -// RUN: FileCheck -check-prefix=LINK_LTOLIB_PATH_WRN %s < %t.log -// -// LINK_LTOLIB_PATH_WRN: warning: libLTO.dylib relative to clang installed dir not found; using 'ld' default search path instead - -// RUN: %clang -target x86_64-apple-darwin10 -### %s \ -// RUN: -ccc-install-dir %S/dummytestdir -mlinker-version=133 -Wno-liblto -flto 2> %t.log -// RUN: cat %t.log -// RUN: FileCheck -check-prefix=LINK_LTOLIB_PATH_NOWRN %s < %t.log -// -// LINK_LTOLIB_PATH_NOWRN-NOT: warning: libLTO.dylib relative to clang installed dir not found; using 'ld' default search path instead +// RUN: -ccc-install-dir %S/dummytestdir -mlinker-version=133 2> %t.log +// RUN: FileCheck -check-prefix=LINK_LTOLIB_PATH %s -input-file %t.log diff --git a/test/Frontend/darwin-version.c b/test/Frontend/darwin-version.c index e7bc41117e3f..eb05a48cfd36 100644 --- a/test/Frontend/darwin-version.c +++ b/test/Frontend/darwin-version.c @@ -10,6 +10,8 @@ // RUN: %clang_cc1 -triple armv6-apple-ios2.3.1 -dM -E -o %t %s // RUN: grep '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__' %t | grep '20301' | count 1 // RUN: not grep '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' %t +// RUN: %clang_cc1 -triple armv7-apple-ios10.1.2 -dM -E -o %t %s +// RUN: grep '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__' %t | grep '100102' | count 1 // RUN: %clang_cc1 -triple i386-apple-macosx10.4.0 -dM -E -o %t %s // RUN: grep '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' %t | grep '1040' | count 1 // RUN: not grep '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__' %t @@ -32,6 +34,8 @@ // RUN: grep '__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__' %t | grep '80300' | count 1 // RUN: not grep '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' %t // RUN: not grep '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__' %t +// RUN: %clang_cc1 -triple arm64-apple-tvos10.2.3 -dM -E -o %t %s +// RUN: grep '__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__' %t | grep '100203' | count 1 // RUN: %clang_cc1 -triple x86_64-apple-tvos8.3 -dM -E -o %t %s // RUN: grep '__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__' %t | grep '80300' | count 1 diff --git a/test/Modules/Inputs/static_assert/a.h b/test/Modules/Inputs/static_assert/a.h new file mode 100644 index 000000000000..e876df06d066 --- /dev/null +++ b/test/Modules/Inputs/static_assert/a.h @@ -0,0 +1,3 @@ +class S { + static_assert(4 == 4); +}; diff --git a/test/Modules/Inputs/static_assert/module.modulemap b/test/Modules/Inputs/static_assert/module.modulemap new file mode 100644 index 000000000000..bb00c840ce39 --- /dev/null +++ b/test/Modules/Inputs/static_assert/module.modulemap @@ -0,0 +1 @@ +module a { header "a.h" } diff --git a/test/Modules/static_assert.cpp b/test/Modules/static_assert.cpp new file mode 100644 index 000000000000..d1b759073cd5 --- /dev/null +++ b/test/Modules/static_assert.cpp @@ -0,0 +1,8 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps \ +// RUN: -I%S/Inputs/static_assert -std=c++1z -verify %s +// expected-no-diagnostics + +#include "a.h" + +S s; diff --git a/test/OpenMP/atomic_write_codegen.c b/test/OpenMP/atomic_write_codegen.c index 66172af07e8f..050d7a510566 100644 --- a/test/OpenMP/atomic_write_codegen.c +++ b/test/OpenMP/atomic_write_codegen.c @@ -78,6 +78,9 @@ float2 float2x; register int rix __asm__("esp"); int main() { +// CHECK: store atomic i32 1, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @civ, i32 0, i32 1) monotonic, +#pragma omp atomic write + __imag(civ) = 1; // CHECK: load i8, i8* // CHECK: store atomic i8 #pragma omp atomic write diff --git a/test/OpenMP/cancel_codegen.cpp b/test/OpenMP/cancel_codegen.cpp index 8234193e8f95..059a8d3901f4 100644 --- a/test/OpenMP/cancel_codegen.cpp +++ b/test/OpenMP/cancel_codegen.cpp @@ -91,9 +91,11 @@ for (int i = 0; i < argc; ++i) { } } // CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( -#pragma omp parallel for +int r = 0; +#pragma omp parallel for reduction(+:r) for (int i = 0; i < argc; ++i) { #pragma omp cancel for + r += i; } // CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( return argc; @@ -164,6 +166,9 @@ for (int i = 0; i < argc; ++i) { // CHECK: [[CONTINUE]] // CHECK: br label // CHECK: call void @__kmpc_for_static_fini( +// CHECK: call i32 @__kmpc_reduce_nowait( +// CHECK: call void @__kmpc_end_reduce_nowait( +// CHECK: call void @__kmpc_for_static_fini( // CHECK: ret void #endif diff --git a/test/OpenMP/debug-info-openmp-array.cpp b/test/OpenMP/debug-info-openmp-array.cpp new file mode 100644 index 000000000000..19bf2a284ad6 --- /dev/null +++ b/test/OpenMP/debug-info-openmp-array.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fopenmp -x c++ %s -verify -debug-info-kind=limited -emit-llvm -o - | FileCheck %s +// expected-no-diagnostics + +void f(int m) { + int i; + int cen[m]; +#pragma omp parallel for + for (i = 0; i < m; ++i) { + cen[i] = i; + } +} + +// CHECK: !DILocalVariable(name: "cen", arg: 6 diff --git a/test/OpenMP/distribute_parallel_for_reduction_messages.cpp b/test/OpenMP/distribute_parallel_for_reduction_messages.cpp index f23a25e28c02..95654a9e5018 100644 --- a/test/OpenMP/distribute_parallel_for_reduction_messages.cpp +++ b/test/OpenMP/distribute_parallel_for_reduction_messages.cpp @@ -9,6 +9,14 @@ bool foobool(int argc) { return argc; } +void foobar(int &ref) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for reduction(+:ref) + for (int i = 0; i < 10; ++i) + foo(); +} + struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} extern S1 a; class S2 { diff --git a/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp index 7b7e9ea53ccb..6ad41d72bf78 100644 --- a/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp +++ b/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp @@ -9,6 +9,14 @@ bool foobool(int argc) { return argc; } +void foobar(int &ref) { +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd reduction(+:ref) + for (int i = 0; i < 10; ++i) + foo(); +} + struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} extern S1 a; class S2 { diff --git a/test/OpenMP/distribute_simd_reduction_messages.cpp b/test/OpenMP/distribute_simd_reduction_messages.cpp index e03b85292808..fca3e85a7104 100644 --- a/test/OpenMP/distribute_simd_reduction_messages.cpp +++ b/test/OpenMP/distribute_simd_reduction_messages.cpp @@ -9,6 +9,14 @@ bool foobool(int argc) { return argc; } +void foobar(int &ref) { +#pragma omp target +#pragma omp teams +#pragma omp distribute simd reduction(+:ref) + for (int i = 0; i < 10; ++i) + foo(); +} + struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} extern S1 a; class S2 { diff --git a/test/OpenMP/for_lastprivate_codegen.cpp b/test/OpenMP/for_lastprivate_codegen.cpp index 2b1d6c3cf97f..75f59f7d406d 100644 --- a/test/OpenMP/for_lastprivate_codegen.cpp +++ b/test/OpenMP/for_lastprivate_codegen.cpp @@ -41,7 +41,7 @@ struct SS { for (a = 0; a < 2; ++a) #ifdef LAMBDA [&]() { - ++this->a, --b, (this)->c /= 1; + --this->a, ++b, (this)->c *= 2; #pragma omp parallel #pragma omp for lastprivate(b) for (b = 0; b < 2; ++b) @@ -190,7 +190,7 @@ int main() { // LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void // LAMBDA: call void @__kmpc_for_static_init_4( // LAMBDA-NOT: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 - // LAMBDA: call void {{.+}} [[SS_LAMBDA:@[^ ]+]] + // LAMBDA: call{{.*}} void [[SS_LAMBDA1:@[^ ]+]] // LAMBDA: call void @__kmpc_for_static_fini(% // LAMBDA: ret @@ -200,7 +200,7 @@ int main() { // LAMBDA: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 2 // LAMBDA: call void @__kmpc_for_static_init_4( // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* - // LAMBDA: call{{.*}} void + // LAMBDA: call{{.*}} void [[SS_LAMBDA:@[^ ]+]] // LAMBDA: call void @__kmpc_for_static_fini( // LAMBDA: br i1 // LAMBDA: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1 @@ -236,6 +236,9 @@ int main() { // LAMBDA: br label // LAMBDA: ret void + // LAMBDA: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}) + // LAMBDA: ret void + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) [[SIVAR:%.+]]) // LAMBDA: alloca i{{[0-9]+}}, // LAMBDA: alloca i{{[0-9]+}}, diff --git a/test/OpenMP/for_reduction_codegen.cpp b/test/OpenMP/for_reduction_codegen.cpp index 6997d8138842..5dcc4b2622b2 100644 --- a/test/OpenMP/for_reduction_codegen.cpp +++ b/test/OpenMP/for_reduction_codegen.cpp @@ -492,7 +492,7 @@ int main() { // CHECK: store float [[UP]], float* [[T_VAR1_LHS]], // CHECK: ret void -// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* nonnull %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(160) %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(160) %{{.+}}) // Reduction list for runtime. // CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*], @@ -696,7 +696,7 @@ int main() { // CHECK: ret void -// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* nonnull %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(160) %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(160) %{{.+}}) // CHECK: [[ARRS_PRIV:%.+]] = alloca [10 x [4 x [[S_FLOAT_TY]]]], diff --git a/test/OpenMP/for_reduction_codegen_UDR.cpp b/test/OpenMP/for_reduction_codegen_UDR.cpp index a30df368663d..da384294e238 100644 --- a/test/OpenMP/for_reduction_codegen_UDR.cpp +++ b/test/OpenMP/for_reduction_codegen_UDR.cpp @@ -301,7 +301,7 @@ int main() { // CHECK: fadd float 5.550000e+02, % // CHECK: ret void -// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* nonnull %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(480) %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(480) %{{.+}}) // Reduction list for runtime. // CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*], @@ -500,7 +500,7 @@ int main() { // CHECK: ret void -// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* nonnull %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(480) %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(480) %{{.+}}) // CHECK: [[ARRS_PRIV:%.+]] = alloca [10 x [4 x [[S_FLOAT_TY]]]], diff --git a/test/OpenMP/for_reduction_messages.cpp b/test/OpenMP/for_reduction_messages.cpp index 45a4681440fc..bb70ecc2b23e 100644 --- a/test/OpenMP/for_reduction_messages.cpp +++ b/test/OpenMP/for_reduction_messages.cpp @@ -9,6 +9,13 @@ bool foobool(int argc) { return argc; } +void foobar(int &ref) { +#pragma omp parallel +#pragma omp for reduction(+:ref) + for (int i = 0; i < 10; ++i) + foo(); +} + struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} extern S1 a; class S2 { diff --git a/test/OpenMP/for_simd_reduction_messages.cpp b/test/OpenMP/for_simd_reduction_messages.cpp index 2935cec602dd..485070e758ae 100644 --- a/test/OpenMP/for_simd_reduction_messages.cpp +++ b/test/OpenMP/for_simd_reduction_messages.cpp @@ -9,6 +9,13 @@ bool foobool(int argc) { return argc; } +void foobar(int &ref) { +#pragma omp parallel +#pragma omp for simd reduction(+:ref) + for (int i = 0; i < 10; ++i) + foo(); +} + struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} extern S1 a; class S2 { diff --git a/test/OpenMP/parallel_codegen.cpp b/test/OpenMP/parallel_codegen.cpp index 04c5c2c85ae2..41a050100bd0 100644 --- a/test/OpenMP/parallel_codegen.cpp +++ b/test/OpenMP/parallel_codegen.cpp @@ -11,7 +11,7 @@ // CHECK-DEBUG-DAG: %ident_t = type { i32, i32, i32, i32, i8* } // CHECK-DEBUG-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00" // CHECK-DEBUG-DAG: [[DEF_LOC_2:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) } -// CHECK-DEBUG-DAG: [[LOC1:@.+]] = private unnamed_addr constant [{{.+}} x i8] c";{{.*}}parallel_codegen.cpp;main;[[@LINE+14]];9;;\00" +// CHECK-DEBUG-DAG: [[LOC1:@.+]] = private unnamed_addr constant [{{.+}} x i8] c";{{.*}}parallel_codegen.cpp;main;[[@LINE+15]];9;;\00" // CHECK-DEBUG-DAG: [[LOC2:@.+]] = private unnamed_addr constant [{{.+}} x i8] c";{{.*}}parallel_codegen.cpp;tmain;[[@LINE+7]];9;;\00" template <class T> @@ -25,17 +25,19 @@ int tmain(T argc) { } int main (int argc, char **argv) { + int a[argc]; #pragma omp parallel - foo(argc); + foo(a[1]); return tmain(argv); } // CHECK-LABEL: define {{[a-z\_\b]*[ ]?i32}} @main({{i32[ ]?[a-z]*}} %argc, i8** %argv) // CHECK: store i32 %argc, i32* [[ARGC_ADDR:%.+]], -// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i32* [[ARGC_ADDR]]) +// CHECK: [[VLA:%.+]] = alloca i32, i{{[0-9]+}} [[VLA_SIZE:%[^,]+]], +// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i{{[0-9]+}}, i32*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i{{[0-9]+}} [[VLA_SIZE]], i32* [[VLA]]) // CHECK-NEXT: [[ARGV:%.+]] = load i8**, i8*** {{%[a-z0-9.]+}} // CHECK-NEXT: [[RET:%.+]] = call {{[a-z\_\b]*[ ]?i32}} [[TMAIN:@.+tmain.+]](i8** [[ARGV]]) -// CHECK-NEXT: ret i32 [[RET]] +// CHECK: ret i32 // CHECK-NEXT: } // CHECK-DEBUG-LABEL: define i32 @main(i32 %argc, i8** %argv) // CHECK-DEBUG: [[LOC_2_ADDR:%.+]] = alloca %ident_t @@ -43,30 +45,33 @@ int main (int argc, char **argv) { // CHECK-DEBUG-NEXT: [[KMPC_DEFAULT_LOC_VOIDPTR:%.+]] = bitcast %ident_t* [[DEF_LOC_2]] to i8* // CHECK-DEBUG-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[KMPC_LOC_VOIDPTR]], i8* [[KMPC_DEFAULT_LOC_VOIDPTR]], i64 24, i32 8, i1 false) // CHECK-DEBUG: store i32 %argc, i32* [[ARGC_ADDR:%.+]], +// CHECK-DEBUG: [[VLA:%.+]] = alloca i32, i64 [[VLA_SIZE:%[^,]+]], // CHECK-DEBUG: [[KMPC_LOC_PSOURCE_REF:%.+]] = getelementptr inbounds %ident_t, %ident_t* [[LOC_2_ADDR]], i32 0, i32 4 // CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.+}} x i8], [{{.+}} x i8]* [[LOC1]], i32 0, i32 0), i8** [[KMPC_LOC_PSOURCE_REF]] -// CHECK-DEBUG: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i32* [[ARGC_ADDR]]) +// CHECK-DEBUG: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64, i32*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i64 [[VLA_SIZE]], i32* [[VLA]]) // CHECK-DEBUG-NEXT: [[ARGV:%.+]] = load i8**, i8*** {{%[a-z0-9.]+}} // CHECK-DEBUG-NEXT: [[RET:%.+]] = call i32 [[TMAIN:@.+tmain.+]](i8** [[ARGV]]) -// CHECK-DEBUG-NEXT: ret i32 [[RET]] +// CHECK-DEBUG: ret i32 // CHECK-DEBUG-NEXT: } -// CHECK: define internal {{.*}}void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) [[ARGC_ADDR:%[^)]+]]) +// CHECK: define internal {{.*}}void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i{{[0-9]+}}{{.*}} [[VLA_SIZE:%.+]], i32* [[VLA_ADDR:%[^)]+]]) // CHECK-SAME: #[[FN_ATTRS:[0-9]+]] -// CHECK: store i32* [[ARGC_ADDR]], i32** [[ARGC_PTR_ADDR:%.+]], -// CHECK: [[ARGC_REF:%.+]] = load i32*, i32** [[ARGC_PTR_ADDR]] -// CHECK-NEXT: [[ARGC:%.+]] = load i32, i32* [[ARGC_REF]] -// CHECK-NEXT: invoke {{.*}}void [[FOO:@.+foo.+]](i32{{[ ]?[a-z]*}} [[ARGC]]) +// CHECK: store i32* [[VLA_ADDR]], i32** [[VLA_PTR_ADDR:%.+]], +// CHECK: [[VLA_REF:%.+]] = load i32*, i32** [[VLA_PTR_ADDR]] +// CHECK: [[VLA_ELEM_REF:%.+]] = getelementptr inbounds i32, i32* [[VLA_REF]], i{{[0-9]+}} 1 +// CHECK-NEXT: [[VLA_ELEM:%.+]] = load i32, i32* [[VLA_ELEM_REF]] +// CHECK-NEXT: invoke {{.*}}void [[FOO:@.+foo.+]](i32{{[ ]?[a-z]*}} [[VLA_ELEM]]) // CHECK: ret void // CHECK: call {{.*}}void @{{.+terminate.*|abort}}( // CHECK-NEXT: unreachable // CHECK-NEXT: } -// CHECK-DEBUG: define internal void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) [[ARGC_ADDR:%[^)]+]]) +// CHECK-DEBUG: define internal void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i64 [[VLA_SIZE:%.+]], i32* [[VLA_ADDR:%[^)]+]]) // CHECK-DEBUG-SAME: #[[FN_ATTRS:[0-9]+]] -// CHECK-DEBUG: store i32* [[ARGC_ADDR]], i32** [[ARGC_PTR_ADDR:%.+]], -// CHECK-DEBUG: [[ARGC_REF:%.+]] = load i32*, i32** [[ARGC_PTR_ADDR]] -// CHECK-DEBUG-NEXT: [[ARGC:%.+]] = load i32, i32* [[ARGC_REF]] -// CHECK-DEBUG-NEXT: invoke void [[FOO:@.+foo.+]](i32 [[ARGC]]) +// CHECK-DEBUG: store i32* [[VLA_ADDR]], i32** [[VLA_PTR_ADDR:%.+]], +// CHECK-DEBUG: [[VLA_REF:%.+]] = load i32*, i32** [[VLA_PTR_ADDR]] +// CHECK-DEBUG: [[VLA_ELEM_REF:%.+]] = getelementptr inbounds i32, i32* [[VLA_REF]], i64 1 +// CHECK-DEBUG-NEXT: [[VLA_ELEM:%.+]] = load i32, i32* [[VLA_ELEM_REF]] +// CHECK-DEBUG-NEXT: invoke void [[FOO:@.+foo.+]](i32 [[VLA_ELEM]]) // CHECK-DEBUG: ret void // CHECK-DEBUG: call void @{{.+terminate.*|abort}}( // CHECK-DEBUG-NEXT: unreachable diff --git a/test/OpenMP/parallel_for_reduction_messages.cpp b/test/OpenMP/parallel_for_reduction_messages.cpp index 4d5a143bae3a..57ab1fac9c11 100644 --- a/test/OpenMP/parallel_for_reduction_messages.cpp +++ b/test/OpenMP/parallel_for_reduction_messages.cpp @@ -9,6 +9,12 @@ bool foobool(int argc) { return argc; } +void foobar(int &ref) { +#pragma omp parallel for reduction(+:ref) + for (int i = 0; i < 10; ++i) + foo(); +} + struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} extern S1 a; class S2 { diff --git a/test/OpenMP/parallel_for_simd_reduction_messages.cpp b/test/OpenMP/parallel_for_simd_reduction_messages.cpp index afb0b367c419..60a947dd5f84 100644 --- a/test/OpenMP/parallel_for_simd_reduction_messages.cpp +++ b/test/OpenMP/parallel_for_simd_reduction_messages.cpp @@ -9,6 +9,12 @@ bool foobool(int argc) { return argc; } +void foobar(int &ref) { +#pragma omp parallel for simd reduction(+:ref) + for (int i = 0; i < 10; ++i) + foo(); +} + struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} extern S1 a; class S2 { diff --git a/test/OpenMP/parallel_reduction_messages.cpp b/test/OpenMP/parallel_reduction_messages.cpp index af1f5ed7bc0d..947353fc2dd4 100644 --- a/test/OpenMP/parallel_reduction_messages.cpp +++ b/test/OpenMP/parallel_reduction_messages.cpp @@ -9,6 +9,11 @@ bool foobool(int argc) { return argc; } +void foobar(int &ref) { +#pragma omp parallel reduction(+:ref) + foo(); +} + struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} extern S1 a; class S2 { diff --git a/test/OpenMP/parallel_sections_reduction_messages.cpp b/test/OpenMP/parallel_sections_reduction_messages.cpp index 52d4cb9cdcb6..05cc7f0f6c5f 100644 --- a/test/OpenMP/parallel_sections_reduction_messages.cpp +++ b/test/OpenMP/parallel_sections_reduction_messages.cpp @@ -9,6 +9,13 @@ bool foobool(int argc) { return argc; } +void foobar(int &ref) { +#pragma omp parallel sections reduction(+:ref) + { + foo(); + } +} + struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} extern S1 a; class S2 { diff --git a/test/OpenMP/sections_reduction_messages.cpp b/test/OpenMP/sections_reduction_messages.cpp index 134bf619c911..f13c5b3f2862 100644 --- a/test/OpenMP/sections_reduction_messages.cpp +++ b/test/OpenMP/sections_reduction_messages.cpp @@ -9,6 +9,14 @@ bool foobool(int argc) { return argc; } +void foobar(int &ref) { +#pragma omp parallel +#pragma omp sections reduction(+:ref) + { + foo(); + } +} + struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} extern S1 a; class S2 { diff --git a/test/OpenMP/simd_reduction_messages.cpp b/test/OpenMP/simd_reduction_messages.cpp index c47d53eb9185..1e1a233ec499 100644 --- a/test/OpenMP/simd_reduction_messages.cpp +++ b/test/OpenMP/simd_reduction_messages.cpp @@ -9,6 +9,12 @@ bool foobool(int argc) { return argc; } +void foobar(int &ref) { +#pragma omp simd reduction(+:ref) + for (int i = 0; i < 10; ++i) + foo(); +} + struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} extern S1 a; class S2 { diff --git a/test/OpenMP/target_firstprivate_codegen.cpp b/test/OpenMP/target_firstprivate_codegen.cpp index ca459e02a425..a9af2d02f237 100644 --- a/test/OpenMP/target_firstprivate_codegen.cpp +++ b/test/OpenMP/target_firstprivate_codegen.cpp @@ -222,7 +222,7 @@ int foo(int n, double *ptr) { // make sure that firstprivate variables are generated in all cases and that we use those instances for operations inside the // target region - // TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A2_IN:%.+]], [10 x float]* {{.+}} [[B_IN:%.+]], i{{[0-9]+}} [[BN_SZ:%.+]], float* {{.+}} [[BN_IN:%.+]], [5 x [10 x double]]* {{.+}} [[C_IN:%.+]], i{{[0-9]+}} [[CN_SZ1:%.+]], i{{[0-9]+}} [[CN_SZ2:%.+]], double* {{.+}} [[CN_IN:%.+]], [[TT]]* {{.+}} [[D_IN:%.+]]) + // TCHECK: define {{.*}}void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A2_IN:%.+]], [10 x float]* {{.+}} [[B_IN:%.+]], i{{[0-9]+}} [[BN_SZ:%.+]], float* [[BN_IN:%.+]], [5 x [10 x double]]* {{.+}} [[C_IN:%.+]], i{{[0-9]+}} [[CN_SZ1:%.+]], i{{[0-9]+}} [[CN_SZ2:%.+]], double* [[CN_IN:%.+]], [[TT]]* {{.+}} [[D_IN:%.+]]) // TCHECK: [[A2_ADDR:%.+]] = alloca i{{[0-9]+}}, // TCHECK: [[B_ADDR:%.+]] = alloca [10 x float]*, // TCHECK: [[VLA_ADDR:%.+]] = alloca i{{[0-9]+}}, diff --git a/test/OpenMP/target_map_codegen.cpp b/test/OpenMP/target_map_codegen.cpp index 626f68d5a2a9..678e774566c1 100644 --- a/test/OpenMP/target_map_codegen.cpp +++ b/test/OpenMP/target_map_codegen.cpp @@ -645,7 +645,7 @@ void implicit_maps_variable_length_array (int a){ } } -// CK13: define internal void [[KERNEL]](i[[sz]] [[VLA0:%.+]], i[[sz]] [[VLA1:%.+]], double* {{.+}}[[ARG:%.+]]) +// CK13: define internal void [[KERNEL]](i[[sz]] [[VLA0:%.+]], i[[sz]] [[VLA1:%.+]], double* {{.*}}[[ARG:%.+]]) // CK13: [[ADDR0:%.+]] = alloca i[[sz]], // CK13: [[ADDR1:%.+]] = alloca i[[sz]], // CK13: [[ADDR2:%.+]] = alloca double*, @@ -4074,7 +4074,9 @@ int explicit_maps_with_inner_lambda(int a){ // CK25: [[VAL1:%.+]] = load i32*, i32** [[VALADDR]], // CK25: [[VALADDR1:%.+]] = getelementptr inbounds [[CA01]], [[CA01]]* [[CA:%[^,]+]], i32 0, i32 0 // CK25: store i32* [[VAL1]], i32** [[VALADDR1]], -// CK25: call void {{.*}}[[LAMBDA]]{{.*}}([[CA01]]* [[CA]]) +// CK25: call void {{.*}}[[LAMBDA2:@.+]]{{.*}}([[CA01]]* [[CA]]) + +// CK25: define {{.+}}[[LAMBDA2]] #endif ///==========================================================================/// // RUN: %clang_cc1 -DCK26 -std=c++11 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK26 --check-prefix CK26-64 diff --git a/test/OpenMP/target_map_messages.cpp b/test/OpenMP/target_map_messages.cpp index 543f47f8216a..f9bb9410c492 100644 --- a/test/OpenMP/target_map_messages.cpp +++ b/test/OpenMP/target_map_messages.cpp @@ -284,6 +284,11 @@ void SAclient(int arg) { {} } } + #pragma omp target data map(marr[:][:][:]) + { + #pragma omp target data map(marr) + {} + } #pragma omp target data map(to: t) { @@ -419,10 +424,10 @@ T tmain(T argc) { #pragma omp target data map(j) #pragma omp target map(l) map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}} foo(); -#pragma omp target data map(k[:4], j, l[:5]) // expected-note 4 {{used here}} +#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}} #pragma omp target data map(k) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} #pragma omp target data map(j) -#pragma omp target map(l) // expected-error 2 {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}} +#pragma omp target map(l) foo(); #pragma omp target data map(always, tofrom: x) @@ -488,10 +493,10 @@ int main(int argc, char **argv) { #pragma omp target data map(j) #pragma omp target map(l) map(l[:5]) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}} foo(); -#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}} +#pragma omp target data map(k[:4], j, l[:5]) // expected-note {{used here}} #pragma omp target data map(k) // expected-error {{pointer cannot be mapped along with a section derived from itself}} #pragma omp target data map(j) -#pragma omp target map(l) // expected-error {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}} +#pragma omp target map(l) foo(); #pragma omp target data map(always, tofrom: x) diff --git a/test/OpenMP/target_parallel_for_map_messages.cpp b/test/OpenMP/target_parallel_for_map_messages.cpp index 5223a2cc78ea..6b5d2e7f8204 100644 --- a/test/OpenMP/target_parallel_for_map_messages.cpp +++ b/test/OpenMP/target_parallel_for_map_messages.cpp @@ -143,13 +143,13 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for map(l) map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target data map(k[:4], j, l[:5]) // expected-note 4 {{used here}} +#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}} { #pragma omp target parallel for map(k) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for map(j) for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for map(l) // expected-error 2 {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}} +#pragma omp target parallel for map(l) for (i = 0; i < argc; ++i) foo(); } @@ -247,13 +247,13 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for map(l) map(l[:5]) // expected-error 1 {{variable already marked as mapped in current construct}} expected-note 1 {{used here}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}} +#pragma omp target data map(k[:4], j, l[:5]) // expected-note {{used here}} { #pragma omp target parallel for map(k) // expected-error {{pointer cannot be mapped along with a section derived from itself}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for map(j) for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for map(l) // expected-error {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}} +#pragma omp target parallel for map(l) for (i = 0; i < argc; ++i) foo(); } diff --git a/test/OpenMP/target_parallel_for_reduction_messages.cpp b/test/OpenMP/target_parallel_for_reduction_messages.cpp index 16697a98733b..234b71aec218 100644 --- a/test/OpenMP/target_parallel_for_reduction_messages.cpp +++ b/test/OpenMP/target_parallel_for_reduction_messages.cpp @@ -9,6 +9,12 @@ bool foobool(int argc) { return argc; } +void foobar(int &ref) { +#pragma omp target parallel for reduction(+:ref) + for (int i = 0; i < 10; ++i) + foo(); +} + struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} extern S1 a; class S2 { diff --git a/test/OpenMP/target_parallel_for_simd_map_messages.cpp b/test/OpenMP/target_parallel_for_simd_map_messages.cpp index f44639e86cab..93f0be81e31a 100644 --- a/test/OpenMP/target_parallel_for_simd_map_messages.cpp +++ b/test/OpenMP/target_parallel_for_simd_map_messages.cpp @@ -143,13 +143,13 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd map(l) map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target data map(k[:4], j, l[:5]) // expected-note 4 {{used here}} +#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}} { #pragma omp target parallel for simd map(k) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd map(j) for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd map(l) // expected-error 2 {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}} +#pragma omp target parallel for simd map(l) for (i = 0; i < argc; ++i) foo(); } @@ -247,13 +247,13 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd map(l) map(l[:5]) // expected-error 1 {{variable already marked as mapped in current construct}} expected-note 1 {{used here}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}} +#pragma omp target data map(k[:4], j, l[:5]) // expected-note {{used here}} { #pragma omp target parallel for simd map(k) // expected-error {{pointer cannot be mapped along with a section derived from itself}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd map(j) for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd map(l) // expected-error {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}} +#pragma omp target parallel for simd map(l) for (i = 0; i < argc; ++i) foo(); } diff --git a/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp b/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp index 3999d3816284..289b5b2641b6 100644 --- a/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp +++ b/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp @@ -9,6 +9,12 @@ bool foobool(int argc) { return argc; } +void foobar(int &ref) { +#pragma omp target parallel for simd reduction(+:ref) + for (int i = 0; i < 10; ++i) + foo(); +} + struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} extern S1 a; class S2 { diff --git a/test/OpenMP/target_parallel_map_messages.cpp b/test/OpenMP/target_parallel_map_messages.cpp index ff20567185bf..e16801665428 100644 --- a/test/OpenMP/target_parallel_map_messages.cpp +++ b/test/OpenMP/target_parallel_map_messages.cpp @@ -143,13 +143,13 @@ T tmain(T argc) { foo(); #pragma omp target parallel map(l) map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}} foo(); -#pragma omp target data map(k[:4], j, l[:5]) // expected-note 4 {{used here}} +#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}} { #pragma omp target parallel map(k) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} foo(); #pragma omp target parallel map(j) foo(); -#pragma omp target parallel map(l) // expected-error 2 {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}} +#pragma omp target parallel map(l) foo(); } @@ -246,13 +246,13 @@ int main(int argc, char **argv) { foo(); #pragma omp target parallel map(l) map(l[:5]) // expected-error 1 {{variable already marked as mapped in current construct}} expected-note 1 {{used here}} foo(); -#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}} +#pragma omp target data map(k[:4], j, l[:5]) // expected-note 1 {{used here}} { #pragma omp target parallel map(k) // expected-error {{pointer cannot be mapped along with a section derived from itself}} foo(); #pragma omp target parallel map(j) foo(); -#pragma omp target parallel map(l) // expected-error {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}} +#pragma omp target parallel map(l) foo(); } diff --git a/test/OpenMP/target_parallel_reduction_messages.cpp b/test/OpenMP/target_parallel_reduction_messages.cpp index c9434e76245b..52338ee71cbe 100644 --- a/test/OpenMP/target_parallel_reduction_messages.cpp +++ b/test/OpenMP/target_parallel_reduction_messages.cpp @@ -9,6 +9,11 @@ bool foobool(int argc) { return argc; } +void foobar(int &ref) { +#pragma omp target parallel reduction(+:ref) + foo(); +} + struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} extern S1 a; class S2 { diff --git a/test/OpenMP/teams_reduction_messages.cpp b/test/OpenMP/teams_reduction_messages.cpp index 0420b010bb65..9974c147b72c 100644 --- a/test/OpenMP/teams_reduction_messages.cpp +++ b/test/OpenMP/teams_reduction_messages.cpp @@ -9,6 +9,12 @@ bool foobool(int argc) { return argc; } +void foobar(int &ref) { +#pragma omp target +#pragma omp teams reduction(+:ref) + foo(); +} + struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}} extern S1 a; class S2 { diff --git a/test/Preprocessor/init.c b/test/Preprocessor/init.c index f7c320b7226b..adf5c778767e 100644 --- a/test/Preprocessor/init.c +++ b/test/Preprocessor/init.c @@ -1975,6 +1975,11 @@ // ARMEABIHARDFP:#define __arm 1 // ARMEABIHARDFP:#define __arm__ 1 +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=armv6-unknown-cloudabi-eabihf < /dev/null | FileCheck -match-full-lines -check-prefix ARMV6-CLOUDABI %s +// +// ARMV6-CLOUDABI:#define __CloudABI__ 1 +// ARMV6-CLOUDABI:#define __arm__ 1 + // RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm-netbsd-eabi < /dev/null | FileCheck -match-full-lines -check-prefix ARM-NETBSD %s // // ARM-NETBSD-NOT:#define _LP64 diff --git a/test/SemaCXX/cxx0x-defaulted-functions.cpp b/test/SemaCXX/cxx0x-defaulted-functions.cpp index 16e20ff4964d..7ec9726095cb 100644 --- a/test/SemaCXX/cxx0x-defaulted-functions.cpp +++ b/test/SemaCXX/cxx0x-defaulted-functions.cpp @@ -208,3 +208,38 @@ int fn() { t = true; } } + +namespace dependent_classes { +template <bool B, typename X, typename Y> +struct conditional; + +template <typename X, typename Y> +struct conditional<true, X, Y> { typedef X type; }; + +template <typename X, typename Y> +struct conditional<false, X, Y> { typedef Y type; }; + +template<bool B> struct X { + X(); + + // B == false triggers error for = default. + using T = typename conditional<B, const X &, int>::type; + X(T) = default; // expected-error {{only special member functions}} + + // Either value of B creates a constructor that can be default + using U = typename conditional<B, X&&, const X&>::type; + X(U) = default; +}; + +X<true> x1; +X<false> x2; // expected-note {{in instantiation}} + +template <typename Type> +class E { + explicit E(const int &) = default; +}; + +template <typename Type> +E<Type>::E(const int&) {} // expected-error {{definition of explicitly defaulted function}} + +} diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp index 0fbdedc70a69..f445725c7429 100644 --- a/test/SemaCXX/nested-name-spec.cpp +++ b/test/SemaCXX/nested-name-spec.cpp @@ -435,3 +435,21 @@ namespace PR16951 { // expected-error{{no member named 'X2' in 'PR16951::enumerator_2'}} } + +namespace PR30619 { +c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; +// expected-error@-1 16{{unknown type name 'c'}} +c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; +// expected-error@-1 16{{unknown type name 'c'}} +c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; +// expected-error@-1 16{{unknown type name 'c'}} +c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; +// expected-error@-1 16{{unknown type name 'c'}} +namespace A { +class B { + typedef C D; // expected-error{{unknown type name 'C'}} + A::D::F; + // expected-error@-1{{'D' (aka 'int') is not a class, namespace, or enumeration}} +}; +} +} diff --git a/test/SemaTemplate/instantiate-self.cpp b/test/SemaTemplate/instantiate-self.cpp index cfe902509f7f..916a01e63f11 100644 --- a/test/SemaTemplate/instantiate-self.cpp +++ b/test/SemaTemplate/instantiate-self.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -verify %s +// RUN: %clang_cc1 -std=c++1z -verify -pedantic-errors %s // Check that we deal with cases where the instantiation of a class template // recursively requires the instantiation of the same template. @@ -47,9 +47,8 @@ namespace test4 { A<int> a; // expected-note {{in instantiation of}} } -// FIXME: PR12298: Recursive constexpr function template instantiation leads to +// PR12298: Recursive constexpr function template instantiation leads to // stack overflow. -#if 0 namespace test5 { template<typename T> struct A { constexpr T f(T k) { return g(k); } @@ -57,22 +56,20 @@ namespace test5 { return k ? f(k-1)+1 : 0; } }; - // This should be accepted. - constexpr int x = A<int>().f(5); + constexpr int x = A<int>().f(5); // ok } namespace test6 { template<typename T> constexpr T f(T); template<typename T> constexpr T g(T t) { - typedef int arr[f(T())]; + typedef int arr[f(T())]; // expected-error {{variable length array}} return t; } template<typename T> constexpr T f(T t) { - typedef int arr[g(T())]; + typedef int arr[g(T())]; // expected-error {{zero size array}} expected-note {{instantiation of}} return t; } - // This should be ill-formed. - int n = f(0); + int n = f(0); // expected-note 2{{instantiation of}} } namespace test7 { @@ -80,10 +77,94 @@ namespace test7 { return t; } template<typename T> constexpr T f(T t) { - typedef int arr[g(T())]; + typedef int arr[g(T() + 1)]; return t; } - // This should be accepted. int n = f(0); } + +namespace test8 { + template<typename T> struct A { + int n = A{}.n; // expected-error {{default member initializer for 'n' uses itself}} expected-note {{instantiation of default member init}} + }; + A<int> ai = {}; // expected-note {{instantiation of default member init}} +} + +namespace test9 { + template<typename T> struct A { enum class B; }; + // FIXME: It'd be nice to give the "it has not yet been instantiated" diagnostic here. + template<typename T> enum class A<T>::B { k = A<T>::B::k2, k2 = k }; // expected-error {{no member named 'k2'}} + auto k = A<int>::B::k; // expected-note {{in instantiation of}} +} + +namespace test10 { + template<typename T> struct A { + void f() noexcept(noexcept(f())); // expected-error {{exception specification of 'f' uses itself}} expected-note {{instantiation of}} + }; + bool b = noexcept(A<int>().f()); // expected-note {{instantiation of}} +} + +namespace test11 { + template<typename T> const int var = var<T>; + int k = var<int>; + + template<typename T> struct X { + static const int k = X<T>::k; + }; + template<typename T> const int X<T>::k; + int q = X<int>::k; + + template<typename T> struct Y { + static const int k; + }; + template<typename T> const int Y<T>::k = Y<T>::k; + int r = Y<int>::k; +} + +namespace test12 { + template<typename T> int f(T t, int = f(T())) {} // expected-error {{recursive evaluation of default argument}} expected-note {{instantiation of}} + struct X {}; + int q = f(X()); // expected-note {{instantiation of}} +} + +namespace test13 { + struct A { + // Cycle via type of non-type template parameter. + template<typename T, typename T::template W<T>::type U = 0> struct W { using type = int; }; + // Cycle via default template argument. + template<typename T, typename U = typename T::template X<T>> struct X {}; + template<typename T, int U = T::template Y<T>::value> struct Y { static const int value = 0; }; + template<typename T, template<typename> typename U = T::template Z<T>::template nested> struct Z { template<typename> struct nested; }; + }; + template<typename T> struct Wrap { + template<typename U> struct W : A::W<T> {}; + template<typename U> struct X : A::X<T> {}; + template<typename U> struct Y : A::Y<T> {}; + template<typename U> struct Z : A::Z<T> {}; + }; + struct B { + template<typename U> struct W { using type = int; }; + template<typename U> struct X {}; + template<typename U> struct Y { static const int value = 0; }; + template<typename U> struct Z { template<typename> struct nested; }; + }; + + A::W<B> awb; + A::X<B> axb; + A::Y<B> ayb; + A::Z<B> azb; + + A::W<Wrap<Wrap<B>>> awwwb; + A::X<Wrap<Wrap<B>>> axwwb; + A::Y<Wrap<Wrap<B>>> aywwb; + A::Z<Wrap<Wrap<B>>> azwwb; + + // FIXME: These tests cause us to use too much stack and crash on a self-hosted debug build. + // FIXME: Check for recursion here and give a better diagnostic. +#if 0 + A::W<A> awa; + A::X<A> axa; + A::Y<A> aya; + A::Z<A> aza; #endif +} diff --git a/test/SemaTemplate/instantiation-depth-exception-spec.cpp b/test/SemaTemplate/instantiation-depth-exception-spec.cpp index 6caa4a60e6f8..3f64811bd108 100644 --- a/test/SemaTemplate/instantiation-depth-exception-spec.cpp +++ b/test/SemaTemplate/instantiation-depth-exception-spec.cpp @@ -1,11 +1,14 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -ftemplate-depth 16 -fcxx-exceptions -fexceptions %s -template<typename T> T go(T a) noexcept(noexcept(go(a))); // \ -// expected-error 16{{call to function 'go' that is neither visible}} \ -// expected-note 16{{'go' should be declared prior to the call site}} \ -// expected-error {{recursive template instantiation exceeded maximum depth of 16}} +template<int N> struct X { + static int go(int a) noexcept(noexcept(X<N+1>::go(a))); // \ +// expected-error {{recursive template instantiation exceeded maximum depth of 16}} \ +// expected-note 9{{in instantiation of exception specification}} \ +// expected-note {{skipping 7 context}} \ +// expected-note {{use -ftemplate-depth}} +}; void f() { - int k = go(0); // \ - // expected-note {{in instantiation of exception specification for 'go<int>' requested here}} + int k = X<0>::go(0); // \ + // expected-note {{in instantiation of exception specification for 'go' requested here}} } diff --git a/test/SemaTemplate/instantiation-depth.cpp b/test/SemaTemplate/instantiation-depth.cpp index c0b8bb2a1245..17f84c170c32 100644 --- a/test/SemaTemplate/instantiation-depth.cpp +++ b/test/SemaTemplate/instantiation-depth.cpp @@ -19,13 +19,12 @@ void test() { // RUN: %clang_cc1 -fsyntax-only -verify -ftemplate-depth 5 -ftemplate-backtrace-limit 4 -std=c++11 -DNOEXCEPT %s template<typename T> struct S { - S() noexcept(noexcept(T())); -}; -struct T : S<T> {}; \ + S() noexcept(noexcept(S<S>())); \ // expected-error{{recursive template instantiation exceeded maximum depth of 5}} \ -// expected-note 4 {{in instantiation of exception spec}} \ +// expected-note 3 {{in instantiation of exception spec}} \ // expected-note {{skipping 2 contexts in backtrace}} \ // expected-note {{use -ftemplate-depth=N to increase recursive template instantiation depth}} -T t; // expected-note {{implicit default constructor for 'T' first required here}} +}; +S<void> t; // expected-note {{in instantiation of exception spec}} #endif diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 027bf95b660b..deb4cc551b8a 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -1243,8 +1243,9 @@ bool CursorVisitor::VisitUnresolvedUsingTypenameDecl( bool CursorVisitor::VisitStaticAssertDecl(StaticAssertDecl *D) { if (Visit(MakeCXCursor(D->getAssertExpr(), StmtParent, TU, RegionOfInterest))) return true; - if (Visit(MakeCXCursor(D->getMessage(), StmtParent, TU, RegionOfInterest))) - return true; + if (StringLiteral *Message = D->getMessage()) + if (Visit(MakeCXCursor(Message, StmtParent, TU, RegionOfInterest))) + return true; return false; } |