diff options
| author | 2017-03-14 08:07:52 +0000 | |
|---|---|---|
| committer | 2017-03-14 08:07:52 +0000 | |
| commit | 1cb66ada17adf0954eaadba4d02ec2470365a3ac (patch) | |
| tree | 521159d8f39562a43fffd680147eb5a71709b9b1 /gnu/llvm/tools/clang/lib | |
| parent | Mark the sshd_config UsePrivilegeSeparation option as deprecated, (diff) | |
| download | wireguard-openbsd-1cb66ada17adf0954eaadba4d02ec2470365a3ac.tar.xz wireguard-openbsd-1cb66ada17adf0954eaadba4d02ec2470365a3ac.zip | |
Import LLVM 4.0.0 release including clang and lld.
Diffstat (limited to 'gnu/llvm/tools/clang/lib')
29 files changed, 319 insertions, 345 deletions
diff --git a/gnu/llvm/tools/clang/lib/AST/ASTContext.cpp b/gnu/llvm/tools/clang/lib/AST/ASTContext.cpp index d03c22af5b2..b531a66dbab 100644 --- a/gnu/llvm/tools/clang/lib/AST/ASTContext.cpp +++ b/gnu/llvm/tools/clang/lib/AST/ASTContext.cpp @@ -9025,7 +9025,8 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { // Variables that have initialization with side-effects are required. if (VD->getInit() && VD->getInit()->HasSideEffects(*this) && - !VD->evaluateValue()) + // We can get a value-dependent initializer during error recovery. + (VD->getInit()->isValueDependent() || !VD->evaluateValue())) return true; // Likewise, variables with tuple-like bindings are required if their diff --git a/gnu/llvm/tools/clang/lib/AST/ExprConstant.cpp b/gnu/llvm/tools/clang/lib/AST/ExprConstant.cpp index a8512b29405..2c0fce91844 100644 --- a/gnu/llvm/tools/clang/lib/AST/ExprConstant.cpp +++ b/gnu/llvm/tools/clang/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); @@ -2362,7 +2362,14 @@ static unsigned getBaseIndex(const CXXRecordDecl *Derived, /// Extract the value of a character from a string literal. static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, uint64_t Index) { - // FIXME: Support ObjCEncodeExpr, MakeStringConstant + // FIXME: Support MakeStringConstant + if (const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) { + std::string Str; + Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str); + assert(Index <= Str.size() && "Index too large"); + return APSInt::getUnsigned(Str.c_str()[Index]); + } + if (auto PE = dyn_cast<PredefinedExpr>(Lit)) Lit = PE->getFunctionName(); const StringLiteral *S = cast<StringLiteral>(Lit); @@ -4796,6 +4803,7 @@ class LValueExprEvaluatorBase : public ExprEvaluatorBase<Derived> { protected: LValue &Result; + bool InvalidBaseOK; typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy; typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy; @@ -4804,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); @@ -4818,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()); @@ -4829,7 +4842,7 @@ public: BaseTy = E->getBase()->getType(); } if (!EvalOK) { - if (!this->Info.allowInvalidBaseExpr()) + if (!InvalidBaseOK) return false; Result.setInvalid(E); return true; @@ -4923,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); @@ -4977,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) { @@ -5141,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; @@ -5153,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) { @@ -5301,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. @@ -5335,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); @@ -5392,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) { @@ -5407,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; @@ -5425,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) { @@ -5459,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; @@ -5506,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); @@ -5523,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); } } @@ -5579,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); @@ -5602,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); @@ -5683,6 +5709,7 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, case Builtin::BI__builtin_strchr: case Builtin::BI__builtin_wcschr: case Builtin::BI__builtin_memchr: + case Builtin::BI__builtin_char_memchr: case Builtin::BI__builtin_wmemchr: { if (!Visit(E->getArg(0))) return false; @@ -5720,6 +5747,7 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, // Fall through. case Builtin::BImemchr: case Builtin::BI__builtin_memchr: + case Builtin::BI__builtin_char_memchr: // memchr compares by converting both sides to unsigned char. That's also // correct for strchr if we get this far (to cope with plain char being // unsigned in the strchr case). @@ -6246,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) { @@ -7349,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/gnu/llvm/tools/clang/lib/Basic/Version.cpp b/gnu/llvm/tools/clang/lib/Basic/Version.cpp index ee60ca74924..97e75a9cd45 100644 --- a/gnu/llvm/tools/clang/lib/Basic/Version.cpp +++ b/gnu/llvm/tools/clang/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_400/rc1/lib/Basic/Version.cpp $"); + StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_400/final/lib/Basic/Version.cpp $"); if (URL.empty()) { URL = SVNRepository.slice(SVNRepository.find(':'), SVNRepository.find("/lib/Basic")); diff --git a/gnu/llvm/tools/clang/lib/CodeGen/CGBuiltin.cpp b/gnu/llvm/tools/clang/lib/CodeGen/CGBuiltin.cpp index 2ede1d46b3d..b3d02f1f51c 100644 --- a/gnu/llvm/tools/clang/lib/CodeGen/CGBuiltin.cpp +++ b/gnu/llvm/tools/clang/lib/CodeGen/CGBuiltin.cpp @@ -1189,6 +1189,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, return RValue::get(Dest.getPointer()); } + case Builtin::BI__builtin_char_memchr: + BuiltinID = Builtin::BI__builtin_memchr; + break; + case Builtin::BI__builtin___memcpy_chk: { // fold __builtin_memcpy_chk(x, y, cst1, cst2) to memcpy iff cst1<=cst2. llvm::APSInt Size, DstSize; diff --git a/gnu/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/gnu/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp index db9de2ab6ad..40252171368 100644 --- a/gnu/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/gnu/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -4697,7 +4697,9 @@ void CGOpenMPRuntime::emitCancellationPointCall( // global_tid, kmp_int32 cncl_kind); if (auto *OMPRegionInfo = dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) { - if (OMPRegionInfo->hasCancel()) { + // For 'cancellation point taskgroup', the task region info may not have a + // cancel. This may instead happen in another adjacent task. + if (CancelRegion == OMPD_taskgroup || OMPRegionInfo->hasCancel()) { llvm::Value *Args[] = { emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc), CGF.Builder.getInt32(getCancellationKind(CancelRegion))}; @@ -4705,7 +4707,6 @@ void CGOpenMPRuntime::emitCancellationPointCall( auto *Result = CGF.EmitRuntimeCall( createRuntimeFunction(OMPRTL__kmpc_cancellationpoint), Args); // if (__kmpc_cancellationpoint()) { - // __kmpc_cancel_barrier(); // exit from construct; // } auto *ExitBB = CGF.createBasicBlock(".cancel.exit"); @@ -4713,8 +4714,6 @@ void CGOpenMPRuntime::emitCancellationPointCall( auto *Cmp = CGF.Builder.CreateIsNotNull(Result); CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB); CGF.EmitBlock(ExitBB); - // __kmpc_cancel_barrier(); - emitBarrierCall(CGF, Loc, OMPD_unknown, /*EmitChecks=*/false); // exit from construct; auto CancelDest = CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind()); @@ -4743,7 +4742,6 @@ void CGOpenMPRuntime::emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc, auto *Result = CGF.EmitRuntimeCall( RT.createRuntimeFunction(OMPRTL__kmpc_cancel), Args); // if (__kmpc_cancel()) { - // __kmpc_cancel_barrier(); // exit from construct; // } auto *ExitBB = CGF.createBasicBlock(".cancel.exit"); @@ -4751,8 +4749,6 @@ void CGOpenMPRuntime::emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc, auto *Cmp = CGF.Builder.CreateIsNotNull(Result); CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB); CGF.EmitBlock(ExitBB); - // __kmpc_cancel_barrier(); - RT.emitBarrierCall(CGF, Loc, OMPD_unknown, /*EmitChecks=*/false); // exit from construct; auto CancelDest = CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind()); diff --git a/gnu/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp b/gnu/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp index 137c69420dd..e142a21b1e7 100644 --- a/gnu/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/gnu/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp @@ -112,9 +112,8 @@ CodeGenFunction::~CodeGenFunction() { if (FirstBlockInfo) destroyBlockInfos(FirstBlockInfo); - if (getLangOpts().OpenMP) { + if (getLangOpts().OpenMP && CurFn) CGM.getOpenMPRuntime().functionFinished(*this); - } } CharUnits CodeGenFunction::getNaturalPointeeTypeAlignment(QualType T, diff --git a/gnu/llvm/tools/clang/lib/CodeGen/CodeGenModule.h b/gnu/llvm/tools/clang/lib/CodeGen/CodeGenModule.h index 1d72b4edeb1..36f6785fd1b 100644 --- a/gnu/llvm/tools/clang/lib/CodeGen/CodeGenModule.h +++ b/gnu/llvm/tools/clang/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/gnu/llvm/tools/clang/lib/CodeGen/CodeGenTypes.cpp b/gnu/llvm/tools/clang/lib/CodeGen/CodeGenTypes.cpp index b95b4fff573..adb40c8c0d4 100644 --- a/gnu/llvm/tools/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/gnu/llvm/tools/clang/lib/CodeGen/CodeGenTypes.cpp @@ -737,7 +737,7 @@ CodeGenTypes::getCGRecordLayout(const RecordDecl *RD) { } bool CodeGenTypes::isPointerZeroInitializable(QualType T) { - assert (T->isAnyPointerType() && "Invalid type"); + assert((T->isAnyPointerType() || T->isBlockPointerType()) && "Invalid type"); return isZeroInitializable(T); } diff --git a/gnu/llvm/tools/clang/lib/Frontend/InitPreprocessor.cpp b/gnu/llvm/tools/clang/lib/Frontend/InitPreprocessor.cpp index 4502c92499a..17603ada11d 100644 --- a/gnu/llvm/tools/clang/lib/Frontend/InitPreprocessor.cpp +++ b/gnu/llvm/tools/clang/lib/Frontend/InitPreprocessor.cpp @@ -286,12 +286,12 @@ static void DefineFastIntType(unsigned TypeWidth, bool IsSigned, /// Get the value the ATOMIC_*_LOCK_FREE macro should have for a type with /// the specified properties. -static const char *getLockFreeValue(unsigned TypeWidth, unsigned InlineWidth) { +static const char *getLockFreeValue(unsigned TypeWidth, unsigned TypeAlign, + unsigned InlineWidth) { // Fully-aligned, power-of-2 sizes no larger than the inline // width will be inlined as lock-free operations. - // Note: we do not need to check alignment since _Atomic(T) is always - // appropriately-aligned in clang. - if ((TypeWidth & (TypeWidth - 1)) == 0 && TypeWidth <= InlineWidth) + if (TypeWidth == TypeAlign && (TypeWidth & (TypeWidth - 1)) == 0 && + TypeWidth <= InlineWidth) return "2"; // "always lock free" // We cannot be certain what operations the lib calls might be // able to implement as lock-free on future processors. @@ -881,6 +881,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI, #define DEFINE_LOCK_FREE_MACRO(TYPE, Type) \ Builder.defineMacro("__GCC_ATOMIC_" #TYPE "_LOCK_FREE", \ getLockFreeValue(TI.get##Type##Width(), \ + TI.get##Type##Align(), \ InlineWidthBits)); DEFINE_LOCK_FREE_MACRO(BOOL, Bool); DEFINE_LOCK_FREE_MACRO(CHAR, Char); @@ -893,6 +894,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI, DEFINE_LOCK_FREE_MACRO(LLONG, LongLong); Builder.defineMacro("__GCC_ATOMIC_POINTER_LOCK_FREE", getLockFreeValue(TI.getPointerWidth(0), + TI.getPointerAlign(0), InlineWidthBits)); #undef DEFINE_LOCK_FREE_MACRO } diff --git a/gnu/llvm/tools/clang/lib/Index/IndexDecl.cpp b/gnu/llvm/tools/clang/lib/Index/IndexDecl.cpp index 7d60aad3895..3b4f3f81399 100644 --- a/gnu/llvm/tools/clang/lib/Index/IndexDecl.cpp +++ b/gnu/llvm/tools/clang/lib/Index/IndexDecl.cpp @@ -92,7 +92,13 @@ public: Relations.emplace_back((unsigned)SymbolRole::RelationAccessorOf, AssociatedProp); - if (!IndexCtx.handleDecl(D, (unsigned)SymbolRole::Dynamic, Relations)) + // getLocation() returns beginning token of a method declaration, but for + // indexing purposes we want to point to the base name. + SourceLocation MethodLoc = D->getSelectorStartLoc(); + if (MethodLoc.isInvalid()) + MethodLoc = D->getLocation(); + + if (!IndexCtx.handleDecl(D, MethodLoc, (unsigned)SymbolRole::Dynamic, Relations)) return false; IndexCtx.indexTypeSourceInfo(D->getReturnTypeSourceInfo(), D); bool hasIBActionAndFirst = D->hasAttr<IBActionAttr>(); diff --git a/gnu/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp b/gnu/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp index aebebaac46a..de166c75e2c 100644 --- a/gnu/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp +++ b/gnu/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp @@ -1183,6 +1183,7 @@ static bool HasFeature(const Preprocessor &PP, StringRef Feature) { .Case("cxx_attributes", LangOpts.CPlusPlus11) .Case("cxx_auto_type", LangOpts.CPlusPlus11) .Case("cxx_constexpr", LangOpts.CPlusPlus11) + .Case("cxx_constexpr_string_builtins", LangOpts.CPlusPlus11) .Case("cxx_decltype", LangOpts.CPlusPlus11) .Case("cxx_decltype_incomplete_return_types", LangOpts.CPlusPlus11) .Case("cxx_default_function_template_args", LangOpts.CPlusPlus11) diff --git a/gnu/llvm/tools/clang/lib/Parse/ParseExpr.cpp b/gnu/llvm/tools/clang/lib/Parse/ParseExpr.cpp index ee06c76f602..852e2269393 100644 --- a/gnu/llvm/tools/clang/lib/Parse/ParseExpr.cpp +++ b/gnu/llvm/tools/clang/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/gnu/llvm/tools/clang/lib/Sema/SemaChecking.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaChecking.cpp index 49208e20a49..3aedb2a8c9b 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaChecking.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaChecking.cpp @@ -2426,11 +2426,12 @@ static void CheckNonNullArguments(Sema &S, } /// Handles the checks for format strings, non-POD arguments to vararg -/// functions, and NULL arguments passed to non-NULL parameters. +/// functions, NULL arguments passed to non-NULL parameters, and diagnose_if +/// attributes. void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, - ArrayRef<const Expr *> Args, bool IsMemberFunction, - SourceLocation Loc, SourceRange Range, - VariadicCallType CallType) { + const Expr *ThisArg, ArrayRef<const Expr *> Args, + bool IsMemberFunction, SourceLocation Loc, + SourceRange Range, VariadicCallType CallType) { // FIXME: We should check as much as we can in the template definition. if (CurContext->isDependentContext()) return; @@ -2477,6 +2478,9 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, CheckArgumentWithTypeTag(I, Args.data()); } } + + if (FD) + diagnoseArgDependentDiagnoseIfAttrs(FD, ThisArg, Args, Loc); } /// CheckConstructorCall - Check a constructor call for correctness and safety @@ -2487,8 +2491,8 @@ void Sema::CheckConstructorCall(FunctionDecl *FDecl, SourceLocation Loc) { VariadicCallType CallType = Proto->isVariadic() ? VariadicConstructor : VariadicDoesNotApply; - checkCall(FDecl, Proto, Args, /*IsMemberFunction=*/true, Loc, SourceRange(), - CallType); + checkCall(FDecl, Proto, /*ThisArg=*/nullptr, Args, /*IsMemberFunction=*/true, + Loc, SourceRange(), CallType); } /// CheckFunctionCall - Check a direct function call for various correctness @@ -2503,14 +2507,20 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, TheCall->getCallee()); Expr** Args = TheCall->getArgs(); unsigned NumArgs = TheCall->getNumArgs(); + + Expr *ImplicitThis = nullptr; if (IsMemberOperatorCall) { // If this is a call to a member operator, hide the first argument // from checkCall. // FIXME: Our choice of AST representation here is less than ideal. + ImplicitThis = Args[0]; ++Args; --NumArgs; - } - checkCall(FDecl, Proto, llvm::makeArrayRef(Args, NumArgs), + } else if (IsMemberFunction) + ImplicitThis = + cast<CXXMemberCallExpr>(TheCall)->getImplicitObjectArgument(); + + checkCall(FDecl, Proto, ImplicitThis, llvm::makeArrayRef(Args, NumArgs), IsMemberFunction, TheCall->getRParenLoc(), TheCall->getCallee()->getSourceRange(), CallType); @@ -2546,8 +2556,8 @@ bool Sema::CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation lbrac, VariadicCallType CallType = Method->isVariadic() ? VariadicMethod : VariadicDoesNotApply; - checkCall(Method, nullptr, Args, - /*IsMemberFunction=*/false, lbrac, Method->getSourceRange(), + checkCall(Method, nullptr, /*ThisArg=*/nullptr, Args, + /*IsMemberFunction=*/false, lbrac, Method->getSourceRange(), CallType); return false; @@ -2576,7 +2586,7 @@ bool Sema::CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall, CallType = VariadicFunction; } - checkCall(NDecl, Proto, + checkCall(NDecl, Proto, /*ThisArg=*/nullptr, llvm::makeArrayRef(TheCall->getArgs(), TheCall->getNumArgs()), /*IsMemberFunction=*/false, TheCall->getRParenLoc(), TheCall->getCallee()->getSourceRange(), CallType); @@ -2589,7 +2599,7 @@ bool Sema::CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall, bool Sema::CheckOtherCall(CallExpr *TheCall, const FunctionProtoType *Proto) { VariadicCallType CallType = getVariadicCallType(/*FDecl=*/nullptr, Proto, TheCall->getCallee()); - checkCall(/*FDecl=*/nullptr, Proto, + checkCall(/*FDecl=*/nullptr, Proto, /*ThisArg=*/nullptr, llvm::makeArrayRef(TheCall->getArgs(), TheCall->getNumArgs()), /*IsMemberFunction=*/false, TheCall->getRParenLoc(), TheCall->getCallee()->getSourceRange(), CallType); diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp index a70e16cce18..f265f4c00f7 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp @@ -12383,9 +12383,9 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) { Diag(Loc, diag::err_in_class_initializer_not_yet_parsed) << OutermostClass << Field; Diag(Field->getLocEnd(), diag::note_in_class_initializer_not_yet_parsed); - - // Don't diagnose this again. - Field->setInvalidDecl(); + // Recover by marking the field invalid, unless we're in a SFINAE context. + if (!isSFINAEContext()) + Field->setInvalidDecl(); return ExprError(); } diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaExpr.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaExpr.cpp index d62e8fd68b6..0077d6c539c 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaExpr.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaExpr.cpp @@ -342,7 +342,6 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, } // See if this is a deleted function. - SmallVector<DiagnoseIfAttr *, 4> DiagnoseIfWarnings; if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { if (FD->isDeleted()) { auto *Ctor = dyn_cast<CXXConstructorDecl>(FD); @@ -365,11 +364,8 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, if (getLangOpts().CUDA && !CheckCUDACall(Loc, FD)) return true; - if (const DiagnoseIfAttr *A = - checkArgIndependentDiagnoseIf(FD, DiagnoseIfWarnings)) { - emitDiagnoseIfDiagnostic(Loc, A); + if (diagnoseArgIndependentDiagnoseIfAttrs(FD, Loc)) return true; - } } // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions @@ -385,9 +381,6 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, return true; } - for (const auto *W : DiagnoseIfWarnings) - emitDiagnoseIfDiagnostic(Loc, W); - DiagnoseAvailabilityOfDecl(*this, D, Loc, UnknownObjCClass, ObjCPropertyAccess); @@ -5189,16 +5182,6 @@ static void checkDirectCallValidity(Sema &S, const Expr *Fn, << Attr->getCond()->getSourceRange() << Attr->getMessage(); return; } - - SmallVector<DiagnoseIfAttr *, 4> Nonfatal; - if (const DiagnoseIfAttr *Attr = S.checkArgDependentDiagnoseIf( - Callee, ArgExprs, Nonfatal, /*MissingImplicitThis=*/true)) { - S.emitDiagnoseIfDiagnostic(Fn->getLocStart(), Attr); - return; - } - - for (const auto *W : Nonfatal) - S.emitDiagnoseIfDiagnostic(Fn->getLocStart(), W); } /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments. @@ -11496,7 +11479,7 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc, return checkPseudoObjectAssignment(S, OpLoc, Opc, LHSExpr, RHSExpr); // Don't resolve overloads if the other type is overloadable. - if (pty->getKind() == BuiltinType::Overload) { + if (getLangOpts().CPlusPlus && pty->getKind() == BuiltinType::Overload) { // We can't actually test that if we still have a placeholder, // though. Fortunately, none of the exceptions we see in that // code below are valid when the LHS is an overload set. Note @@ -11521,17 +11504,16 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc, // An overload in the RHS can potentially be resolved by the type // being assigned to. if (Opc == BO_Assign && pty->getKind() == BuiltinType::Overload) { - if (LHSExpr->isTypeDependent() || RHSExpr->isTypeDependent()) - return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr); - - if (LHSExpr->getType()->isOverloadableType()) + if (getLangOpts().CPlusPlus && + (LHSExpr->isTypeDependent() || RHSExpr->isTypeDependent() || + LHSExpr->getType()->isOverloadableType())) return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr); return CreateBuiltinBinOp(OpLoc, Opc, LHSExpr, RHSExpr); } // Don't resolve overloads if the other type is overloadable. - if (pty->getKind() == BuiltinType::Overload && + if (getLangOpts().CPlusPlus && pty->getKind() == BuiltinType::Overload && LHSExpr->getType()->isOverloadableType()) return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr); diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp index b2fb33f5343..3afa95f7d1f 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp @@ -6712,6 +6712,11 @@ ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl, CXXMemberCallExpr *CE = new (Context) CXXMemberCallExpr(Context, ME, None, ResultType, VK, Exp.get()->getLocEnd()); + + if (CheckFunctionCall(Method, CE, + Method->getType()->castAs<FunctionProtoType>())) + return ExprError(); + return CE; } @@ -7185,14 +7190,6 @@ public: ExprResult TransformBlockExpr(BlockExpr *E) { return Owned(E); } - ExprResult TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { - return Owned(E); - } - - ExprResult TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) { - return Owned(E); - } - ExprResult Transform(Expr *E) { ExprResult Res; while (true) { diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaInit.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaInit.cpp index 45eff5ee6b6..b053c83c3f6 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaInit.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaInit.cpp @@ -1684,7 +1684,7 @@ void InitListChecker::CheckArrayType(const InitializedEntity &Entity, // If this is an incomplete array type, the actual type needs to // be calculated here. llvm::APSInt Zero(maxElements.getBitWidth(), maxElements.isUnsigned()); - if (maxElements == Zero) { + if (maxElements == Zero && !Entity.isVariableLengthArrayNew()) { // Sizing an array implicitly to zero is not allowed by ISO C, // but is supported by GNU. SemaRef.Diag(IList->getLocStart(), diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaLookup.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaLookup.cpp index 883e2ae264e..e2cb2c8169c 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaLookup.cpp +++ b/gnu/llvm/tools/clang/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()) { @@ -2960,7 +2963,6 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD, if (CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(Cand->getUnderlyingDecl())) { if (SM == CXXCopyAssignment || SM == CXXMoveAssignment) AddMethodCandidate(M, Cand, RD, ThisTy, Classification, - /*ThisArg=*/nullptr, llvm::makeArrayRef(&Arg, NumArgs), OCS, true); else if (CtorInfo) AddOverloadCandidate(CtorInfo.Constructor, CtorInfo.FoundDecl, @@ -2973,7 +2975,7 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD, if (SM == CXXCopyAssignment || SM == CXXMoveAssignment) AddMethodTemplateCandidate( Tmpl, Cand, RD, nullptr, ThisTy, Classification, - /*ThisArg=*/nullptr, llvm::makeArrayRef(&Arg, NumArgs), OCS, true); + llvm::makeArrayRef(&Arg, NumArgs), OCS, true); else if (CtorInfo) AddTemplateOverloadCandidate( CtorInfo.ConstructorTmpl, CtorInfo.FoundDecl, nullptr, @@ -2988,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/gnu/llvm/tools/clang/lib/Sema/SemaOverload.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaOverload.cpp index afdae4ed6d7..f976b76727f 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaOverload.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaOverload.cpp @@ -839,20 +839,12 @@ void OverloadCandidateSet::destroyCandidates() { void OverloadCandidateSet::clear() { destroyCandidates(); - // DiagnoseIfAttrs are just pointers, so we don't need to destroy them. SlabAllocator.Reset(); NumInlineBytesUsed = 0; Candidates.clear(); Functions.clear(); } -DiagnoseIfAttr ** -OverloadCandidateSet::addDiagnoseIfComplaints(ArrayRef<DiagnoseIfAttr *> CA) { - auto *DIA = slabAllocate<DiagnoseIfAttr *>(CA.size()); - std::uninitialized_copy(CA.begin(), CA.end(), DIA); - return DIA; -} - namespace { class UnbridgedCastsSet { struct Entry { @@ -5831,28 +5823,6 @@ static bool IsAcceptableNonMemberOperatorCandidate(ASTContext &Context, return false; } -static void initDiagnoseIfComplaint(Sema &S, OverloadCandidateSet &CandidateSet, - OverloadCandidate &Candidate, - FunctionDecl *Function, - ArrayRef<Expr *> Args, - bool MissingImplicitThis = false, - Expr *ExplicitThis = nullptr) { - SmallVector<DiagnoseIfAttr *, 8> Results; - if (DiagnoseIfAttr *DIA = S.checkArgDependentDiagnoseIf( - Function, Args, Results, MissingImplicitThis, ExplicitThis)) { - Results.clear(); - Results.push_back(DIA); - } - - Candidate.NumTriggeredDiagnoseIfs = Results.size(); - if (Results.empty()) - Candidate.DiagnoseIfInfo = nullptr; - else if (Results.size() == 1) - Candidate.DiagnoseIfInfo = Results[0]; - else - Candidate.DiagnoseIfInfo = CandidateSet.addDiagnoseIfComplaints(Results); -} - /// AddOverloadCandidate - Adds the given function to the set of /// candidate functions, using the given function call arguments. If /// @p SuppressUserConversions, then don't allow user-defined @@ -5886,10 +5856,9 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, // object argument (C++ [over.call.func]p3), and the acting context // is irrelevant. AddMethodCandidate(Method, FoundDecl, Method->getParent(), QualType(), - Expr::Classification::makeSimpleLValue(), - /*ThisArg=*/nullptr, Args, CandidateSet, - SuppressUserConversions, PartialOverloading, - EarlyConversions); + Expr::Classification::makeSimpleLValue(), Args, + CandidateSet, SuppressUserConversions, + PartialOverloading, EarlyConversions); return; } // We treat a constructor like a non-member function, since its object @@ -5944,6 +5913,28 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, Candidate.FailureKind = ovl_fail_illegal_constructor; return; } + + // C++ [over.match.funcs]p8: (proposed DR resolution) + // A constructor inherited from class type C that has a first parameter + // of type "reference to P" (including such a constructor instantiated + // from a template) is excluded from the set of candidate functions when + // constructing an object of type cv D if the argument list has exactly + // one argument and D is reference-related to P and P is reference-related + // to C. + auto *Shadow = dyn_cast<ConstructorUsingShadowDecl>(FoundDecl.getDecl()); + if (Shadow && Args.size() == 1 && Constructor->getNumParams() >= 1 && + Constructor->getParamDecl(0)->getType()->isReferenceType()) { + QualType P = Constructor->getParamDecl(0)->getType()->getPointeeType(); + QualType C = Context.getRecordType(Constructor->getParent()); + QualType D = Context.getRecordType(Shadow->getParent()); + SourceLocation Loc = Args.front()->getExprLoc(); + if ((Context.hasSameUnqualifiedType(P, C) || IsDerivedFrom(Loc, P, C)) && + (Context.hasSameUnqualifiedType(D, P) || IsDerivedFrom(Loc, D, P))) { + Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_inhctor_slice; + return; + } + } } unsigned NumParams = Proto->getNumParams(); @@ -6016,31 +6007,6 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, } } - // C++ [over.best.ics]p4+: (proposed DR resolution) - // If the target is the first parameter of an inherited constructor when - // constructing an object of type C with an argument list that has exactly - // one expression, an implicit conversion sequence cannot be formed if C is - // reference-related to the type that the argument would have after the - // application of the user-defined conversion (if any) and before the final - // standard conversion sequence. - auto *Shadow = dyn_cast<ConstructorUsingShadowDecl>(FoundDecl.getDecl()); - if (Shadow && Args.size() == 1 && !isa<InitListExpr>(Args.front())) { - bool DerivedToBase, ObjCConversion, ObjCLifetimeConversion; - QualType ConvertedArgumentType = Args.front()->getType(); - if (Candidate.Conversions[0].isUserDefined()) - ConvertedArgumentType = - Candidate.Conversions[0].UserDefined.After.getFromType(); - if (CompareReferenceRelationship(Args.front()->getLocStart(), - Context.getRecordType(Shadow->getParent()), - ConvertedArgumentType, DerivedToBase, - ObjCConversion, - ObjCLifetimeConversion) >= Ref_Related) { - Candidate.Viable = false; - Candidate.FailureKind = ovl_fail_inhctor_slice; - return; - } - } - if (EnableIfAttr *FailedAttr = CheckEnableIf(Function, Args)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_enable_if; @@ -6053,8 +6019,6 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, Candidate.FailureKind = ovl_fail_ext_disabled; return; } - - initDiagnoseIfComplaint(*this, CandidateSet, Candidate, Function, Args); } ObjCMethodDecl * @@ -6263,85 +6227,73 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args, return nullptr; } -static bool gatherDiagnoseIfAttrs(FunctionDecl *Function, bool ArgDependent, - SmallVectorImpl<DiagnoseIfAttr *> &Errors, - SmallVectorImpl<DiagnoseIfAttr *> &Nonfatal) { - for (auto *DIA : Function->specific_attrs<DiagnoseIfAttr>()) - if (ArgDependent == DIA->getArgDependent()) { - if (DIA->isError()) - Errors.push_back(DIA); - else - Nonfatal.push_back(DIA); - } +template <typename CheckFn> +static bool diagnoseDiagnoseIfAttrsWith(Sema &S, const FunctionDecl *FD, + bool ArgDependent, SourceLocation Loc, + CheckFn &&IsSuccessful) { + SmallVector<const DiagnoseIfAttr *, 8> Attrs; + for (const auto *DIA : FD->specific_attrs<DiagnoseIfAttr>()) { + if (ArgDependent == DIA->getArgDependent()) + Attrs.push_back(DIA); + } - return !Errors.empty() || !Nonfatal.empty(); -} + // Common case: No diagnose_if attributes, so we can quit early. + if (Attrs.empty()) + return false; + + auto WarningBegin = std::stable_partition( + Attrs.begin(), Attrs.end(), + [](const DiagnoseIfAttr *DIA) { return DIA->isError(); }); -template <typename CheckFn> -static DiagnoseIfAttr * -checkDiagnoseIfAttrsWith(const SmallVectorImpl<DiagnoseIfAttr *> &Errors, - SmallVectorImpl<DiagnoseIfAttr *> &Nonfatal, - CheckFn &&IsSuccessful) { // Note that diagnose_if attributes are late-parsed, so they appear in the // correct order (unlike enable_if attributes). - auto ErrAttr = llvm::find_if(Errors, IsSuccessful); - if (ErrAttr != Errors.end()) - return *ErrAttr; - - llvm::erase_if(Nonfatal, [&](DiagnoseIfAttr *A) { return !IsSuccessful(A); }); - return nullptr; -} - -DiagnoseIfAttr * -Sema::checkArgDependentDiagnoseIf(FunctionDecl *Function, ArrayRef<Expr *> Args, - SmallVectorImpl<DiagnoseIfAttr *> &Nonfatal, - bool MissingImplicitThis, - Expr *ThisArg) { - SmallVector<DiagnoseIfAttr *, 4> Errors; - if (!gatherDiagnoseIfAttrs(Function, /*ArgDependent=*/true, Errors, Nonfatal)) - return nullptr; + auto ErrAttr = llvm::find_if(llvm::make_range(Attrs.begin(), WarningBegin), + IsSuccessful); + if (ErrAttr != WarningBegin) { + const DiagnoseIfAttr *DIA = *ErrAttr; + S.Diag(Loc, diag::err_diagnose_if_succeeded) << DIA->getMessage(); + S.Diag(DIA->getLocation(), diag::note_from_diagnose_if) + << DIA->getParent() << DIA->getCond()->getSourceRange(); + return true; + } - SFINAETrap Trap(*this); - SmallVector<Expr *, 16> ConvertedArgs; - Expr *ConvertedThis; - if (!convertArgsForAvailabilityChecks(*this, Function, ThisArg, Args, Trap, - MissingImplicitThis, ConvertedThis, - ConvertedArgs)) - return nullptr; + for (const auto *DIA : llvm::make_range(WarningBegin, Attrs.end())) + if (IsSuccessful(DIA)) { + S.Diag(Loc, diag::warn_diagnose_if_succeeded) << DIA->getMessage(); + S.Diag(DIA->getLocation(), diag::note_from_diagnose_if) + << DIA->getParent() << DIA->getCond()->getSourceRange(); + } - return checkDiagnoseIfAttrsWith(Errors, Nonfatal, [&](DiagnoseIfAttr *DIA) { - APValue Result; - // It's sane to use the same ConvertedArgs for any redecl of this function, - // since EvaluateWithSubstitution only cares about the position of each - // argument in the arg list, not the ParmVarDecl* it maps to. - if (!DIA->getCond()->EvaluateWithSubstitution( - Result, Context, DIA->getParent(), ConvertedArgs, ConvertedThis)) - return false; - return Result.isInt() && Result.getInt().getBoolValue(); - }); + return false; } -DiagnoseIfAttr *Sema::checkArgIndependentDiagnoseIf( - FunctionDecl *Function, SmallVectorImpl<DiagnoseIfAttr *> &Nonfatal) { - SmallVector<DiagnoseIfAttr *, 4> Errors; - if (!gatherDiagnoseIfAttrs(Function, /*ArgDependent=*/false, Errors, - Nonfatal)) - return nullptr; - - return checkDiagnoseIfAttrsWith(Errors, Nonfatal, [&](DiagnoseIfAttr *DIA) { - bool Result; - return DIA->getCond()->EvaluateAsBooleanCondition(Result, Context) && - Result; - }); +bool Sema::diagnoseArgDependentDiagnoseIfAttrs(const FunctionDecl *Function, + const Expr *ThisArg, + ArrayRef<const Expr *> Args, + SourceLocation Loc) { + return diagnoseDiagnoseIfAttrsWith( + *this, Function, /*ArgDependent=*/true, Loc, + [&](const DiagnoseIfAttr *DIA) { + APValue Result; + // It's sane to use the same Args for any redecl of this function, since + // EvaluateWithSubstitution only cares about the position of each + // argument in the arg list, not the ParmVarDecl* it maps to. + if (!DIA->getCond()->EvaluateWithSubstitution( + Result, Context, DIA->getParent(), Args, ThisArg)) + return false; + return Result.isInt() && Result.getInt().getBoolValue(); + }); } -void Sema::emitDiagnoseIfDiagnostic(SourceLocation Loc, - const DiagnoseIfAttr *DIA) { - auto Code = DIA->isError() ? diag::err_diagnose_if_succeeded - : diag::warn_diagnose_if_succeeded; - Diag(Loc, Code) << DIA->getMessage(); - Diag(DIA->getLocation(), diag::note_from_diagnose_if) - << DIA->getParent() << DIA->getCond()->getSourceRange(); +bool Sema::diagnoseArgIndependentDiagnoseIfAttrs(const FunctionDecl *Function, + SourceLocation Loc) { + return diagnoseDiagnoseIfAttrsWith( + *this, Function, /*ArgDependent=*/false, Loc, + [&](const DiagnoseIfAttr *DIA) { + bool Result; + return DIA->getCond()->EvaluateAsBooleanCondition(Result, Context) && + Result; + }); } /// \brief Add all of the function declarations in the given function set to @@ -6359,8 +6311,8 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns, AddMethodCandidate(cast<CXXMethodDecl>(FD), F.getPair(), cast<CXXMethodDecl>(FD)->getParent(), Args[0]->getType(), Args[0]->Classify(Context), - Args[0], Args.slice(1), CandidateSet, - SuppressUserConversions, PartialOverloading); + Args.slice(1), CandidateSet, SuppressUserConversions, + PartialOverloading); else AddOverloadCandidate(FD, F.getPair(), Args, CandidateSet, SuppressUserConversions, PartialOverloading); @@ -6372,7 +6324,7 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns, FunTmpl, F.getPair(), cast<CXXRecordDecl>(FunTmpl->getDeclContext()), ExplicitTemplateArgs, Args[0]->getType(), - Args[0]->Classify(Context), Args[0], Args.slice(1), CandidateSet, + Args[0]->Classify(Context), Args.slice(1), CandidateSet, SuppressUserConversions, PartialOverloading); else AddTemplateOverloadCandidate(FunTmpl, F.getPair(), @@ -6388,7 +6340,6 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns, void Sema::AddMethodCandidate(DeclAccessPair FoundDecl, QualType ObjectType, Expr::Classification ObjectClassification, - Expr *ThisArg, ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, bool SuppressUserConversions) { @@ -6402,15 +6353,13 @@ void Sema::AddMethodCandidate(DeclAccessPair FoundDecl, assert(isa<CXXMethodDecl>(TD->getTemplatedDecl()) && "Expected a member function template"); AddMethodTemplateCandidate(TD, FoundDecl, ActingContext, - /*ExplicitArgs*/ nullptr, - ObjectType, ObjectClassification, - ThisArg, Args, CandidateSet, + /*ExplicitArgs*/ nullptr, ObjectType, + ObjectClassification, Args, CandidateSet, SuppressUserConversions); } else { AddMethodCandidate(cast<CXXMethodDecl>(Decl), FoundDecl, ActingContext, - ObjectType, ObjectClassification, - ThisArg, Args, - CandidateSet, SuppressUserConversions); + ObjectType, ObjectClassification, Args, CandidateSet, + SuppressUserConversions); } } @@ -6425,7 +6374,7 @@ void Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, QualType ObjectType, Expr::Classification ObjectClassification, - Expr *ThisArg, ArrayRef<Expr *> Args, + ArrayRef<Expr *> Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, bool PartialOverloading, @@ -6547,9 +6496,6 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, Candidate.DeductionFailure.Data = FailedAttr; return; } - - initDiagnoseIfComplaint(*this, CandidateSet, Candidate, Method, Args, - /*MissingImplicitThis=*/!ThisArg, ThisArg); } /// \brief Add a C++ member function template as a candidate to the candidate @@ -6562,7 +6508,6 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, TemplateArgumentListInfo *ExplicitTemplateArgs, QualType ObjectType, Expr::Classification ObjectClassification, - Expr *ThisArg, ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, bool SuppressUserConversions, @@ -6616,9 +6561,9 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, assert(isa<CXXMethodDecl>(Specialization) && "Specialization is not a member function?"); AddMethodCandidate(cast<CXXMethodDecl>(Specialization), FoundDecl, - ActingContext, ObjectType, ObjectClassification, - /*ThisArg=*/ThisArg, Args, CandidateSet, - SuppressUserConversions, PartialOverloading, Conversions); + ActingContext, ObjectType, ObjectClassification, Args, + CandidateSet, SuppressUserConversions, PartialOverloading, + Conversions); } /// \brief Add a C++ function template specialization as a candidate @@ -6945,8 +6890,6 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion, Candidate.DeductionFailure.Data = FailedAttr; return; } - - initDiagnoseIfComplaint(*this, CandidateSet, Candidate, Conversion, None, false, From); } /// \brief Adds a conversion function template specialization @@ -7099,8 +7042,6 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion, Candidate.DeductionFailure.Data = FailedAttr; return; } - - initDiagnoseIfComplaint(*this, CandidateSet, Candidate, Conversion, None); } /// \brief Add overload candidates for overloaded operators that are @@ -7149,7 +7090,7 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op, Oper != OperEnd; ++Oper) AddMethodCandidate(Oper.getPair(), Args[0]->getType(), - Args[0]->Classify(Context), Args[0], Args.slice(1), + Args[0]->Classify(Context), Args.slice(1), CandidateSet, /*SuppressUserConversions=*/false); } } @@ -9181,17 +9122,6 @@ void Sema::diagnoseEquivalentInternalLinkageDeclarations( } } -static bool isCandidateUnavailableDueToDiagnoseIf(const OverloadCandidate &OC) { - ArrayRef<DiagnoseIfAttr *> Info = OC.getDiagnoseIfInfo(); - if (!Info.empty() && Info[0]->isError()) - return true; - - assert(llvm::all_of(Info, - [](const DiagnoseIfAttr *A) { return !A->isError(); }) && - "DiagnoseIf info shouldn't have mixed warnings and errors."); - return false; -} - /// \brief Computes the best viable function (C++ 13.3.3) /// within an overload candidate set. /// @@ -9270,19 +9200,13 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc, // Best is the best viable function. if (Best->Function && (Best->Function->isDeleted() || - S.isFunctionConsideredUnavailable(Best->Function) || - isCandidateUnavailableDueToDiagnoseIf(*Best))) + S.isFunctionConsideredUnavailable(Best->Function))) return OR_Deleted; if (!EquivalentCands.empty()) S.diagnoseEquivalentInternalLinkageDeclarations(Loc, Best->Function, EquivalentCands); - for (const auto *W : Best->getDiagnoseIfInfo()) { - assert(W->isWarning() && "Errors should've been caught earlier!"); - S.emitDiagnoseIfDiagnostic(Loc, W); - } - return OR_Success; } @@ -10165,14 +10089,6 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } - if (isCandidateUnavailableDueToDiagnoseIf(*Cand)) { - auto *A = Cand->DiagnoseIfInfo.get<DiagnoseIfAttr *>(); - assert(A->isError() && "Non-error diagnose_if disables a candidate?"); - S.Diag(Cand->Function->getLocation(), - diag::note_ovl_candidate_disabled_by_function_cond_attr) - << A->getCond()->getSourceRange() << A->getMessage(); - return; - } // We don't really have anything else to say about viable candidates. S.NoteOverloadCandidate(Cand->FoundDecl, Fn); @@ -10222,8 +10138,13 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, return DiagnoseOpenCLExtensionDisabled(S, Cand); case ovl_fail_inhctor_slice: + // It's generally not interesting to note copy/move constructors here. + if (cast<CXXConstructorDecl>(Fn)->isCopyOrMoveConstructor()) + return; S.Diag(Fn->getLocation(), - diag::note_ovl_candidate_inherited_constructor_slice); + diag::note_ovl_candidate_inherited_constructor_slice) + << (Fn->getPrimaryTemplate() ? 1 : 0) + << Fn->getParamDecl(0)->getType()->isRValueReferenceType(); MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; @@ -12111,6 +12032,10 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl)) return ExprError(); + if (CheckFunctionCall(FnDecl, TheCall, + FnDecl->getType()->castAs<FunctionProtoType>())) + return ExprError(); + return MaybeBindToTemporary(TheCall); } else { // We matched a built-in operator. Convert the arguments, then @@ -12341,16 +12266,20 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, return ExprError(); ArrayRef<const Expr *> ArgsArray(Args, 2); + const Expr *ImplicitThis = nullptr; // Cut off the implicit 'this'. - if (isa<CXXMethodDecl>(FnDecl)) + if (isa<CXXMethodDecl>(FnDecl)) { + ImplicitThis = ArgsArray[0]; ArgsArray = ArgsArray.slice(1); + } // Check for a self move. if (Op == OO_Equal) DiagnoseSelfMove(Args[0], Args[1], OpLoc); - checkCall(FnDecl, nullptr, ArgsArray, isa<CXXMethodDecl>(FnDecl), OpLoc, - TheCall->getSourceRange(), VariadicDoesNotApply); + checkCall(FnDecl, nullptr, ImplicitThis, ArgsArray, + isa<CXXMethodDecl>(FnDecl), OpLoc, TheCall->getSourceRange(), + VariadicDoesNotApply); return MaybeBindToTemporary(TheCall); } else { @@ -12559,6 +12488,10 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, if (CheckCallReturnType(FnDecl->getReturnType(), LLoc, TheCall, FnDecl)) return ExprError(); + if (CheckFunctionCall(Method, TheCall, + Method->getType()->castAs<FunctionProtoType>())) + return ExprError(); + return MaybeBindToTemporary(TheCall); } else { // We matched a built-in operator. Convert the arguments, then @@ -12725,16 +12658,6 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, TemplateArgs = &TemplateArgsBuffer; } - // Poor-programmer's Lazy<Expr *>; isImplicitAccess requires stripping - // parens/casts, which would be nice to avoid potentially doing multiple - // times. - llvm::Optional<Expr *> UnresolvedBase; - auto GetUnresolvedBase = [&] { - if (!UnresolvedBase.hasValue()) - UnresolvedBase = - UnresExpr->isImplicitAccess() ? nullptr : UnresExpr->getBase(); - return *UnresolvedBase; - }; for (UnresolvedMemberExpr::decls_iterator I = UnresExpr->decls_begin(), E = UnresExpr->decls_end(); I != E; ++I) { @@ -12755,14 +12678,12 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, continue; AddMethodCandidate(Method, I.getPair(), ActingDC, ObjectType, - ObjectClassification, - /*ThisArg=*/GetUnresolvedBase(), Args, CandidateSet, + ObjectClassification, Args, CandidateSet, /*SuppressUserConversions=*/false); } else { AddMethodTemplateCandidate( cast<FunctionTemplateDecl>(Func), I.getPair(), ActingDC, - TemplateArgs, ObjectType, ObjectClassification, - /*ThisArg=*/GetUnresolvedBase(), Args, CandidateSet, + TemplateArgs, ObjectType, ObjectClassification, Args, CandidateSet, /*SuppressUsedConversions=*/false); } } @@ -12880,16 +12801,6 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, << Attr->getCond()->getSourceRange() << Attr->getMessage(); return ExprError(); } - - SmallVector<DiagnoseIfAttr *, 4> Nonfatal; - if (const DiagnoseIfAttr *Attr = checkArgDependentDiagnoseIf( - Method, Args, Nonfatal, false, MemE->getBase())) { - emitDiagnoseIfDiagnostic(MemE->getMemberLoc(), Attr); - return ExprError(); - } - - for (const auto *Attr : Nonfatal) - emitDiagnoseIfDiagnostic(MemE->getMemberLoc(), Attr); } if ((isa<CXXConstructorDecl>(CurContext) || @@ -12968,9 +12879,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end(); Oper != OperEnd; ++Oper) { AddMethodCandidate(Oper.getPair(), Object.get()->getType(), - Object.get()->Classify(Context), - Object.get(), Args, CandidateSet, - /*SuppressUserConversions=*/ false); + Object.get()->Classify(Context), Args, CandidateSet, + /*SuppressUserConversions=*/false); } // C++ [over.call.object]p2: @@ -13245,8 +13155,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end(); Oper != OperEnd; ++Oper) { AddMethodCandidate(Oper.getPair(), Base->getType(), Base->Classify(Context), - Base, None, CandidateSet, - /*SuppressUserConversions=*/false); + None, CandidateSet, /*SuppressUserConversions=*/false); } bool HadMultipleCandidates = (CandidateSet.size() > 1); @@ -13320,7 +13229,11 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, Base, ResultTy, VK, OpLoc, false); if (CheckCallReturnType(Method->getReturnType(), OpLoc, TheCall, Method)) - return ExprError(); + return ExprError(); + + if (CheckFunctionCall(Method, TheCall, + Method->getType()->castAs<FunctionProtoType>())) + return ExprError(); return MaybeBindToTemporary(TheCall); } diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaStmt.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaStmt.cpp index a8832e9a1c5..390e1b52c8e 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaStmt.cpp +++ b/gnu/llvm/tools/clang/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/gnu/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 48d8b94af15..200775756d3 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4996,8 +4996,12 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, NamedDecl *Result = nullptr; // FIXME: If the name is a dependent name, this lookup won't necessarily // find it. Does that ever matter? - if (D->getDeclName()) { - DeclContext::lookup_result Found = ParentDC->lookup(D->getDeclName()); + if (auto Name = D->getDeclName()) { + DeclarationNameInfo NameInfo(Name, D->getLocation()); + Name = SubstDeclarationNameInfo(NameInfo, TemplateArgs).getName(); + if (!Name) + return nullptr; + DeclContext::lookup_result Found = ParentDC->lookup(Name); Result = findInstantiationOf(Context, D, Found.begin(), Found.end()); } else { // Since we don't have a name for the entity we're looking for, diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaTemplateVariadic.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaTemplateVariadic.cpp index 54556b505ee..725a3e42520 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/gnu/llvm/tools/clang/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(); diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaType.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaType.cpp index 29b21426790..2cdf76caa7e 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaType.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaType.cpp @@ -3154,7 +3154,7 @@ getCCForDeclaratorChunk(Sema &S, Declarator &D, if (Attr->getKind() == AttributeList::AT_OpenCLKernel) { llvm::Triple::ArchType arch = S.Context.getTargetInfo().getTriple().getArch(); if (arch == llvm::Triple::spir || arch == llvm::Triple::spir64 || - arch == llvm::Triple::amdgcn) { + arch == llvm::Triple::amdgcn || arch == llvm::Triple::r600) { CC = CC_OpenCLKernel; } break; diff --git a/gnu/llvm/tools/clang/lib/Sema/TreeTransform.h b/gnu/llvm/tools/clang/lib/Sema/TreeTransform.h index c2aa3fef67c..f8e65a119c3 100644 --- a/gnu/llvm/tools/clang/lib/Sema/TreeTransform.h +++ b/gnu/llvm/tools/clang/lib/Sema/TreeTransform.h @@ -2932,16 +2932,17 @@ public: ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar, SourceLocation IvarLoc, bool IsArrow, bool IsFreeIvar) { - // FIXME: We lose track of the IsFreeIvar bit. CXXScopeSpec SS; DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc); - return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(), - /*FIXME:*/IvarLoc, IsArrow, - SS, SourceLocation(), - /*FirstQualifierInScope=*/nullptr, - NameInfo, - /*TemplateArgs=*/nullptr, - /*S=*/nullptr); + ExprResult Result = getSema().BuildMemberReferenceExpr( + BaseArg, BaseArg->getType(), + /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(), + /*FirstQualifierInScope=*/nullptr, NameInfo, + /*TemplateArgs=*/nullptr, + /*S=*/nullptr); + if (IsFreeIvar && Result.isUsable()) + cast<ObjCIvarRefExpr>(Result.get())->setIsFreeIvar(IsFreeIvar); + return Result; } /// \brief Build a new Objective-C property reference expression. @@ -8818,12 +8819,18 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) { // base (and therefore couldn't do the check) and a // nested-name-qualifier (and therefore could do the lookup). NamedDecl *FirstQualifierInScope = nullptr; + DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo(); + if (MemberNameInfo.getName()) { + MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo); + if (!MemberNameInfo.getName()) + return ExprError(); + } return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc, E->isArrow(), QualifierLoc, TemplateKWLoc, - E->getMemberNameInfo(), + MemberNameInfo, Member, FoundDecl, (E->hasExplicitTemplateArgs() diff --git a/gnu/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp b/gnu/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp index c6919193391..707a9249dd9 100644 --- a/gnu/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/gnu/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2513,8 +2513,8 @@ static bool isConsumerInterestedIn(ASTContext &Ctx, Decl *D, bool HasBody) { // An ImportDecl or VarDecl imported from a module will get emitted when // we import the relevant module. - if ((isa<ImportDecl>(D) || isa<VarDecl>(D)) && Ctx.DeclMustBeEmitted(D) && - D->getImportedOwningModule()) + if ((isa<ImportDecl>(D) || isa<VarDecl>(D)) && D->getImportedOwningModule() && + Ctx.DeclMustBeEmitted(D)) return false; if (isa<FileScopeAsmDecl>(D) || diff --git a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp index 0e0f52af316..437378e53da 100644 --- a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp +++ b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp @@ -94,11 +94,18 @@ void MacOSXAPIChecker::CheckDispatchOnce(CheckerContext &C, const CallExpr *CE, bool SuggestStatic = false; os << "Call to '" << FName << "' uses"; if (const VarRegion *VR = dyn_cast<VarRegion>(RB)) { + const VarDecl *VD = VR->getDecl(); + // FIXME: These should have correct memory space and thus should be filtered + // out earlier. This branch only fires when we're looking from a block, + // which we analyze as a top-level declaration, onto a static local + // in a function that contains the block. + if (VD->isStaticLocal()) + return; // We filtered out globals earlier, so it must be a local variable // or a block variable which is under UnknownSpaceRegion. if (VR != R) os << " memory within"; - if (VR->getDecl()->hasAttr<BlocksAttr>()) + if (VD->hasAttr<BlocksAttr>()) os << " the block variable '"; else os << " the local variable '"; diff --git a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp index 15e8ea31c4c..b47762b915c 100644 --- a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp +++ b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp @@ -179,7 +179,8 @@ void WalkAST::VisitCXXMemberCallExpr(CallExpr *CE) { } // Get the callee. - const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CE->getDirectCallee()); + const CXXMethodDecl *MD = + dyn_cast_or_null<CXXMethodDecl>(CE->getDirectCallee()); if (MD && MD->isVirtual() && !callIsNonVirtual && !MD->hasAttr<FinalAttr>() && !MD->getParent()->hasAttr<FinalAttr>()) ReportVirtualCall(CE, MD->isPure()); diff --git a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp index c4ba2ae199f..d6e8fe5b51b 100644 --- a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp +++ b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp @@ -816,9 +816,11 @@ const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D, const StackFrameContext *STC = V.get<const StackFrameContext*>(); - if (!STC) + if (!STC) { + // FIXME: Assign a more sensible memory space to static locals + // we see from within blocks that we analyze as top-level declarations. sReg = getUnknownRegion(); - else { + } else { if (D->hasLocalStorage()) { sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D) ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC)) diff --git a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index 15ca2c14f94..934cc5cd3ac 100644 --- a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -1849,6 +1849,8 @@ SVal RegionStoreManager::getBindingForVar(RegionBindingsConstRef B, // Function-scoped static variables are default-initialized to 0; if they // have an initializer, it would have been processed by now. + // FIXME: This is only true when we're starting analysis from main(). + // We're losing a lot of coverage here. if (isa<StaticGlobalSpaceRegion>(MS)) return svalBuilder.makeZeroVal(T); |
