diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-05-21 06:58:08 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-05-21 06:58:08 +0000 |
commit | d5f23b0b7528b5c3caed1ba14f897cc4aaa9e3c3 (patch) | |
tree | 133ab22e59f61162b7f8e8e794dd6458769e8e1a /lib | |
parent | 624e91b063cecc3671eeb40e4b0fa08d71b59284 (diff) | |
download | src-test2-d5f23b0b7528b5c3caed1ba14f897cc4aaa9e3c3.tar.gz src-test2-d5f23b0b7528b5c3caed1ba14f897cc4aaa9e3c3.zip |
Notes
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 4 | ||||
-rw-r--r-- | lib/AST/ASTDiagnostic.cpp | 53 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 3 | ||||
-rw-r--r-- | lib/Analysis/ThreadSafety.cpp | 4 | ||||
-rw-r--r-- | lib/Basic/SourceManager.cpp | 39 | ||||
-rw-r--r-- | lib/Basic/TargetInfo.cpp | 1 | ||||
-rw-r--r-- | lib/Basic/Targets.cpp | 20 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 1 | ||||
-rw-r--r-- | lib/CodeGen/ItaniumCXXABI.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/TargetInfo.cpp | 2 | ||||
-rw-r--r-- | lib/Driver/ToolChains.cpp | 2 | ||||
-rw-r--r-- | lib/Frontend/InitPreprocessor.cpp | 7 | ||||
-rw-r--r-- | lib/Sema/DeclSpec.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 21 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 7 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 10 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 56 |
17 files changed, 157 insertions, 81 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 6b864d0f0ac2..c9fb80ceaae2 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -682,6 +682,7 @@ CXXABI *ASTContext::createCXXABI(const TargetInfo &T) { case TargetCXXABI::iOS: case TargetCXXABI::iOS64: case TargetCXXABI::GenericAArch64: + case TargetCXXABI::GenericMIPS: case TargetCXXABI::GenericItanium: return CreateItaniumCXXABI(*this); case TargetCXXABI::Microsoft: @@ -7873,7 +7874,7 @@ static GVALinkage basicGVALinkageForFunction(const ASTContext &Context, // Functions specified with extern and inline in -fms-compatibility mode // forcibly get emitted. While the body of the function cannot be later // replaced, the function definition cannot be discarded. - if (FD->getMostRecentDecl()->isMSExternInline()) + if (FD->isMSExternInline()) return GVA_StrongODR; return GVA_DiscardableODR; @@ -8064,6 +8065,7 @@ MangleContext *ASTContext::createMangleContext() { case TargetCXXABI::GenericAArch64: case TargetCXXABI::GenericItanium: case TargetCXXABI::GenericARM: + case TargetCXXABI::GenericMIPS: case TargetCXXABI::iOS: case TargetCXXABI::iOS64: return ItaniumMangleContext::create(*this, getDiagnostics()); diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp index 3212359db183..000588face96 100644 --- a/lib/AST/ASTDiagnostic.cpp +++ b/lib/AST/ASTDiagnostic.cpp @@ -998,29 +998,27 @@ class TemplateDiff { (!HasFromValueDecl && !HasToValueDecl)) && "Template argument cannot be both integer and declaration"); - unsigned ParamWidth = 128; // Safe default - if (FromDefaultNonTypeDecl->getType()->isIntegralOrEnumerationType()) - ParamWidth = Context.getIntWidth(FromDefaultNonTypeDecl->getType()); - if (!HasFromInt && !HasToInt && !HasFromValueDecl && !HasToValueDecl) { Tree.SetNode(FromExpr, ToExpr); Tree.SetDefault(FromIter.isEnd() && FromExpr, ToIter.isEnd() && ToExpr); if (FromDefaultNonTypeDecl->getType()->isIntegralOrEnumerationType()) { if (FromExpr) - HasFromInt = GetInt(Context, FromIter, FromExpr, FromInt); + HasFromInt = GetInt(Context, FromIter, FromExpr, FromInt, + FromDefaultNonTypeDecl->getType()); if (ToExpr) - HasToInt = GetInt(Context, ToIter, ToExpr, ToInt); + HasToInt = GetInt(Context, ToIter, ToExpr, ToInt, + ToDefaultNonTypeDecl->getType()); } if (HasFromInt && HasToInt) { Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt); - Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt)); + Tree.SetSame(FromInt == ToInt); Tree.SetKind(DiffTree::Integer); } else if (HasFromInt || HasToInt) { Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt); Tree.SetSame(false); Tree.SetKind(DiffTree::Integer); } else { - Tree.SetSame(IsEqualExpr(Context, ParamWidth, FromExpr, ToExpr) || + Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr) || (FromNullPtr && ToNullPtr)); Tree.SetNullPtr(FromNullPtr, ToNullPtr); Tree.SetKind(DiffTree::Expression); @@ -1030,11 +1028,17 @@ class TemplateDiff { if (HasFromInt || HasToInt) { if (!HasFromInt && FromExpr) - HasFromInt = GetInt(Context, FromIter, FromExpr, FromInt); + HasFromInt = GetInt(Context, FromIter, FromExpr, FromInt, + FromDefaultNonTypeDecl->getType()); if (!HasToInt && ToExpr) - HasToInt = GetInt(Context, ToIter, ToExpr, ToInt); + HasToInt = GetInt(Context, ToIter, ToExpr, ToInt, + ToDefaultNonTypeDecl->getType()); Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt); - Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt)); + if (HasFromInt && HasToInt) { + Tree.SetSame(FromInt == ToInt); + } else { + Tree.SetSame(false); + } Tree.SetDefault(FromIter.isEnd() && HasFromInt, ToIter.isEnd() && HasToInt); Tree.SetKind(DiffTree::Integer); @@ -1210,9 +1214,11 @@ class TemplateDiff { } /// GetInt - Retrieves the template integer argument, including evaluating - /// default arguments. + /// default arguments. If the value comes from an expression, extend the + /// APSInt to size of IntegerType to match the behavior in + /// Sema::CheckTemplateArgument static bool GetInt(ASTContext &Context, const TSTiterator &Iter, - Expr *ArgExpr, llvm::APInt &Int) { + Expr *ArgExpr, llvm::APSInt &Int, QualType IntegerType) { // Default, value-depenedent expressions require fetching // from the desugared TemplateArgument, otherwise expression needs to // be evaluatable. @@ -1224,12 +1230,14 @@ class TemplateDiff { case TemplateArgument::Expression: ArgExpr = Iter.getDesugar().getAsExpr(); Int = ArgExpr->EvaluateKnownConstInt(Context); + Int = Int.extOrTrunc(Context.getTypeSize(IntegerType)); return true; default: llvm_unreachable("Unexpected template argument kind"); } } else if (ArgExpr->isEvaluatable(Context)) { Int = ArgExpr->EvaluateKnownConstInt(Context); + Int = Int.extOrTrunc(Context.getTypeSize(IntegerType)); return true; } @@ -1302,18 +1310,8 @@ class TemplateDiff { return nullptr; } - /// IsSameConvertedInt - Returns true if both integers are equal when - /// converted to an integer type with the given width. - static bool IsSameConvertedInt(unsigned Width, const llvm::APSInt &X, - const llvm::APSInt &Y) { - llvm::APInt ConvertedX = X.extOrTrunc(Width); - llvm::APInt ConvertedY = Y.extOrTrunc(Width); - return ConvertedX == ConvertedY; - } - /// IsEqualExpr - Returns true if the expressions evaluate to the same value. - static bool IsEqualExpr(ASTContext &Context, unsigned ParamWidth, - Expr *FromExpr, Expr *ToExpr) { + static bool IsEqualExpr(ASTContext &Context, Expr *FromExpr, Expr *ToExpr) { if (FromExpr == ToExpr) return true; @@ -1345,7 +1343,7 @@ class TemplateDiff { switch (FromVal.getKind()) { case APValue::Int: - return IsSameConvertedInt(ParamWidth, FromVal.getInt(), ToVal.getInt()); + return FromVal.getInt() == ToVal.getInt(); case APValue::LValue: { APValue::LValueBase FromBase = FromVal.getLValueBase(); APValue::LValueBase ToBase = ToVal.getLValueBase(); @@ -1655,11 +1653,14 @@ class TemplateDiff { } Unbold(); } - + /// HasExtraInfo - Returns true if E is not an integer literal or the /// negation of an integer literal bool HasExtraInfo(Expr *E) { if (!E) return false; + + E = E->IgnoreImpCasts(); + if (isa<IntegerLiteral>(E)) return false; if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index e43c28af9b69..dc08d23a24b5 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -2674,7 +2674,8 @@ bool FunctionDecl::isMSExternInline() const { if (!Context.getLangOpts().MSVCCompat && !hasAttr<DLLExportAttr>()) return false; - for (const FunctionDecl *FD = this; FD; FD = FD->getPreviousDecl()) + for (const FunctionDecl *FD = getMostRecentDecl(); FD; + FD = FD->getPreviousDecl()) if (FD->getStorageClass() == SC_Extern) return true; diff --git a/lib/Analysis/ThreadSafety.cpp b/lib/Analysis/ThreadSafety.cpp index a986c587f869..f45d6e7ef139 100644 --- a/lib/Analysis/ThreadSafety.cpp +++ b/lib/Analysis/ThreadSafety.cpp @@ -2108,8 +2108,8 @@ void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) { // Create a dummy expression, VarDecl *VD = const_cast<VarDecl*>(AD.getVarDecl()); - DeclRefExpr DRE(VD, false, VD->getType(), VK_LValue, - AD.getTriggerStmt()->getLocEnd()); + DeclRefExpr DRE(VD, false, VD->getType().getNonReferenceType(), + VK_LValue, AD.getTriggerStmt()->getLocEnd()); LocksetBuilder.handleCall(&DRE, DD); break; } diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp index 305dcd43960c..118e3f32008b 100644 --- a/lib/Basic/SourceManager.cpp +++ b/lib/Basic/SourceManager.cpp @@ -2076,22 +2076,33 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS, return IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second); } - // This can happen if a location is in a built-ins buffer. - // But see PR5662. + // If we arrived here, the location is either in a built-ins buffer or + // associated with global inline asm. PR5662 and PR22576 are examples. + // Clear the lookup cache, it depends on a common location. IsBeforeInTUCache.clear(); - bool LIsBuiltins = strcmp("<built-in>", - getBuffer(LOffs.first)->getBufferIdentifier()) == 0; - bool RIsBuiltins = strcmp("<built-in>", - getBuffer(ROffs.first)->getBufferIdentifier()) == 0; - // built-in is before non-built-in - if (LIsBuiltins != RIsBuiltins) - return LIsBuiltins; - assert(LIsBuiltins && RIsBuiltins && - "Non-built-in locations must be rooted in the main file"); - // Both are in built-in buffers, but from different files. We just claim that - // lower IDs come first. - return LOffs.first < ROffs.first; + llvm::MemoryBuffer *LBuf = getBuffer(LOffs.first); + llvm::MemoryBuffer *RBuf = getBuffer(ROffs.first); + bool LIsBuiltins = strcmp("<built-in>", LBuf->getBufferIdentifier()) == 0; + bool RIsBuiltins = strcmp("<built-in>", RBuf->getBufferIdentifier()) == 0; + // Sort built-in before non-built-in. + if (LIsBuiltins || RIsBuiltins) { + if (LIsBuiltins != RIsBuiltins) + return LIsBuiltins; + // Both are in built-in buffers, but from different files. We just claim that + // lower IDs come first. + return LOffs.first < ROffs.first; + } + bool LIsAsm = strcmp("<inline asm>", LBuf->getBufferIdentifier()) == 0; + bool RIsAsm = strcmp("<inline asm>", RBuf->getBufferIdentifier()) == 0; + // Sort assembler after built-ins, but before the rest. + if (LIsAsm || RIsAsm) { + if (LIsAsm != RIsAsm) + return RIsAsm; + assert(LOffs.first == ROffs.first); + return false; + } + llvm_unreachable("Unsortable locations found"); } void SourceManager::PrintStats() const { diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp index 6987cd71f3d7..871bbd5ef43f 100644 --- a/lib/Basic/TargetInfo.cpp +++ b/lib/Basic/TargetInfo.cpp @@ -655,6 +655,7 @@ bool TargetCXXABI::tryParse(llvm::StringRef name) { .Case("ios", iOS) .Case("itanium", GenericItanium) .Case("microsoft", Microsoft) + .Case("mips", GenericMIPS) .Default(unknown); if (kind == unknown) return false; diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index bf60bbf3fd9f..a7a00570d127 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -419,6 +419,7 @@ protected: public: NetBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { this->UserLabelPrefix = ""; + this->MCountName = "_mcount"; } }; @@ -919,6 +920,10 @@ public: if (RegNo == 1) return 4; return -1; } + + bool hasSjLjLowering() const override { + return true; + } }; const Builtin::Info PPCTargetInfo::BuiltinInfo[] = { @@ -2181,6 +2186,10 @@ public: CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override { return MT == CCMT_Member ? CC_X86ThisCall : CC_C; } + + bool hasSjLjLowering() const override { + return true; + } }; bool X86TargetInfo::setFPMath(StringRef Name) { @@ -3354,7 +3363,10 @@ public: : WindowsTargetInfo<X86_32TargetInfo>(Triple) { WCharType = UnsignedShort; DoubleAlign = LongLongAlign = 64; - DescriptionString = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"; + bool IsWinCOFF = + getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF(); + DescriptionString = IsWinCOFF ? "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32" + : "e-m:e-p:32:32-i64:64-f80:32-n8:16:32-S32"; } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { @@ -5628,7 +5640,9 @@ public: const std::string &CPUStr) : TargetInfo(Triple), CPU(CPUStr), IsMips16(false), IsMicromips(false), IsNan2008(false), IsSingleFloat(false), FloatABI(HardFloat), - DspRev(NoDSP), HasMSA(false), HasFP64(false), ABI(ABIStr) {} + DspRev(NoDSP), HasMSA(false), HasFP64(false), ABI(ABIStr) { + TheCXXABI.set(TargetCXXABI::GenericMIPS); + } bool isNaN2008Default() const { return CPU == "mips32r6" || CPU == "mips64r6"; @@ -6662,6 +6676,8 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) { switch (os) { case llvm::Triple::Linux: return new LinuxTargetInfo<PPC64TargetInfo>(Triple); + case llvm::Triple::NetBSD: + return new NetBSDTargetInfo<PPC64TargetInfo>(Triple); default: return new PPC64TargetInfo(Triple); } diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 9f4567dbbb84..d653130df3d0 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -64,6 +64,7 @@ static CGCXXABI *createCXXABI(CodeGenModule &CGM) { case TargetCXXABI::GenericARM: case TargetCXXABI::iOS: case TargetCXXABI::iOS64: + case TargetCXXABI::GenericMIPS: case TargetCXXABI::GenericItanium: return CreateItaniumCXXABI(CGM); case TargetCXXABI::Microsoft: diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index deebab858399..9e88b1ebbadc 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -339,6 +339,9 @@ CodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) { return new ItaniumCXXABI(CGM, /* UseARMMethodPtrABI = */ true, /* UseARMGuardVarABI = */ true); + case TargetCXXABI::GenericMIPS: + return new ItaniumCXXABI(CGM, /* UseARMMethodPtrABI = */ true); + case TargetCXXABI::GenericItanium: if (CGM.getContext().getTargetInfo().getTriple().getArch() == llvm::Triple::le32) { diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 39cc7e5d99c4..c05b23a32e86 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -664,7 +664,6 @@ public: ('T' << 24); return llvm::ConstantInt::get(CGM.Int32Ty, Sig); } - }; } @@ -4455,7 +4454,6 @@ public: llvm::AttributeSet::FunctionIndex, B)); } - }; } diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index f789fd55598f..8bd8298031f5 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -1724,6 +1724,7 @@ static bool findMIPSMultilibs(const llvm::Triple &TargetTriple, StringRef Path, MultilibSet AndroidMipsMultilibs = MultilibSet() .Maybe(Multilib("/mips-r2").flag("+march=mips32r2")) + .Maybe(Multilib("/mips-r6").flag("+march=mips32r6")) .FilterOut(NonExistent); MultilibSet DebianMipsMultilibs; @@ -1783,6 +1784,7 @@ static bool findMIPSMultilibs(const llvm::Triple &TargetTriple, StringRef Path, addMultilibFlag(isMips16(Args), "mips16", Flags); addMultilibFlag(CPUName == "mips32", "march=mips32", Flags); addMultilibFlag(CPUName == "mips32r2", "march=mips32r2", Flags); + addMultilibFlag(CPUName == "mips32r6", "march=mips32r6", Flags); addMultilibFlag(CPUName == "mips64", "march=mips64", Flags); addMultilibFlag(CPUName == "mips64r2" || CPUName == "octeon", "march=mips64r2", Flags); diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp index f4241a94ae02..3550ac25159b 100644 --- a/lib/Frontend/InitPreprocessor.cpp +++ b/lib/Frontend/InitPreprocessor.cpp @@ -662,12 +662,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI, TI.getTypeWidth(TI.getWCharType()), TI, Builder); DefineTypeSizeof("__SIZEOF_WINT_T__", TI.getTypeWidth(TI.getWIntType()), TI, Builder); - // This is a temporary workaround while MIPS64 has not yet fully supported - // 128-bit integers. But declaration of int128 type is necessary even though - // __SIZEOF_INT128__ is undefined because c++ standard header files like - // limits throw error message if __int128 is not available. - if (TI.hasInt128Type() && !(TI.getTriple().getArch() == llvm::Triple::mips64el - || TI.getTriple().getArch() == llvm::Triple::mips64)) + if (TI.hasInt128Type()) DefineTypeSizeof("__SIZEOF_INT128__", 128, TI, Builder); DefineType("__INTMAX_TYPE__", TI.getIntMaxType(), Builder); diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp index 7bf3e51999b6..349bb3258025 100644 --- a/lib/Sema/DeclSpec.cpp +++ b/lib/Sema/DeclSpec.cpp @@ -345,8 +345,9 @@ bool Declarator::isDeclarationOfFunction() const { bool Declarator::isStaticMember() { assert(getContext() == MemberContext); return getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static || - CXXMethodDecl::isStaticOverloadedOperator( - getName().OperatorFunctionId.Operator); + (getName().Kind == UnqualifiedId::IK_OperatorFunctionId && + CXXMethodDecl::isStaticOverloadedOperator( + getName().OperatorFunctionId.Operator)); } bool DeclSpec::hasTagDefinition() const { diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index fdc136ccbd23..8c3efdee9036 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -297,6 +297,10 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, if (SemaBuiltinLongjmp(TheCall)) return ExprError(); break; + case Builtin::BI__builtin_setjmp: + if (SemaBuiltinSetjmp(TheCall)) + return ExprError(); + break; case Builtin::BI__builtin_classify_type: if (checkArgCount(*this, TheCall, 1)) return true; @@ -2367,8 +2371,13 @@ bool Sema::SemaBuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, } /// SemaBuiltinLongjmp - Handle __builtin_longjmp(void *env[5], int val). -/// This checks that val is a constant 1. +/// This checks that the target supports __builtin_longjmp and +/// that val is a constant 1. bool Sema::SemaBuiltinLongjmp(CallExpr *TheCall) { + if (!Context.getTargetInfo().hasSjLjLowering()) + return Diag(TheCall->getLocStart(), diag::err_builtin_longjmp_unsupported) + << SourceRange(TheCall->getLocStart(), TheCall->getLocEnd()); + Expr *Arg = TheCall->getArg(1); llvm::APSInt Result; @@ -2383,6 +2392,16 @@ bool Sema::SemaBuiltinLongjmp(CallExpr *TheCall) { return false; } + +/// SemaBuiltinSetjmp - Handle __builtin_setjmp(void *env[5]). +/// This checks that the target supports __builtin_setjmp. +bool Sema::SemaBuiltinSetjmp(CallExpr *TheCall) { + if (!Context.getTargetInfo().hasSjLjLowering()) + return Diag(TheCall->getLocStart(), diag::err_builtin_setjmp_unsupported) + << SourceRange(TheCall->getLocStart(), TheCall->getLocEnd()); + return false; +} + namespace { enum StringLiteralCheckType { SLCT_NotALiteral, diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 091fd27db85d..8be11572b2e0 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -117,7 +117,7 @@ static AvailabilityResult DiagnoseAvailabilityOfDecl(Sema &S, case AR_Available: case AR_NotYetIntroduced: break; - + case AR_Deprecated: if (S.getCurContextAvailability() != AR_Deprecated) S.EmitAvailabilityWarning(Sema::AD_Deprecation, @@ -11630,8 +11630,11 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, } else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(Func)) { Destructor = cast<CXXDestructorDecl>(Destructor->getFirstDecl()); - if (Destructor->isDefaulted() && !Destructor->isDeleted()) + if (Destructor->isDefaulted() && !Destructor->isDeleted()) { + if (Destructor->isTrivial() && !Destructor->hasAttr<DLLExportAttr>()) + return; DefineImplicitDestructor(Loc, Destructor); + } if (Destructor->isVirtual()) MarkVTableUsed(Loc, Destructor->getParent()); } else if (CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(Func)) { diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 3e2a2de5b406..a92b7ac472e7 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -5705,6 +5705,16 @@ ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl, ExprResult Sema::BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand, SourceLocation RParen) { + // If the operand is an unresolved lookup expression, the expression is ill- + // formed per [over.over]p1, because overloaded function names cannot be used + // without arguments except in explicit contexts. + ExprResult R = CheckPlaceholderExpr(Operand); + if (R.isInvalid()) + return R; + + // The operand may have been modified when checking the placeholder type. + Operand = R.get(); + if (ActiveTemplateInstantiations.empty() && Operand->HasSideEffects(Context, false)) { // The expression operand for noexcept is in an unevaluated expression diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 67c36a5fb5e9..1e7176222b57 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -3355,7 +3355,7 @@ Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template, /// \param Param The template parameter against which the argument will be /// checked. /// -/// \param Arg The template argument. +/// \param Arg The template argument, which may be updated due to conversions. /// /// \param Template The template in which the template argument resides. /// @@ -3433,6 +3433,13 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, if (Res.isInvalid()) return true; + // If the resulting expression is new, then use it in place of the + // old expression in the template argument. + if (Res.get() != Arg.getArgument().getAsExpr()) { + TemplateArgument TA(Res.get()); + Arg = TemplateArgumentLoc(TA, Res.get()); + } + Converted.push_back(Result); break; } @@ -3640,9 +3647,14 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs, SmallVectorImpl<TemplateArgument> &Converted) { + // Make a copy of the template arguments for processing. Only make the + // changes at the end when successful in matching the arguments to the + // template. + TemplateArgumentListInfo NewArgs = TemplateArgs; + TemplateParameterList *Params = Template->getTemplateParameters(); - SourceLocation RAngleLoc = TemplateArgs.getRAngleLoc(); + SourceLocation RAngleLoc = NewArgs.getRAngleLoc(); // C++ [temp.arg]p1: // [...] The type and form of each template-argument specified in @@ -3651,7 +3663,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, // template-parameter-list. bool isTemplateTemplateParameter = isa<TemplateTemplateParmDecl>(Template); SmallVector<TemplateArgument, 2> ArgumentPack; - unsigned ArgIdx = 0, NumArgs = TemplateArgs.size(); + unsigned ArgIdx = 0, NumArgs = NewArgs.size(); LocalInstantiationScope InstScope(*this, true); for (TemplateParameterList::iterator Param = Params->begin(), ParamEnd = Params->end(); @@ -3687,21 +3699,21 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, if (ArgIdx < NumArgs) { // Check the template argument we were given. - if (CheckTemplateArgument(*Param, TemplateArgs[ArgIdx], Template, + if (CheckTemplateArgument(*Param, NewArgs[ArgIdx], Template, TemplateLoc, RAngleLoc, ArgumentPack.size(), Converted)) return true; bool PackExpansionIntoNonPack = - TemplateArgs[ArgIdx].getArgument().isPackExpansion() && + NewArgs[ArgIdx].getArgument().isPackExpansion() && (!(*Param)->isTemplateParameterPack() || getExpandedPackSize(*Param)); if (PackExpansionIntoNonPack && isa<TypeAliasTemplateDecl>(Template)) { // Core issue 1430: we have a pack expansion as an argument to an // alias template, and it's not part of a parameter pack. This // can't be canonicalized, so reject it now. - Diag(TemplateArgs[ArgIdx].getLocation(), + Diag(NewArgs[ArgIdx].getLocation(), diag::err_alias_template_expansion_into_fixed_list) - << TemplateArgs[ArgIdx].getSourceRange(); + << NewArgs[ArgIdx].getSourceRange(); Diag((*Param)->getLocation(), diag::note_template_param_here); return true; } @@ -3733,7 +3745,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, } while (ArgIdx < NumArgs) { - Converted.push_back(TemplateArgs[ArgIdx].getArgument()); + Converted.push_back(NewArgs[ArgIdx].getArgument()); ++ArgIdx; } @@ -3784,8 +3796,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, // the default argument. if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) { if (!TTP->hasDefaultArgument()) - return diagnoseArityMismatch(*this, Template, TemplateLoc, - TemplateArgs); + return diagnoseArityMismatch(*this, Template, TemplateLoc, NewArgs); TypeSourceInfo *ArgType = SubstDefaultTemplateArgument(*this, Template, @@ -3801,8 +3812,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, } else if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*Param)) { if (!NTTP->hasDefaultArgument()) - return diagnoseArityMismatch(*this, Template, TemplateLoc, - TemplateArgs); + return diagnoseArityMismatch(*this, Template, TemplateLoc, NewArgs); ExprResult E = SubstDefaultTemplateArgument(*this, Template, TemplateLoc, @@ -3819,8 +3829,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, = cast<TemplateTemplateParmDecl>(*Param); if (!TempParm->hasDefaultArgument()) - return diagnoseArityMismatch(*this, Template, TemplateLoc, - TemplateArgs); + return diagnoseArityMismatch(*this, Template, TemplateLoc, NewArgs); NestedNameSpecifierLoc QualifierLoc; TemplateName Name = SubstDefaultTemplateArgument(*this, Template, @@ -3848,12 +3857,12 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, RAngleLoc, 0, Converted)) return true; - // Core issue 150 (assumed resolution): if this is a template template - // parameter, keep track of the default template arguments from the + // Core issue 150 (assumed resolution): if this is a template template + // parameter, keep track of the default template arguments from the // template definition. if (isTemplateTemplateParameter) - TemplateArgs.addArgument(Arg); - + NewArgs.addArgument(Arg); + // Move to the next template parameter and argument. ++Param; ++ArgIdx; @@ -3865,15 +3874,18 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, // still dependent). if (ArgIdx < NumArgs && CurrentInstantiationScope && CurrentInstantiationScope->getPartiallySubstitutedPack()) { - while (ArgIdx < NumArgs && - TemplateArgs[ArgIdx].getArgument().isPackExpansion()) - Converted.push_back(TemplateArgs[ArgIdx++].getArgument()); + while (ArgIdx < NumArgs && NewArgs[ArgIdx].getArgument().isPackExpansion()) + Converted.push_back(NewArgs[ArgIdx++].getArgument()); } // If we have any leftover arguments, then there were too many arguments. // Complain and fail. if (ArgIdx < NumArgs) - return diagnoseArityMismatch(*this, Template, TemplateLoc, TemplateArgs); + return diagnoseArityMismatch(*this, Template, TemplateLoc, NewArgs); + + // No problems found with the new argument list, propagate changes back + // to caller. + TemplateArgs = NewArgs; return false; } |