summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-05-21 06:58:08 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-05-21 06:58:08 +0000
commitd5f23b0b7528b5c3caed1ba14f897cc4aaa9e3c3 (patch)
tree133ab22e59f61162b7f8e8e794dd6458769e8e1a /lib
parent624e91b063cecc3671eeb40e4b0fa08d71b59284 (diff)
downloadsrc-test2-d5f23b0b7528b5c3caed1ba14f897cc4aaa9e3c3.tar.gz
src-test2-d5f23b0b7528b5c3caed1ba14f897cc4aaa9e3c3.zip
Notes
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTContext.cpp4
-rw-r--r--lib/AST/ASTDiagnostic.cpp53
-rw-r--r--lib/AST/Decl.cpp3
-rw-r--r--lib/Analysis/ThreadSafety.cpp4
-rw-r--r--lib/Basic/SourceManager.cpp39
-rw-r--r--lib/Basic/TargetInfo.cpp1
-rw-r--r--lib/Basic/Targets.cpp20
-rw-r--r--lib/CodeGen/CodeGenModule.cpp1
-rw-r--r--lib/CodeGen/ItaniumCXXABI.cpp3
-rw-r--r--lib/CodeGen/TargetInfo.cpp2
-rw-r--r--lib/Driver/ToolChains.cpp2
-rw-r--r--lib/Frontend/InitPreprocessor.cpp7
-rw-r--r--lib/Sema/DeclSpec.cpp5
-rw-r--r--lib/Sema/SemaChecking.cpp21
-rw-r--r--lib/Sema/SemaExpr.cpp7
-rw-r--r--lib/Sema/SemaExprCXX.cpp10
-rw-r--r--lib/Sema/SemaTemplate.cpp56
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;
}