aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-02-17 19:36:19 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-02-17 19:36:19 +0000
commiteb2854521a26d3f186018f1b119761ca7bb90dc2 (patch)
tree8cb7e2fc50b6c6580827cc26dc7c9a5921b4bdb2 /lib
parent3bae5253046bf2859f76e3d0d22f47a5fc0844c7 (diff)
downloadsrc-eb2854521a26d3f186018f1b119761ca7bb90dc2.tar.gz
src-eb2854521a26d3f186018f1b119761ca7bb90dc2.zip
Vendor import of clang release_40 branch r295380:vendor/clang/clang-release_40-r295380
Notes
Notes: svn path=/vendor/clang/dist/; revision=313883 svn path=/vendor/clang/clang-release_40-r295380/; revision=313884; tag=vendor/clang/clang-release_40-r295380
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ExprConstant.cpp94
-rw-r--r--lib/CodeGen/CodeGenModule.h2
-rw-r--r--lib/Parse/ParseExpr.cpp2
-rw-r--r--lib/Sema/SemaLookup.cpp11
-rw-r--r--lib/Sema/SemaStmt.cpp8
-rw-r--r--lib/Sema/SemaTemplateVariadic.cpp7
6 files changed, 78 insertions, 46 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 6a6baf96ad37..2c0fce91844c 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -604,10 +604,12 @@ namespace {
/// gets a chance to look at it.
EM_PotentialConstantExpressionUnevaluated,
- /// Evaluate as a constant expression. Continue evaluating if either:
- /// - We find a MemberExpr with a base that can't be evaluated.
- /// - We find a variable initialized with a call to a function that has
- /// the alloc_size attribute on it.
+ /// Evaluate as a constant expression. In certain scenarios, if:
+ /// - we find a MemberExpr with a base that can't be evaluated, or
+ /// - we find a variable initialized with a call to a function that has
+ /// the alloc_size attribute on it
+ /// then we may consider evaluation to have succeeded.
+ ///
/// In either case, the LValue returned shall have an invalid base; in the
/// former, the base will be the invalid MemberExpr, in the latter, the
/// base will be either the alloc_size CallExpr or a CastExpr wrapping
@@ -890,10 +892,6 @@ namespace {
return KeepGoing;
}
- bool allowInvalidBaseExpr() const {
- return EvalMode == EM_OffsetFold;
- }
-
class ArrayInitLoopIndex {
EvalInfo &Info;
uint64_t OuterIndex;
@@ -1394,8 +1392,10 @@ static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E);
static bool EvaluateInPlace(APValue &Result, EvalInfo &Info,
const LValue &This, const Expr *E,
bool AllowNonLiteralTypes = false);
-static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info);
-static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info);
+static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info,
+ bool InvalidBaseOK = false);
+static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info,
+ bool InvalidBaseOK = false);
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result,
EvalInfo &Info);
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info);
@@ -4803,6 +4803,7 @@ class LValueExprEvaluatorBase
: public ExprEvaluatorBase<Derived> {
protected:
LValue &Result;
+ bool InvalidBaseOK;
typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
@@ -4811,9 +4812,14 @@ protected:
return true;
}
+ bool evaluatePointer(const Expr *E, LValue &Result) {
+ return EvaluatePointer(E, Result, this->Info, InvalidBaseOK);
+ }
+
public:
- LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result) :
- ExprEvaluatorBaseTy(Info), Result(Result) {}
+ LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result, bool InvalidBaseOK)
+ : ExprEvaluatorBaseTy(Info), Result(Result),
+ InvalidBaseOK(InvalidBaseOK) {}
bool Success(const APValue &V, const Expr *E) {
Result.setFrom(this->Info.Ctx, V);
@@ -4825,7 +4831,7 @@ public:
QualType BaseTy;
bool EvalOK;
if (E->isArrow()) {
- EvalOK = EvaluatePointer(E->getBase(), Result, this->Info);
+ EvalOK = evaluatePointer(E->getBase(), Result);
BaseTy = E->getBase()->getType()->castAs<PointerType>()->getPointeeType();
} else if (E->getBase()->isRValue()) {
assert(E->getBase()->getType()->isRecordType());
@@ -4836,7 +4842,7 @@ public:
BaseTy = E->getBase()->getType();
}
if (!EvalOK) {
- if (!this->Info.allowInvalidBaseExpr())
+ if (!InvalidBaseOK)
return false;
Result.setInvalid(E);
return true;
@@ -4930,8 +4936,8 @@ namespace {
class LValueExprEvaluator
: public LValueExprEvaluatorBase<LValueExprEvaluator> {
public:
- LValueExprEvaluator(EvalInfo &Info, LValue &Result) :
- LValueExprEvaluatorBaseTy(Info, Result) {}
+ LValueExprEvaluator(EvalInfo &Info, LValue &Result, bool InvalidBaseOK) :
+ LValueExprEvaluatorBaseTy(Info, Result, InvalidBaseOK) {}
bool VisitVarDecl(const Expr *E, const VarDecl *VD);
bool VisitUnaryPreIncDec(const UnaryOperator *UO);
@@ -4984,10 +4990,11 @@ public:
/// * function designators in C, and
/// * "extern void" objects
/// * @selector() expressions in Objective-C
-static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info) {
+static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info,
+ bool InvalidBaseOK) {
assert(E->isGLValue() || E->getType()->isFunctionType() ||
E->getType()->isVoidType() || isa<ObjCSelectorExpr>(E));
- return LValueExprEvaluator(Info, Result).Visit(E);
+ return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
}
bool LValueExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) {
@@ -5148,7 +5155,7 @@ bool LValueExprEvaluator::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
if (E->getBase()->getType()->isVectorType())
return Error(E);
- if (!EvaluatePointer(E->getBase(), Result, Info))
+ if (!evaluatePointer(E->getBase(), Result))
return false;
APSInt Index;
@@ -5160,7 +5167,7 @@ bool LValueExprEvaluator::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
}
bool LValueExprEvaluator::VisitUnaryDeref(const UnaryOperator *E) {
- return EvaluatePointer(E->getSubExpr(), Result, Info);
+ return evaluatePointer(E->getSubExpr(), Result);
}
bool LValueExprEvaluator::VisitUnaryReal(const UnaryOperator *E) {
@@ -5308,7 +5315,7 @@ static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx,
/// and mark Result's Base as invalid.
static bool evaluateLValueAsAllocSize(EvalInfo &Info, APValue::LValueBase Base,
LValue &Result) {
- if (!Info.allowInvalidBaseExpr() || Base.isNull())
+ if (Base.isNull())
return false;
// Because we do no form of static analysis, we only support const variables.
@@ -5342,17 +5349,27 @@ namespace {
class PointerExprEvaluator
: public ExprEvaluatorBase<PointerExprEvaluator> {
LValue &Result;
+ bool InvalidBaseOK;
bool Success(const Expr *E) {
Result.set(E);
return true;
}
+ bool evaluateLValue(const Expr *E, LValue &Result) {
+ return EvaluateLValue(E, Result, Info, InvalidBaseOK);
+ }
+
+ bool evaluatePointer(const Expr *E, LValue &Result) {
+ return EvaluatePointer(E, Result, Info, InvalidBaseOK);
+ }
+
bool visitNonBuiltinCallExpr(const CallExpr *E);
public:
- PointerExprEvaluator(EvalInfo &info, LValue &Result)
- : ExprEvaluatorBaseTy(info), Result(Result) {}
+ PointerExprEvaluator(EvalInfo &info, LValue &Result, bool InvalidBaseOK)
+ : ExprEvaluatorBaseTy(info), Result(Result),
+ InvalidBaseOK(InvalidBaseOK) {}
bool Success(const APValue &V, const Expr *E) {
Result.setFrom(Info.Ctx, V);
@@ -5399,9 +5416,10 @@ public:
};
} // end anonymous namespace
-static bool EvaluatePointer(const Expr* E, LValue& Result, EvalInfo &Info) {
+static bool EvaluatePointer(const Expr* E, LValue& Result, EvalInfo &Info,
+ bool InvalidBaseOK) {
assert(E->isRValue() && E->getType()->hasPointerRepresentation());
- return PointerExprEvaluator(Info, Result).Visit(E);
+ return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
}
bool PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
@@ -5414,7 +5432,7 @@ bool PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
if (IExp->getType()->isPointerType())
std::swap(PExp, IExp);
- bool EvalPtrOK = EvaluatePointer(PExp, Result, Info);
+ bool EvalPtrOK = evaluatePointer(PExp, Result);
if (!EvalPtrOK && !Info.noteFailure())
return false;
@@ -5432,7 +5450,7 @@ bool PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
}
bool PointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) {
- return EvaluateLValue(E->getSubExpr(), Result, Info);
+ return evaluateLValue(E->getSubExpr(), Result);
}
bool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
@@ -5466,7 +5484,7 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
case CK_DerivedToBase:
case CK_UncheckedDerivedToBase:
- if (!EvaluatePointer(E->getSubExpr(), Result, Info))
+ if (!evaluatePointer(E->getSubExpr(), Result))
return false;
if (!Result.Base && Result.Offset.isZero())
return true;
@@ -5513,7 +5531,7 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
}
case CK_ArrayToPointerDecay:
if (SubExpr->isGLValue()) {
- if (!EvaluateLValue(SubExpr, Result, Info))
+ if (!evaluateLValue(SubExpr, Result))
return false;
} else {
Result.set(SubExpr, Info.CurrentCall->Index);
@@ -5530,18 +5548,19 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
return true;
case CK_FunctionToPointerDecay:
- return EvaluateLValue(SubExpr, Result, Info);
+ return evaluateLValue(SubExpr, Result);
case CK_LValueToRValue: {
LValue LVal;
- if (!EvaluateLValue(E->getSubExpr(), LVal, Info))
+ if (!evaluateLValue(E->getSubExpr(), LVal))
return false;
APValue RVal;
// Note, we use the subexpression's type in order to retain cv-qualifiers.
if (!handleLValueToRValueConversion(Info, E, E->getSubExpr()->getType(),
LVal, RVal))
- return evaluateLValueAsAllocSize(Info, LVal.Base, Result);
+ return InvalidBaseOK &&
+ evaluateLValueAsAllocSize(Info, LVal.Base, Result);
return Success(RVal, E);
}
}
@@ -5586,7 +5605,7 @@ bool PointerExprEvaluator::visitNonBuiltinCallExpr(const CallExpr *E) {
if (ExprEvaluatorBaseTy::VisitCallExpr(E))
return true;
- if (!(Info.allowInvalidBaseExpr() && getAllocSizeAttr(E)))
+ if (!(InvalidBaseOK && getAllocSizeAttr(E)))
return false;
Result.setInvalid(E);
@@ -5609,12 +5628,12 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
unsigned BuiltinOp) {
switch (BuiltinOp) {
case Builtin::BI__builtin_addressof:
- return EvaluateLValue(E->getArg(0), Result, Info);
+ return evaluateLValue(E->getArg(0), Result);
case Builtin::BI__builtin_assume_aligned: {
// We need to be very careful here because: if the pointer does not have the
// asserted alignment, then the behavior is undefined, and undefined
// behavior is non-constant.
- if (!EvaluatePointer(E->getArg(0), Result, Info))
+ if (!evaluatePointer(E->getArg(0), Result))
return false;
LValue OffsetResult(Result);
@@ -6255,7 +6274,7 @@ class TemporaryExprEvaluator
: public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
public:
TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) :
- LValueExprEvaluatorBaseTy(Info, Result) {}
+ LValueExprEvaluatorBaseTy(Info, Result, false) {}
/// Visit an expression which constructs the value of this temporary.
bool VisitConstructExpr(const Expr *E) {
@@ -7358,7 +7377,8 @@ static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type,
if (!EvaluateAsRValue(Info, E, RVal))
return false;
LVal.setFrom(Info.Ctx, RVal);
- } else if (!EvaluatePointer(ignorePointerCastsAndParens(E), LVal, Info))
+ } else if (!EvaluatePointer(ignorePointerCastsAndParens(E), LVal, Info,
+ /*InvalidBaseOK=*/true))
return false;
}
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 1d72b4edeb13..36f6785fd1b9 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -166,7 +166,7 @@ struct ObjCEntrypoints {
/// void objc_release(id);
llvm::Constant *objc_release;
- /// id objc_storeStrong(id*, id);
+ /// void objc_storeStrong(id*, id);
llvm::Constant *objc_storeStrong;
/// id objc_storeWeak(id*, id);
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index ee06c76f6024..852e2269393a 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -2408,7 +2408,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
// fold-expressions, we'll need to allow multiple ArgExprs here.
if (ArgExprs.size() == 1 && isFoldOperator(Tok.getKind()) &&
NextToken().is(tok::ellipsis))
- return ParseFoldExpression(Result, T);
+ return ParseFoldExpression(ArgExprs[0], T);
ExprType = SimpleExpr;
Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(),
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 38a7b8c127cc..e2cb2c8169ce 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -2831,6 +2831,9 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
assert((SM != CXXDefaultConstructor && SM != CXXDestructor) &&
"parameter-less special members can't have qualified arguments");
+ // FIXME: Get the caller to pass in a location for the lookup.
+ SourceLocation LookupLoc = RD->getLocation();
+
llvm::FoldingSetNodeID ID;
ID.AddPointer(RD);
ID.AddInteger(SM);
@@ -2912,7 +2915,7 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
VK = VK_RValue;
}
- OpaqueValueExpr FakeArg(SourceLocation(), ArgType, VK);
+ OpaqueValueExpr FakeArg(LookupLoc, ArgType, VK);
if (SM != CXXDefaultConstructor) {
NumArgs = 1;
@@ -2926,13 +2929,13 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
if (VolatileThis)
ThisTy.addVolatile();
Expr::Classification Classification =
- OpaqueValueExpr(SourceLocation(), ThisTy,
+ OpaqueValueExpr(LookupLoc, ThisTy,
RValueThis ? VK_RValue : VK_LValue).Classify(Context);
// Now we perform lookup on the name we computed earlier and do overload
// resolution. Lookup is only performed directly into the class since there
// will always be a (possibly implicit) declaration to shadow any others.
- OverloadCandidateSet OCS(RD->getLocation(), OverloadCandidateSet::CSK_Normal);
+ OverloadCandidateSet OCS(LookupLoc, OverloadCandidateSet::CSK_Normal);
DeclContext::lookup_result R = RD->lookup(Name);
if (R.empty()) {
@@ -2987,7 +2990,7 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
}
OverloadCandidateSet::iterator Best;
- switch (OCS.BestViableFunction(*this, SourceLocation(), Best)) {
+ switch (OCS.BestViableFunction(*this, LookupLoc, Best)) {
case OR_Success:
Result->setMethod(cast<CXXMethodDecl>(Best->Function));
Result->setKind(SpecialMemberOverloadResult::Success);
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index a8832e9a1c54..390e1b52c8ed 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -2743,15 +2743,17 @@ bool Sema::isCopyElisionCandidate(QualType ReturnType, const VarDecl *VD,
// ...automatic...
if (!VD->hasLocalStorage()) return false;
+ // Return false if VD is a __block variable. We don't want to implicitly move
+ // out of a __block variable during a return because we cannot assume the
+ // variable will no longer be used.
+ if (VD->hasAttr<BlocksAttr>()) return false;
+
if (AllowParamOrMoveConstructible)
return true;
// ...non-volatile...
if (VD->getType().isVolatileQualified()) return false;
- // __block variables can't be allocated in a way that permits NRVO.
- if (VD->hasAttr<BlocksAttr>()) return false;
-
// Variables with higher required alignment than their type's ABI
// alignment cannot use NRVO.
if (!VD->getType()->isDependentType() && VD->hasAttr<AlignedAttr>() &&
diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp
index 54556b505ee0..725a3e425201 100644
--- a/lib/Sema/SemaTemplateVariadic.cpp
+++ b/lib/Sema/SemaTemplateVariadic.cpp
@@ -1014,6 +1014,11 @@ ExprResult Sema::ActOnCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS,
CheckFoldOperand(*this, LHS);
CheckFoldOperand(*this, RHS);
+ auto DiscardOperands = [&] {
+ CorrectDelayedTyposInExpr(LHS);
+ CorrectDelayedTyposInExpr(RHS);
+ };
+
// [expr.prim.fold]p3:
// In a binary fold, op1 and op2 shall be the same fold-operator, and
// either e1 shall contain an unexpanded parameter pack or e2 shall contain
@@ -1021,6 +1026,7 @@ ExprResult Sema::ActOnCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS,
if (LHS && RHS &&
LHS->containsUnexpandedParameterPack() ==
RHS->containsUnexpandedParameterPack()) {
+ DiscardOperands();
return Diag(EllipsisLoc,
LHS->containsUnexpandedParameterPack()
? diag::err_fold_expression_packs_both_sides
@@ -1034,6 +1040,7 @@ ExprResult Sema::ActOnCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS,
if (!LHS || !RHS) {
Expr *Pack = LHS ? LHS : RHS;
assert(Pack && "fold expression with neither LHS nor RHS");
+ DiscardOperands();
if (!Pack->containsUnexpandedParameterPack())
return Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
<< Pack->getSourceRange();