diff options
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 808 |
1 files changed, 625 insertions, 183 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 5a2eb6060ee9..57159fb59715 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -49,7 +49,7 @@ using namespace sema; /// \brief Determine whether the use of this declaration is valid, without /// emitting diagnostics. -bool Sema::CanUseDecl(NamedDecl *D) { +bool Sema::CanUseDecl(NamedDecl *D, bool TreatUnavailableAsInvalid) { // See if this is an auto-typed variable whose initializer we are parsing. if (ParsingInitForAutoVars.count(D)) return false; @@ -67,7 +67,7 @@ bool Sema::CanUseDecl(NamedDecl *D) { } // See if this function is unavailable. - if (D->getAvailability() == AR_Unavailable && + if (TreatUnavailableAsInvalid && D->getAvailability() == AR_Unavailable && cast<Decl>(CurContext)->getAvailability() != AR_Unavailable) return false; @@ -76,10 +76,14 @@ bool Sema::CanUseDecl(NamedDecl *D) { static void DiagnoseUnusedOfDecl(Sema &S, NamedDecl *D, SourceLocation Loc) { // Warn if this is used but marked unused. - if (D->hasAttr<UnusedAttr>()) { - const Decl *DC = cast_or_null<Decl>(S.getCurObjCLexicalContext()); - if (DC && !DC->hasAttr<UnusedAttr>()) - S.Diag(Loc, diag::warn_used_but_marked_unused) << D->getDeclName(); + if (const auto *A = D->getAttr<UnusedAttr>()) { + // [[maybe_unused]] should not diagnose uses, but __attribute__((unused)) + // should diagnose them. + if (A->getSemanticSpelling() != UnusedAttr::CXX11_maybe_unused) { + const Decl *DC = cast_or_null<Decl>(S.getCurObjCLexicalContext()); + if (DC && !DC->hasAttr<UnusedAttr>()) + S.Diag(Loc, diag::warn_used_but_marked_unused) << D->getDeclName(); + } } } @@ -137,7 +141,7 @@ DiagnoseAvailabilityOfDecl(Sema &S, NamedDecl *D, SourceLocation Loc, const ObjCPropertyDecl *ObjCPDecl = nullptr; if (Result == AR_Deprecated || Result == AR_Unavailable || - AR_NotYetIntroduced) { + Result == AR_NotYetIntroduced) { if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { if (const ObjCPropertyDecl *PD = MD->findPropertyDecl()) { AvailabilityResult PDeclResult = PD->getAvailability(nullptr); @@ -212,25 +216,14 @@ void Sema::NoteDeletedFunction(FunctionDecl *Decl) { // deleted. This might fail, if that reason no longer applies. CXXSpecialMember CSM = getSpecialMember(Method); if (CSM != CXXInvalid) - ShouldDeleteSpecialMember(Method, CSM, /*Diagnose=*/true); + ShouldDeleteSpecialMember(Method, CSM, nullptr, /*Diagnose=*/true); return; } - if (CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(Decl)) { - if (CXXConstructorDecl *BaseCD = - const_cast<CXXConstructorDecl*>(CD->getInheritedConstructor())) { - Diag(Decl->getLocation(), diag::note_inherited_deleted_here); - if (BaseCD->isDeleted()) { - NoteDeletedFunction(BaseCD); - } else { - // FIXME: An explanation of why exactly it can't be inherited - // would be nice. - Diag(BaseCD->getLocation(), diag::note_cannot_inherit); - } - return; - } - } + auto *Ctor = dyn_cast<CXXConstructorDecl>(Decl); + if (Ctor && Ctor->isInheritingConstructor()) + return NoteDeletedInheritingConstructor(Ctor); Diag(Decl->getLocation(), diag::note_availability_specified_here) << Decl << true; @@ -357,7 +350,13 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, // See if this is a deleted function. if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { if (FD->isDeleted()) { - Diag(Loc, diag::err_deleted_function_use); + auto *Ctor = dyn_cast<CXXConstructorDecl>(FD); + if (Ctor && Ctor->isInheritingConstructor()) + Diag(Loc, diag::err_deleted_inherited_ctor_use) + << Ctor->getParent() + << Ctor->getInheritedConstructor().getConstructor()->getParent(); + else + Diag(Loc, diag::err_deleted_function_use); NoteDeletedFunction(FD); return true; } @@ -368,6 +367,19 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, DeduceReturnType(FD, Loc)) return true; } + + // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions + // Only the variables omp_in and omp_out are allowed in the combiner. + // Only the variables omp_priv and omp_orig are allowed in the + // initializer-clause. + auto *DRD = dyn_cast<OMPDeclareReductionDecl>(CurContext); + if (LangOpts.OpenMP && DRD && !CurContext->containsDecl(D) && + isa<VarDecl>(D)) { + Diag(Loc, diag::err_omp_wrong_var_in_declare_reduction) + << getCurFunction()->HasOMPDeclareReductionCombiner; + Diag(D->getLocation(), diag::note_entity_declared_at) << D; + return true; + } DiagnoseAvailabilityOfDecl(*this, D, Loc, UnknownObjCClass, ObjCPropertyAccess); @@ -695,7 +707,7 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) { // balance that. if (getLangOpts().ObjCAutoRefCount && E->getType().getObjCLifetime() == Qualifiers::OCL_Weak) - ExprNeedsCleanups = true; + Cleanup.setExprNeedsCleanups(true); ExprResult Res = ImplicitCastExpr::Create(Context, T, CK_LValueToRValue, E, nullptr, VK_RValue); @@ -1138,6 +1150,48 @@ static QualType handleFloatConversion(Sema &S, ExprResult &LHS, /*convertFloat=*/!IsCompAssign); } +/// \brief Diagnose attempts to convert between __float128 and long double if +/// there is no support for such conversion. Helper function of +/// UsualArithmeticConversions(). +static bool unsupportedTypeConversion(const Sema &S, QualType LHSType, + QualType RHSType) { + /* No issue converting if at least one of the types is not a floating point + type or the two types have the same rank. + */ + if (!LHSType->isFloatingType() || !RHSType->isFloatingType() || + S.Context.getFloatingTypeOrder(LHSType, RHSType) == 0) + return false; + + assert(LHSType->isFloatingType() && RHSType->isFloatingType() && + "The remaining types must be floating point types."); + + auto *LHSComplex = LHSType->getAs<ComplexType>(); + auto *RHSComplex = RHSType->getAs<ComplexType>(); + + QualType LHSElemType = LHSComplex ? + LHSComplex->getElementType() : LHSType; + QualType RHSElemType = RHSComplex ? + RHSComplex->getElementType() : RHSType; + + // No issue if the two types have the same representation + if (&S.Context.getFloatTypeSemantics(LHSElemType) == + &S.Context.getFloatTypeSemantics(RHSElemType)) + return false; + + bool Float128AndLongDouble = (LHSElemType == S.Context.Float128Ty && + RHSElemType == S.Context.LongDoubleTy); + Float128AndLongDouble |= (LHSElemType == S.Context.LongDoubleTy && + RHSElemType == S.Context.Float128Ty); + + /* We've handled the situation where __float128 and long double have the same + representation. The only other allowable conversion is if long double is + really just double. + */ + return Float128AndLongDouble && + (&S.Context.getFloatTypeSemantics(S.Context.LongDoubleTy) != + &llvm::APFloat::IEEEdouble); +} + typedef ExprResult PerformCastFn(Sema &S, Expr *operand, QualType toType); namespace { @@ -1301,6 +1355,11 @@ QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, // At this point, we have two different arithmetic types. + // Diagnose attempts to convert between __float128 and long double where + // such conversions currently can't be handled. + if (unsupportedTypeConversion(*this, LHSType, RHSType)) + return QualType(); + // Handle complex types first (C99 6.3.1.8p1). if (LHSType->isComplexType() || RHSType->isComplexType()) return handleComplexFloatConversion(*this, LHS, RHS, LHSType, RHSType, @@ -1719,10 +1778,12 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, E->getLocStart())) recordUseOfEvaluatedWeak(E); - // Just in case we're building an illegal pointer-to-member. - FieldDecl *FD = dyn_cast<FieldDecl>(D); - if (FD && FD->isBitField()) - E->setObjectKind(OK_BitField); + if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { + UnusedPrivateFields.remove(FD); + // Just in case we're building an illegal pointer-to-member. + if (FD->isBitField()) + E->setObjectKind(OK_BitField); + } return E; } @@ -2840,6 +2901,7 @@ ExprResult Sema::BuildDeclarationNameExpr( // Unresolved using declarations are dependent. case Decl::EnumConstant: case Decl::UnresolvedUsingValue: + case Decl::OMPDeclareReduction: valueKind = VK_RValue; break; @@ -2877,6 +2939,7 @@ ExprResult Sema::BuildDeclarationNameExpr( case Decl::Var: case Decl::VarTemplateSpecialization: case Decl::VarTemplatePartialSpecialization: + case Decl::OMPCapturedExpr: // In C, "extern void blah;" is valid and is an r-value. if (!getLangOpts().CPlusPlus && !type.hasQualifiers() && @@ -3297,12 +3360,21 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { if (Literal.isFloatingLiteral()) { QualType Ty; - if (Literal.isFloat) + if (Literal.isHalf){ + if (getOpenCLOptions().cl_khr_fp16) + Ty = Context.HalfTy; + else { + Diag(Tok.getLocation(), diag::err_half_const_requires_fp16); + return ExprError(); + } + } else if (Literal.isFloat) Ty = Context.FloatTy; - else if (!Literal.isLong) - Ty = Context.DoubleTy; - else + else if (Literal.isLong) Ty = Context.LongDoubleTy; + else if (Literal.isFloat128) + Ty = Context.Float128Ty; + else + Ty = Context.DoubleTy; Res = BuildFloatingLiteral(*this, Literal, Ty, Tok.getLocation()); @@ -3890,14 +3962,24 @@ Sema::CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo, if (T->isVariablyModifiedType() && FunctionScopes.size() > 1) { if (auto *TT = T->getAs<TypedefType>()) { - if (auto *CSI = dyn_cast<CapturingScopeInfo>(FunctionScopes.back())) { + for (auto I = FunctionScopes.rbegin(), + E = std::prev(FunctionScopes.rend()); + I != E; ++I) { + auto *CSI = dyn_cast<CapturingScopeInfo>(*I); + if (CSI == nullptr) + break; DeclContext *DC = nullptr; - if (auto LSI = dyn_cast<LambdaScopeInfo>(CSI)) + if (auto *LSI = dyn_cast<LambdaScopeInfo>(CSI)) DC = LSI->CallOperator; - else if (auto CRSI = dyn_cast<CapturedRegionScopeInfo>(CSI)) + else if (auto *CRSI = dyn_cast<CapturedRegionScopeInfo>(CSI)) DC = CRSI->TheCapturedDecl; - if (DC && TT->getDecl()->getDeclContext() != DC) + else if (auto *BSI = dyn_cast<BlockScopeInfo>(CSI)) + DC = BSI->TheDecl; + if (DC) { + if (DC->containsDecl(TT->getDecl())) + break; captureVariablyModifiedType(Context, T, CSI); + } } } } @@ -4141,12 +4223,18 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, ExprResult Result = CheckPlaceholderExpr(LowerBound); if (Result.isInvalid()) return ExprError(); + Result = DefaultLvalueConversion(Result.get()); + if (Result.isInvalid()) + return ExprError(); LowerBound = Result.get(); } if (Length && Length->getType()->isNonOverloadPlaceholderType()) { ExprResult Result = CheckPlaceholderExpr(Length); if (Result.isInvalid()) return ExprError(); + Result = DefaultLvalueConversion(Result.get()); + if (Result.isInvalid()) + return ExprError(); Length = Result.get(); } @@ -4253,6 +4341,13 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, return ExprError(); } + if (!Base->getType()->isSpecificPlaceholderType( + BuiltinType::OMPArraySection)) { + ExprResult Result = DefaultFunctionArrayLvalueConversion(Base); + if (Result.isInvalid()) + return ExprError(); + Base = Result.get(); + } return new (Context) OMPArraySectionExpr(Base, LowerBound, Length, Context.OMPArraySectionTy, VK_LValue, OK_Ordinary, ColonLoc, RBLoc); @@ -4466,6 +4561,13 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, } } + // If the default argument expression is not set yet, we are building it now. + if (!Param->hasInit()) { + Diag(Param->getLocStart(), diag::err_recursive_default_argument) << FD; + Param->setInvalidDecl(); + return ExprError(); + } + // If the default expression creates temporaries, we need to // push them to the current stack of expression temporaries so they'll // be properly destroyed. @@ -4473,15 +4575,15 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, // bound temporaries; see the comment in PR5810. // We don't need to do that with block decls, though, because // blocks in default argument expression can never capture anything. - if (isa<ExprWithCleanups>(Param->getInit())) { + if (auto Init = dyn_cast<ExprWithCleanups>(Param->getInit())) { // Set the "needs cleanups" bit regardless of whether there are // any explicit objects. - ExprNeedsCleanups = true; + Cleanup.setExprNeedsCleanups(Init->cleanupsHaveSideEffects()); // Append all the objects to the cleanup list. Right now, this // should always be a no-op, because blocks in default argument // expressions should never be able to capture anything. - assert(!cast<ExprWithCleanups>(Param->getInit())->getNumObjects() && + assert(!Init->getNumObjects() && "default argument expression has capturing blocks?"); } @@ -4866,6 +4968,9 @@ static bool isPlaceholderToRemoveAsArg(QualType type) { switch (placeholder->getKind()) { // Ignore all the non-placeholder types. +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: +#include "clang/Basic/OpenCLImageTypes.def" #define PLACEHOLDER_TYPE(ID, SINGLETON_ID) #define BUILTIN_TYPE(ID, SINGLETON_ID) case BuiltinType::ID: #include "clang/AST/BuiltinTypes.def" @@ -4995,6 +5100,14 @@ static FunctionDecl *rewriteBuiltinFunctionDecl(Sema *Sema, ASTContext &Context, return OverloadDecl; } +static bool isNumberOfArgsValidForCall(Sema &S, const FunctionDecl *Callee, + std::size_t NumArgs) { + if (S.TooManyArguments(Callee->getNumParams(), NumArgs, + /*PartialOverloading=*/false)) + return Callee->isVariadic(); + return Callee->getMinRequiredArguments() <= NumArgs; +} + /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments. /// This provides the location of the left/right parens and a list of comma /// locations. @@ -5032,8 +5145,6 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, // Determine whether this is a dependent call inside a C++ template, // in which case we won't do any semantic analysis now. - // FIXME: Will need to cache the results of name lookup (including ADL) in - // Fn. bool Dependent = false; if (Fn->isTypeDependent()) Dependent = true; @@ -5126,7 +5237,14 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, Fn->getLocStart())) return ExprError(); - if (FD->hasAttr<EnableIfAttr>()) { + // CheckEnableIf assumes that the we're passing in a sane number of args for + // FD, but that doesn't always hold true here. This is because, in some + // cases, we'll emit a diag about an ill-formed function call, but then + // we'll continue on as if the function call wasn't ill-formed. So, if the + // number of args looks incorrect, don't do enable_if checks; we should've + // already emitted an error about the bad call. + if (FD->hasAttr<EnableIfAttr>() && + isNumberOfArgsValidForCall(*this, FD, ArgExprs.size())) { if (const EnableIfAttr *Attr = CheckEnableIf(FD, ArgExprs, true)) { Diag(Fn->getLocStart(), isa<CXXMethodDecl>(FD) ? @@ -5192,6 +5310,12 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, FunctionDecl *FDecl = dyn_cast_or_null<FunctionDecl>(NDecl); unsigned BuiltinID = (FDecl ? FDecl->getBuiltinID() : 0); + // Functions with 'interrupt' attribute cannot be called directly. + if (FDecl && FDecl->hasAttr<AnyX86InterruptAttr>()) { + Diag(Fn->getExprLoc(), diag::err_anyx86_interrupt_called); + return ExprError(); + } + // Promote the function operand. // We special-case function promotion here because we only allow promoting // builtin functions to function pointers in the callee of a call. @@ -5474,7 +5598,7 @@ void Sema::maybeExtendBlockObject(ExprResult &E) { E = ImplicitCastExpr::Create(Context, E.get()->getType(), CK_ARCExtendBlockObject, E.get(), /*base path*/ nullptr, VK_RValue); - ExprNeedsCleanups = true; + Cleanup.setExprNeedsCleanups(true); } /// Prepare a conversion of the given expression to an ObjC object @@ -6122,30 +6246,87 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS, lhptee = S.Context.getQualifiedType(lhptee.getUnqualifiedType(), lhQual); rhptee = S.Context.getQualifiedType(rhptee.getUnqualifiedType(), rhQual); + // For OpenCL: + // 1. If LHS and RHS types match exactly and: + // (a) AS match => use standard C rules, no bitcast or addrspacecast + // (b) AS overlap => generate addrspacecast + // (c) AS don't overlap => give an error + // 2. if LHS and RHS types don't match: + // (a) AS match => use standard C rules, generate bitcast + // (b) AS overlap => generate addrspacecast instead of bitcast + // (c) AS don't overlap => give an error + + // For OpenCL, non-null composite type is returned only for cases 1a and 1b. QualType CompositeTy = S.Context.mergeTypes(lhptee, rhptee); + // OpenCL cases 1c, 2a, 2b, and 2c. if (CompositeTy.isNull()) { - S.Diag(Loc, diag::ext_typecheck_cond_incompatible_pointers) - << LHSTy << RHSTy << LHS.get()->getSourceRange() - << RHS.get()->getSourceRange(); // In this situation, we assume void* type. No especially good // reason, but this is what gcc does, and we do have to pick // to get a consistent AST. - QualType incompatTy = S.Context.getPointerType(S.Context.VoidTy); - LHS = S.ImpCastExprToType(LHS.get(), incompatTy, CK_BitCast); - RHS = S.ImpCastExprToType(RHS.get(), incompatTy, CK_BitCast); + QualType incompatTy; + if (S.getLangOpts().OpenCL) { + // OpenCL v1.1 s6.5 - Conversion between pointers to distinct address + // spaces is disallowed. + unsigned ResultAddrSpace; + if (lhQual.isAddressSpaceSupersetOf(rhQual)) { + // Cases 2a and 2b. + ResultAddrSpace = lhQual.getAddressSpace(); + } else if (rhQual.isAddressSpaceSupersetOf(lhQual)) { + // Cases 2a and 2b. + ResultAddrSpace = rhQual.getAddressSpace(); + } else { + // Cases 1c and 2c. + S.Diag(Loc, + diag::err_typecheck_op_on_nonoverlapping_address_space_pointers) + << LHSTy << RHSTy << 2 << LHS.get()->getSourceRange() + << RHS.get()->getSourceRange(); + return QualType(); + } + + // Continue handling cases 2a and 2b. + incompatTy = S.Context.getPointerType( + S.Context.getAddrSpaceQualType(S.Context.VoidTy, ResultAddrSpace)); + LHS = S.ImpCastExprToType(LHS.get(), incompatTy, + (lhQual.getAddressSpace() != ResultAddrSpace) + ? CK_AddressSpaceConversion /* 2b */ + : CK_BitCast /* 2a */); + RHS = S.ImpCastExprToType(RHS.get(), incompatTy, + (rhQual.getAddressSpace() != ResultAddrSpace) + ? CK_AddressSpaceConversion /* 2b */ + : CK_BitCast /* 2a */); + } else { + S.Diag(Loc, diag::ext_typecheck_cond_incompatible_pointers) + << LHSTy << RHSTy << LHS.get()->getSourceRange() + << RHS.get()->getSourceRange(); + incompatTy = S.Context.getPointerType(S.Context.VoidTy); + LHS = S.ImpCastExprToType(LHS.get(), incompatTy, CK_BitCast); + RHS = S.ImpCastExprToType(RHS.get(), incompatTy, CK_BitCast); + } return incompatTy; } // The pointer types are compatible. QualType ResultTy = CompositeTy.withCVRQualifiers(MergedCVRQual); + auto LHSCastKind = CK_BitCast, RHSCastKind = CK_BitCast; if (IsBlockPointer) ResultTy = S.Context.getBlockPointerType(ResultTy); - else + else { + // Cases 1a and 1b for OpenCL. + auto ResultAddrSpace = ResultTy.getQualifiers().getAddressSpace(); + LHSCastKind = lhQual.getAddressSpace() == ResultAddrSpace + ? CK_BitCast /* 1a */ + : CK_AddressSpaceConversion /* 1b */; + RHSCastKind = rhQual.getAddressSpace() == ResultAddrSpace + ? CK_BitCast /* 1a */ + : CK_AddressSpaceConversion /* 1b */; ResultTy = S.Context.getPointerType(ResultTy); + } - LHS = S.ImpCastExprToType(LHS.get(), ResultTy, CK_BitCast); - RHS = S.ImpCastExprToType(RHS.get(), ResultTy, CK_BitCast); + // For case 1a of OpenCL, S.ImpCastExprToType will not insert bitcast + // if the target type does not change. + LHS = S.ImpCastExprToType(LHS.get(), ResultTy, LHSCastKind); + RHS = S.ImpCastExprToType(RHS.get(), ResultTy, RHSCastKind); return ResultTy; } @@ -6413,6 +6594,18 @@ OpenCLCheckVectorConditional(Sema &S, ExprResult &Cond, return OpenCLConvertScalarsToVectors(S, LHS, RHS, CondTy, QuestionLoc); } +/// \brief Return true if the Expr is block type +static bool checkBlockType(Sema &S, const Expr *E) { + if (const CallExpr *CE = dyn_cast<CallExpr>(E)) { + QualType Ty = CE->getCallee()->getType(); + if (Ty->isBlockPointerType()) { + S.Diag(E->getExprLoc(), diag::err_opencl_ternary_with_block); + return true; + } + } + return false; +} + /// Note that LHS is not null here, even if this is the gnu "x ?: y" extension. /// In that case, LHS = cond. /// C99 6.5.15 @@ -6462,6 +6655,22 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, QualType LHSTy = LHS.get()->getType(); QualType RHSTy = RHS.get()->getType(); + // Diagnose attempts to convert between __float128 and long double where + // such conversions currently can't be handled. + if (unsupportedTypeConversion(*this, LHSTy, RHSTy)) { + Diag(QuestionLoc, + diag::err_typecheck_cond_incompatible_operands) << LHSTy << RHSTy + << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); + return QualType(); + } + + // OpenCL v2.0 s6.12.5 - Blocks cannot be used as expressions of the ternary + // selection operator (?:). + if (getLangOpts().OpenCL && + (checkBlockType(*this, LHS.get()) | checkBlockType(*this, RHS.get()))) { + return QualType(); + } + // If both operands have arithmetic type, do the usual arithmetic conversions // to find a common type: C99 6.5.15p3,5. if (LHSTy->isArithmeticType() && RHSTy->isArithmeticType()) { @@ -6804,8 +7013,23 @@ ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc, // doesn't handle dependent types properly, so make sure any TypoExprs have // been dealt with before checking the operands. ExprResult CondResult = CorrectDelayedTyposInExpr(CondExpr); - if (!CondResult.isUsable()) return ExprError(); + ExprResult LHSResult = CorrectDelayedTyposInExpr(LHSExpr); + ExprResult RHSResult = CorrectDelayedTyposInExpr(RHSExpr); + + if (!CondResult.isUsable()) + return ExprError(); + + if (LHSExpr) { + if (!LHSResult.isUsable()) + return ExprError(); + } + + if (!RHSResult.isUsable()) + return ExprError(); + CondExpr = CondResult.get(); + LHSExpr = LHSResult.get(); + RHSExpr = RHSResult.get(); } // If this is the gnu "x ?: y" extension, analyze the types as though the LHS @@ -6918,7 +7142,7 @@ checkPointerTypesForAssignment(Sema &S, QualType LHSType, QualType RHSType) { else if (lhq.getObjCLifetime() != rhq.getObjCLifetime()) ConvTy = Sema::IncompatiblePointerDiscardsQualifiers; - // For GCC compatibility, other qualifier mismatches are treated + // For GCC/MS compatibility, other qualifier mismatches are treated // as still compatible in C. else ConvTy = Sema::CompatiblePointerDiscardsQualifiers; } @@ -7170,9 +7394,30 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, return IncompatibleVectors; } } + + // When the RHS comes from another lax conversion (e.g. binops between + // scalars and vectors) the result is canonicalized as a vector. When the + // LHS is also a vector, the lax is allowed by the condition above. Handle + // the case where LHS is a scalar. + if (LHSType->isScalarType()) { + const VectorType *VecType = RHSType->getAs<VectorType>(); + if (VecType && VecType->getNumElements() == 1 && + isLaxVectorConversion(RHSType, LHSType)) { + ExprResult *VecExpr = &RHS; + *VecExpr = ImpCastExprToType(VecExpr->get(), LHSType, CK_BitCast); + Kind = CK_BitCast; + return Compatible; + } + } + return Incompatible; } + // Diagnose attempts to convert between __float128 and long double where + // such conversions currently can't be handled. + if (unsupportedTypeConversion(*this, LHSType, RHSType)) + return Incompatible; + // Arithmetic conversions. if (LHSType->isArithmeticType() && RHSType->isArithmeticType() && !(getLangOpts().CPlusPlus && LHSType->isEnumeralType())) { @@ -7539,13 +7784,24 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS, if (result != Incompatible && RHS.get()->getType() != LHSType) { QualType Ty = LHSType.getNonLValueExprType(Context); Expr *E = RHS.get(); - if (getLangOpts().ObjCAutoRefCount) - CheckObjCARCConversion(SourceRange(), Ty, E, CCK_ImplicitConversion, - Diagnose, DiagnoseCFAudited); + + // Check for various Objective-C errors. If we are not reporting + // diagnostics and just checking for errors, e.g., during overload + // resolution, return Incompatible to indicate the failure. + if (getLangOpts().ObjCAutoRefCount && + CheckObjCARCConversion(SourceRange(), Ty, E, CCK_ImplicitConversion, + Diagnose, DiagnoseCFAudited) != ACR_okay) { + if (!Diagnose) + return Incompatible; + } if (getLangOpts().ObjC1 && (CheckObjCBridgeRelatedConversions(E->getLocStart(), LHSType, E->getType(), E, Diagnose) || ConversionToObjCStringLiteralCheck(LHSType, E, Diagnose))) { + if (!Diagnose) + return Incompatible; + // Replace the expression with a corrected version and continue so we + // can find further errors. RHS = E; return Compatible; } @@ -7693,14 +7949,16 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, return RHSType; } - // If we're allowing lax vector conversions, only the total (data) size - // needs to be the same. - // FIXME: Should we really be allowing this? - // FIXME: We really just pick the LHS type arbitrarily? - if (isLaxVectorConversion(RHSType, LHSType)) { - QualType resultType = LHSType; - RHS = ImpCastExprToType(RHS.get(), resultType, CK_BitCast); - return resultType; + // If we're allowing lax vector conversions, only the total (data) size needs + // to be the same. If one of the types is scalar, the result is always the + // vector type. Don't allow this if the scalar operand is an lvalue. + QualType VecType = LHSVecType ? LHSType : RHSType; + QualType ScalarType = LHSVecType ? RHSType : LHSType; + ExprResult *ScalarExpr = LHSVecType ? &RHS : &LHS; + if (isLaxVectorConversion(ScalarType, VecType) && + !ScalarExpr->get()->isLValue()) { + *ScalarExpr = ImpCastExprToType(ScalarExpr->get(), VecType, CK_BitCast); + return VecType; } // Okay, the expression is invalid. @@ -9244,7 +9502,7 @@ QualType Sema::CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS, } // Return a signed type for the vector. - return GetSignedVectorType(LHSType); + return GetSignedVectorType(vType); } QualType Sema::CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS, @@ -9411,7 +9669,16 @@ static NonConstCaptureKind isReferenceToNonConstCapture(Sema &S, Expr *E) { // Decide whether the first capture was for a block or a lambda. DeclContext *DC = S.CurContext, *Prev = nullptr; - while (DC != var->getDeclContext()) { + // Decide whether the first capture was for a block or a lambda. + while (DC) { + // For init-capture, it is possible that the variable belongs to the + // template pattern of the current context. + if (auto *FD = dyn_cast<FunctionDecl>(DC)) + if (var->isInitCapture() && + FD->getTemplateInstantiationPattern() == var->getDeclContext()) + break; + if (DC == var->getDeclContext()) + break; Prev = DC; DC = DC->getParent(); } @@ -9558,6 +9825,9 @@ static void DiagnoseConstAssignment(Sema &S, const Expr *E, /// emit an error and return true. If so, return false. static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) { assert(!E->hasPlaceholderType(BuiltinType::PseudoObject)); + + S.CheckShadowingDeclModification(E, Loc); + SourceLocation OrigLoc = Loc; Expr::isModifiableLvalueResult IsLV = E->isModifiableLvalue(S.Context, &Loc); @@ -9798,6 +10068,67 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS, ? LHSType : LHSType.getUnqualifiedType()); } +// Only ignore explicit casts to void. +static bool IgnoreCommaOperand(const Expr *E) { + E = E->IgnoreParens(); + + if (const CastExpr *CE = dyn_cast<CastExpr>(E)) { + if (CE->getCastKind() == CK_ToVoid) { + return true; + } + } + + return false; +} + +// Look for instances where it is likely the comma operator is confused with +// another operator. There is a whitelist of acceptable expressions for the +// left hand side of the comma operator, otherwise emit a warning. +void Sema::DiagnoseCommaOperator(const Expr *LHS, SourceLocation Loc) { + // No warnings in macros + if (Loc.isMacroID()) + return; + + // Don't warn in template instantiations. + if (!ActiveTemplateInstantiations.empty()) + return; + + // Scope isn't fine-grained enough to whitelist the specific cases, so + // instead, skip more than needed, then call back into here with the + // CommaVisitor in SemaStmt.cpp. + // The whitelisted locations are the initialization and increment portions + // of a for loop. The additional checks are on the condition of + // if statements, do/while loops, and for loops. + const unsigned ForIncrementFlags = + Scope::ControlScope | Scope::ContinueScope | Scope::BreakScope; + const unsigned ForInitFlags = Scope::ControlScope | Scope::DeclScope; + const unsigned ScopeFlags = getCurScope()->getFlags(); + if ((ScopeFlags & ForIncrementFlags) == ForIncrementFlags || + (ScopeFlags & ForInitFlags) == ForInitFlags) + return; + + // If there are multiple comma operators used together, get the RHS of the + // of the comma operator as the LHS. + while (const BinaryOperator *BO = dyn_cast<BinaryOperator>(LHS)) { + if (BO->getOpcode() != BO_Comma) + break; + LHS = BO->getRHS(); + } + + // Only allow some expressions on LHS to not warn. + if (IgnoreCommaOperand(LHS)) + return; + + Diag(Loc, diag::warn_comma_operator); + Diag(LHS->getLocStart(), diag::note_cast_to_void) + << LHS->getSourceRange() + << FixItHint::CreateInsertion(LHS->getLocStart(), + LangOpts.CPlusPlus ? "static_cast<void>(" + : "(void)(") + << FixItHint::CreateInsertion(PP.getLocForEndOfToken(LHS->getLocEnd()), + ")"); +} + // C99 6.5.17 static QualType CheckCommaOperands(Sema &S, ExprResult &LHS, ExprResult &RHS, SourceLocation Loc) { @@ -9827,6 +10158,9 @@ static QualType CheckCommaOperands(Sema &S, ExprResult &LHS, ExprResult &RHS, diag::err_incomplete_type); } + if (!S.getDiagnostics().isIgnored(diag::warn_comma_operator, Loc)) + S.DiagnoseCommaOperator(LHS.get(), Loc); + return RHS.get()->getType(); } @@ -10075,8 +10409,8 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) { if (sfinae) return QualType(); // Materialize the temporary as an lvalue so that we can take its address. - OrigOp = op = new (Context) - MaterializeTemporaryExpr(op->getType(), OrigOp.get(), true); + OrigOp = op = + CreateMaterializeTemporaryExpr(op->getType(), OrigOp.get(), true); } else if (isa<ObjCSelectorExpr>(op)) { return Context.getPointerType(op->getType()); } else if (lval == Expr::LV_MemberFunction) { @@ -10199,6 +10533,7 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) { // If the operand has type "type", the result has type "pointer to type". if (op->getType()->isObjCObjectType()) return Context.getObjCObjectPointerType(op->getType()); + return Context.getPointerType(op->getType()); } @@ -10240,7 +10575,9 @@ static QualType CheckIndirectionOperand(Sema &S, Expr *Op, ExprValueKind &VK, } if (const PointerType *PT = OpTy->getAs<PointerType>()) + { Result = PT->getPointeeType(); + } else if (const ObjCObjectPointerType *OPT = OpTy->getAs<ObjCObjectPointerType>()) Result = OPT->getPointeeType(); @@ -10478,10 +10815,11 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, } if (getLangOpts().OpenCL) { + QualType LHSTy = LHSExpr->getType(); + QualType RHSTy = RHSExpr->getType(); // OpenCLC v2.0 s6.13.11.1 allows atomic variables to be initialized by // the ATOMIC_VAR_INIT macro. - if (LHSExpr->getType()->isAtomicType() || - RHSExpr->getType()->isAtomicType()) { + if (LHSTy->isAtomicType() || RHSTy->isAtomicType()) { SourceRange SR(LHSExpr->getLocStart(), RHSExpr->getLocEnd()); if (BO_Assign == Opc) Diag(OpLoc, diag::err_atomic_init_constant) << SR; @@ -10489,6 +10827,16 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, ResultTy = InvalidOperands(OpLoc, LHS, RHS); return ExprError(); } + + // OpenCL special types - image, sampler, pipe, and blocks are to be used + // only with a builtin functions and therefore should be disallowed here. + if (LHSTy->isImageType() || RHSTy->isImageType() || + LHSTy->isSamplerT() || RHSTy->isSamplerT() || + LHSTy->isPipeType() || RHSTy->isPipeType() || + LHSTy->isBlockPointerType() || RHSTy->isBlockPointerType()) { + ResultTy = InvalidOperands(OpLoc, LHS, RHS); + return ExprError(); + } } switch (Opc) { @@ -10959,8 +11307,13 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, ExprObjectKind OK = OK_Ordinary; QualType resultType; if (getLangOpts().OpenCL) { + QualType Ty = InputExpr->getType(); // The only legal unary operation for atomics is '&'. - if (Opc != UO_AddrOf && InputExpr->getType()->isAtomicType()) { + if ((Opc != UO_AddrOf && Ty->isAtomicType()) || + // OpenCL special types - image, sampler, pipe, and blocks are to be used + // only with a builtin functions and therefore should be disallowed here. + (Ty->isImageType() || Ty->isSamplerT() || Ty->isPipeType() + || Ty->isBlockPointerType())) { return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) << InputExpr->getType() << Input.get()->getSourceRange()); @@ -11273,7 +11626,8 @@ Sema::ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, if (hasAnyUnrecoverableErrorsInThisFunction()) DiscardCleanupsInEvaluationContext(); - assert(!ExprNeedsCleanups && "cleanups within StmtExpr not correctly bound!"); + assert(!Cleanup.exprNeedsCleanups() && + "cleanups within StmtExpr not correctly bound!"); PopExpressionEvaluationContext(); // FIXME: there are a variety of strange constraints to enforce here, for @@ -11697,8 +12051,7 @@ void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo, // Set the parameters on the block decl. if (!Params.empty()) { CurBlock->TheDecl->setParams(Params); - CheckParmsForFunctionDef(CurBlock->TheDecl->param_begin(), - CurBlock->TheDecl->param_end(), + CheckParmsForFunctionDef(CurBlock->TheDecl->parameters(), /*CheckParameterNames=*/false); } @@ -11706,7 +12059,7 @@ void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo, ProcessDeclAttributes(CurScope, CurBlock->TheDecl, ParamInfo); // Put the parameter variables in scope. - for (auto AI : CurBlock->TheDecl->params()) { + for (auto AI : CurBlock->TheDecl->parameters()) { AI->setOwningFunction(CurBlock->TheDecl); // If this has an identifier, add it to the scope stack. @@ -11736,12 +12089,13 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, Stmt *Body, Scope *CurScope) { // If blocks are disabled, emit an error. if (!LangOpts.Blocks) - Diag(CaretLoc, diag::err_blocks_disable); + Diag(CaretLoc, diag::err_blocks_disable) << LangOpts.OpenCL; // Leave the expression-evaluation context. if (hasAnyUnrecoverableErrorsInThisFunction()) DiscardCleanupsInEvaluationContext(); - assert(!ExprNeedsCleanups && "cleanups within block not correctly bound!"); + assert(!Cleanup.exprNeedsCleanups() && + "cleanups within block not correctly bound!"); PopExpressionEvaluationContext(); BlockScopeInfo *BSI = cast<BlockScopeInfo>(FunctionScopes.back()); @@ -11805,8 +12159,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, BlockTy = Context.getFunctionType(RetTy, None, EPI); } - DiagnoseUnusedParameters(BSI->TheDecl->param_begin(), - BSI->TheDecl->param_end()); + DiagnoseUnusedParameters(BSI->TheDecl->parameters()); BlockTy = Context.getBlockPointerType(BlockTy); // If needed, diagnose invalid gotos and switches in the block. @@ -11832,7 +12185,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, if (Result->getBlockDecl()->hasCaptures()) { // First, this expression has a new cleanup object. ExprCleanupObjects.push_back(Result->getBlockDecl()); - ExprNeedsCleanups = true; + Cleanup.setExprNeedsCleanups(true); // It also gets a branch-protected scope if any of the captured // variables needs destruction. @@ -11848,9 +12201,8 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, return Result; } -ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc, - Expr *E, ParsedType Ty, - SourceLocation RPLoc) { +ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc, Expr *E, ParsedType Ty, + SourceLocation RPLoc) { TypeSourceInfo *TInfo; GetTypeFromParser(Ty, &TInfo); return BuildVAArgExpr(BuiltinLoc, E, TInfo, RPLoc); @@ -11862,6 +12214,15 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc, Expr *OrigExpr = E; bool IsMS = false; + // CUDA device code does not support varargs. + if (getLangOpts().CUDA && getLangOpts().CUDAIsDevice) { + if (const FunctionDecl *F = dyn_cast<FunctionDecl>(CurContext)) { + CUDAFunctionTarget T = IdentifyCUDATarget(F); + if (T == CFT_Global || T == CFT_Device || T == CFT_HostDevice) + return ExprError(Diag(E->getLocStart(), diag::err_va_arg_in_device)); + } + } + // It might be a __builtin_ms_va_list. (But don't ever mark a va_arg() // as Microsoft ABI on an actual Microsoft platform, where // __builtin_ms_va_list and __builtin_va_list are the same.) @@ -12000,10 +12361,11 @@ bool Sema::ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&Exp, StringLiteral *SL = dyn_cast<StringLiteral>(SrcExpr); if (!SL || !SL->isAscii()) return false; - if (Diagnose) + if (Diagnose) { Diag(SL->getLocStart(), diag::err_missing_atsign_prefix) << FixItHint::CreateInsertion(SL->getLocStart(), "@"); - Exp = BuildObjCStringLiteral(SL->getLocStart(), SL).get(); + Exp = BuildObjCStringLiteral(SL->getLocStart(), SL).get(); + } return true; } @@ -12460,10 +12822,9 @@ void Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl, bool IsDecltype) { - ExprEvalContexts.emplace_back(NewContext, ExprCleanupObjects.size(), - ExprNeedsCleanups, LambdaContextDecl, - IsDecltype); - ExprNeedsCleanups = false; + ExprEvalContexts.emplace_back(NewContext, ExprCleanupObjects.size(), Cleanup, + LambdaContextDecl, IsDecltype); + Cleanup.reset(); if (!MaybeODRUseExprs.empty()) std::swap(MaybeODRUseExprs, ExprEvalContexts.back().SavedMaybeODRUseExprs); } @@ -12514,12 +12875,12 @@ void Sema::PopExpressionEvaluationContext() { if (Rec.isUnevaluated() || Rec.Context == ConstantEvaluated) { ExprCleanupObjects.erase(ExprCleanupObjects.begin() + Rec.NumCleanupObjects, ExprCleanupObjects.end()); - ExprNeedsCleanups = Rec.ParentNeedsCleanups; + Cleanup = Rec.ParentCleanup; CleanupVarDeclMarking(); std::swap(MaybeODRUseExprs, Rec.SavedMaybeODRUseExprs); // Otherwise, merge the contexts together. } else { - ExprNeedsCleanups |= Rec.ParentNeedsCleanups; + Cleanup.mergeFrom(Rec.ParentCleanup); MaybeODRUseExprs.insert(Rec.SavedMaybeODRUseExprs.begin(), Rec.SavedMaybeODRUseExprs.end()); } @@ -12538,7 +12899,7 @@ void Sema::DiscardCleanupsInEvaluationContext() { ExprCleanupObjects.erase( ExprCleanupObjects.begin() + ExprEvalContexts.back().NumCleanupObjects, ExprCleanupObjects.end()); - ExprNeedsCleanups = false; + Cleanup.reset(); MaybeODRUseExprs.clear(); } @@ -12563,6 +12924,11 @@ static bool IsPotentiallyEvaluatedContext(Sema &SemaRef) { // definition of a null pointer constant is completely crazy.) return false; + case Sema::DiscardedStatement: + // These are technically a potentially evaluated but they have the effect + // of suppressing use marking. + return false; + case Sema::ConstantEvaluated: case Sema::PotentiallyEvaluated: // We are in a potentially evaluated expression (or a constant-expression @@ -12581,7 +12947,7 @@ static bool IsPotentiallyEvaluatedContext(Sema &SemaRef) { /// \brief Mark a function referenced, and check whether it is odr-used /// (C++ [basic.def.odr]p2, C99 6.9p3) void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, - bool OdrUse) { + bool MightBeOdrUse) { assert(Func && "No function?"); Func->setReferenced(); @@ -12592,39 +12958,53 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, // set of overloaded functions [...]. // // We (incorrectly) mark overload resolution as an unevaluated context, so we - // can just check that here. Skip the rest of this function if we've already - // marked the function as used. - if (Func->isUsed(/*CheckUsedAttr=*/false) || - !IsPotentiallyEvaluatedContext(*this)) { - // C++11 [temp.inst]p3: - // Unless a function template specialization has been explicitly - // instantiated or explicitly specialized, the function template - // specialization is implicitly instantiated when the specialization is - // referenced in a context that requires a function definition to exist. - // - // We consider constexpr function templates to be referenced in a context - // that requires a definition to exist whenever they are referenced. - // - // FIXME: This instantiates constexpr functions too frequently. If this is - // really an unevaluated context (and we're not just in the definition of a - // function template or overload resolution or other cases which we - // incorrectly consider to be unevaluated contexts), and we're not in a - // subexpression which we actually need to evaluate (for instance, a - // template argument, array bound or an expression in a braced-init-list), - // we are not permitted to instantiate this constexpr function definition. - // - // FIXME: This also implicitly defines special members too frequently. They - // are only supposed to be implicitly defined if they are odr-used, but they - // are not odr-used from constant expressions in unevaluated contexts. - // However, they cannot be referenced if they are deleted, and they are - // deleted whenever the implicit definition of the special member would - // fail. - if (!Func->isConstexpr() || Func->getBody()) - return; - CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Func); - if (!Func->isImplicitlyInstantiable() && (!MD || MD->isUserProvided())) - return; - } + // can just check that here. + bool OdrUse = MightBeOdrUse && IsPotentiallyEvaluatedContext(*this); + + // Determine whether we require a function definition to exist, per + // C++11 [temp.inst]p3: + // Unless a function template specialization has been explicitly + // instantiated or explicitly specialized, the function template + // specialization is implicitly instantiated when the specialization is + // referenced in a context that requires a function definition to exist. + // + // We consider constexpr function templates to be referenced in a context + // that requires a definition to exist whenever they are referenced. + // + // FIXME: This instantiates constexpr functions too frequently. If this is + // really an unevaluated context (and we're not just in the definition of a + // function template or overload resolution or other cases which we + // incorrectly consider to be unevaluated contexts), and we're not in a + // subexpression which we actually need to evaluate (for instance, a + // template argument, array bound or an expression in a braced-init-list), + // we are not permitted to instantiate this constexpr function definition. + // + // FIXME: This also implicitly defines special members too frequently. They + // are only supposed to be implicitly defined if they are odr-used, but they + // are not odr-used from constant expressions in unevaluated contexts. + // However, they cannot be referenced if they are deleted, and they are + // deleted whenever the implicit definition of the special member would + // fail (with very few exceptions). + CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Func); + bool NeedDefinition = + OdrUse || (Func->isConstexpr() && (Func->isImplicitlyInstantiable() || + (MD && !MD->isUserProvided()))); + + // C++14 [temp.expl.spec]p6: + // If a template [...] is explicitly specialized then that specialization + // shall be declared before the first use of that specialization that would + // cause an implicit instantiation to take place, in every translation unit + // in which such a use occurs + if (NeedDefinition && + (Func->getTemplateSpecializationKind() != TSK_Undeclared || + Func->getMemberSpecializationInfo())) + checkSpecializationVisibility(Loc, Func); + + // If we don't need to mark the function as used, and we don't need to + // try to provide a definition, there's nothing more to do. + if ((Func->isUsed(/*CheckUsedAttr=*/false) || !OdrUse) && + (!NeedDefinition || Func->getBody())) + return; // Note that this declaration has been used. if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Func)) { @@ -12659,7 +13039,7 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, if (MethodDecl->isDefaulted() && !MethodDecl->isDeleted()) { if (MethodDecl->isCopyAssignmentOperator()) DefineImplicitCopyAssignment(Loc, MethodDecl); - else + else if (MethodDecl->isMoveAssignmentOperator()) DefineImplicitMoveAssignment(Loc, MethodDecl); } } else if (isa<CXXConversionDecl>(MethodDecl) && @@ -12684,8 +13064,6 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, if (FPT && isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) ResolveExceptionSpec(Loc, FPT); - if (!OdrUse) return; - // Implicit instantiation of function templates and member functions of // class templates. if (Func->isImplicitlyInstantiable()) { @@ -12733,10 +13111,12 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, // Walk redefinitions, as some of them may be instantiable. for (auto i : Func->redecls()) { if (!i->isUsed(false) && i->isImplicitlyInstantiable()) - MarkFunctionReferenced(Loc, i); + MarkFunctionReferenced(Loc, i, OdrUse); } } + if (!OdrUse) return; + // Keep track of used but undefined functions. if (!Func->isDefined()) { if (mightHaveNonExternalLinkage(Func)) @@ -12747,17 +13127,7 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, UndefinedButUsed.insert(std::make_pair(Func->getCanonicalDecl(), Loc)); } - // Normally the most current decl is marked used while processing the use and - // any subsequent decls are marked used by decl merging. This fails with - // template instantiation since marking can happen at the end of the file - // and, because of the two phase lookup, this function is called with at - // decl in the middle of a decl chain. We loop to maintain the invariant - // that once a decl is used, all decls after it are also used. - for (FunctionDecl *F = Func->getMostRecentDecl();; F = F->getPreviousDecl()) { - F->markUsed(Context); - if (F == Func) - break; - } + Func->markUsed(Context); } static void @@ -12945,7 +13315,8 @@ static bool captureInBlock(BlockScopeInfo *BSI, VarDecl *Var, return false; } const bool HasBlocksAttr = Var->hasAttr<BlocksAttr>(); - if (HasBlocksAttr || CaptureType->isReferenceType()) { + if (HasBlocksAttr || CaptureType->isReferenceType() || + (S.getLangOpts().OpenMP && S.IsOpenMPCapturedDecl(Var))) { // Block capture by reference does not change the capture or // declaration reference types. ByRef = true; @@ -13013,14 +13384,13 @@ static bool captureInCapturedRegion(CapturedRegionScopeInfo *RSI, QualType &DeclRefType, const bool RefersToCapturedVariable, Sema &S) { - // By default, capture variables by reference. bool ByRef = true; // Using an LValue reference type is consistent with Lambdas (see below). - if (S.getLangOpts().OpenMP) { - ByRef = S.IsOpenMPCapturedByRef(Var, RSI); - if (S.IsOpenMPCapturedVar(Var)) + if (S.getLangOpts().OpenMP && RSI->CapRegionKind == CR_OpenMP) { + if (S.IsOpenMPCapturedDecl(Var)) DeclRefType = DeclRefType.getUnqualifiedType(); + ByRef = S.IsOpenMPCapturedByRef(Var, RSI->OpenMPLevel); } if (ByRef) @@ -13060,7 +13430,7 @@ static bool captureInCapturedRegion(CapturedRegionScopeInfo *RSI, /// \brief Create a field within the lambda class for the variable /// being captured. -static void addAsFieldToClosureType(Sema &S, LambdaScopeInfo *LSI, VarDecl *Var, +static void addAsFieldToClosureType(Sema &S, LambdaScopeInfo *LSI, QualType FieldType, QualType DeclRefType, SourceLocation Loc, bool RefersToCapturedVariable) { @@ -13154,7 +13524,7 @@ static bool captureInLambda(LambdaScopeInfo *LSI, // Capture this variable in the lambda. if (BuildAndDiagnose) - addAsFieldToClosureType(S, LSI, Var, CaptureType, DeclRefType, Loc, + addAsFieldToClosureType(S, LSI, CaptureType, DeclRefType, Loc, RefersToCapturedVariable); // Compute the type of a reference to this captured variable. @@ -13210,7 +13580,7 @@ bool Sema::tryCaptureVariable( // Capture global variables if it is required to use private copy of this // variable. bool IsGlobal = !Var->hasLocalStorage(); - if (IsGlobal && !(LangOpts.OpenMP && IsOpenMPCapturedVar(Var))) + if (IsGlobal && !(LangOpts.OpenMP && IsOpenMPCapturedDecl(Var))) return true; // Walk up the stack to determine whether we can capture the variable, @@ -13226,7 +13596,6 @@ bool Sema::tryCaptureVariable( bool Nested = false; bool Explicit = (Kind != TryCapture_Implicit); unsigned FunctionScopesIndex = MaxFunctionScopesIndex; - unsigned OpenMPLevel = 0; do { // Only block literals, captured statements, and lambda expressions can // capture; other scopes don't work. @@ -13292,20 +13661,19 @@ bool Sema::tryCaptureVariable( // just break here. Similarly, global variables that are captured in a // target region should not be captured outside the scope of the region. if (RSI->CapRegionKind == CR_OpenMP) { - auto isTargetCap = isOpenMPTargetCapturedVar(Var, OpenMPLevel); + auto IsTargetCap = isOpenMPTargetCapturedDecl(Var, RSI->OpenMPLevel); // When we detect target captures we are looking from inside the // target region, therefore we need to propagate the capture from the // enclosing region. Therefore, the capture is not initially nested. - if (isTargetCap) + if (IsTargetCap) FunctionScopesIndex--; - if (isTargetCap || isOpenMPPrivateVar(Var, OpenMPLevel)) { - Nested = !isTargetCap; + if (IsTargetCap || isOpenMPPrivateDecl(Var, RSI->OpenMPLevel)) { + Nested = !IsTargetCap; DeclRefType = DeclRefType.getUnqualifiedType(); CaptureType = Context.getLValueReferenceType(DeclRefType); break; } - ++OpenMPLevel; } } } @@ -13316,8 +13684,9 @@ bool Sema::tryCaptureVariable( Diag(ExprLoc, diag::err_lambda_impcap) << Var->getDeclName(); Diag(Var->getLocation(), diag::note_previous_decl) << Var->getDeclName(); - Diag(cast<LambdaScopeInfo>(CSI)->Lambda->getLocStart(), - diag::note_lambda_decl); + if (cast<LambdaScopeInfo>(CSI)->Lambda) + Diag(cast<LambdaScopeInfo>(CSI)->Lambda->getLocStart(), + diag::note_lambda_decl); // FIXME: If we error out because an outer lambda can not implicitly // capture a variable that an inner lambda explicitly captures, we // should have the inner lambda do the explicit capture - because @@ -13539,6 +13908,12 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc, assert(!isa<VarTemplatePartialSpecializationDecl>(Var) && "Can't instantiate a partial template specialization."); + // If this might be a member specialization of a static data member, check + // the specialization is visible. We already did the checks for variable + // template specializations when we created them. + if (TSK != TSK_Undeclared && !isa<VarTemplateSpecializationDecl>(Var)) + SemaRef.checkSpecializationVisibility(Loc, Var); + // Perform implicit instantiation of static data members, static data member // templates of class templates, and variable template specializations. Delay // instantiations of variable templates, except for those that could be used @@ -13582,7 +13957,8 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc, } } - if(!MarkODRUsed) return; + if (!MarkODRUsed) + return; // Per C++11 [basic.def.odr], a variable is odr-used "unless it satisfies // the requirements for appearing in a constant expression (5.19) and, if @@ -13610,13 +13986,16 @@ void Sema::MarkVariableReferenced(SourceLocation Loc, VarDecl *Var) { } static void MarkExprReferenced(Sema &SemaRef, SourceLocation Loc, - Decl *D, Expr *E, bool OdrUse) { + Decl *D, Expr *E, bool MightBeOdrUse) { + if (SemaRef.isInOpenMPDeclareTargetContext()) + SemaRef.checkDeclIsAllowedInOpenMPTarget(E, D); + if (VarDecl *Var = dyn_cast<VarDecl>(D)) { DoMarkVarDeclReferenced(SemaRef, Loc, Var, E); return; } - SemaRef.MarkAnyDeclReferenced(Loc, D, OdrUse); + SemaRef.MarkAnyDeclReferenced(Loc, D, MightBeOdrUse); // If this is a call to a method via a cast, also mark the method in the // derived class used in case codegen can devirtualize the call. @@ -13638,7 +14017,7 @@ static void MarkExprReferenced(Sema &SemaRef, SourceLocation Loc, CXXMethodDecl *DM = MD->getCorrespondingMethodInClass(MostDerivedClassDecl); if (!DM || DM->isPure()) return; - SemaRef.MarkAnyDeclReferenced(Loc, DM, OdrUse); + SemaRef.MarkAnyDeclReferenced(Loc, DM, MightBeOdrUse); } /// \brief Perform reference-marking and odr-use handling for a DeclRefExpr. @@ -13661,30 +14040,31 @@ void Sema::MarkMemberReferenced(MemberExpr *E) { // overload resolution when referred to from a potentially-evaluated // expression, is odr-used, unless it is a pure virtual function and its // name is not explicitly qualified. - bool OdrUse = true; + bool MightBeOdrUse = true; if (E->performsVirtualDispatch(getLangOpts())) { if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(E->getMemberDecl())) if (Method->isPure()) - OdrUse = false; + MightBeOdrUse = false; } SourceLocation Loc = E->getMemberLoc().isValid() ? E->getMemberLoc() : E->getLocStart(); - MarkExprReferenced(*this, Loc, E->getMemberDecl(), E, OdrUse); + MarkExprReferenced(*this, Loc, E->getMemberDecl(), E, MightBeOdrUse); } /// \brief Perform marking for a reference to an arbitrary declaration. It /// marks the declaration referenced, and performs odr-use checking for /// functions and variables. This method should not be used when building a /// normal expression which refers to a variable. -void Sema::MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse) { - if (OdrUse) { +void Sema::MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, + bool MightBeOdrUse) { + if (MightBeOdrUse) { if (auto *VD = dyn_cast<VarDecl>(D)) { MarkVariableReferenced(Loc, VD); return; } } if (auto *FD = dyn_cast<FunctionDecl>(D)) { - MarkFunctionReferenced(Loc, FD, OdrUse); + MarkFunctionReferenced(Loc, FD, MightBeOdrUse); return; } D->setReferenced(); @@ -13838,6 +14218,7 @@ bool Sema::DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, switch (ExprEvalContexts.back().Context) { case Unevaluated: case UnevaluatedAbstract: + case DiscardedStatement: // The argument will never be evaluated, so don't complain. break; @@ -13987,7 +14368,8 @@ void Sema::DiagnoseEqualityWithExtraParens(ParenExpr *ParenE) { } } -ExprResult Sema::CheckBooleanCondition(Expr *E, SourceLocation Loc) { +ExprResult Sema::CheckBooleanCondition(SourceLocation Loc, Expr *E, + bool IsConstexpr) { DiagnoseAssignmentAsCondition(E); if (ParenExpr *parenE = dyn_cast<ParenExpr>(E)) DiagnoseEqualityWithExtraParens(parenE); @@ -13998,7 +14380,7 @@ ExprResult Sema::CheckBooleanCondition(Expr *E, SourceLocation Loc) { if (!E->isTypeDependent()) { if (getLangOpts().CPlusPlus) - return CheckCXXBooleanCondition(E); // C++ 6.4p4 + return CheckCXXBooleanCondition(E, IsConstexpr); // C++ 6.4p4 ExprResult ERes = DefaultFunctionArrayLvalueConversion(E); if (ERes.isInvalid()) @@ -14017,12 +14399,36 @@ ExprResult Sema::CheckBooleanCondition(Expr *E, SourceLocation Loc) { return E; } -ExprResult Sema::ActOnBooleanCondition(Scope *S, SourceLocation Loc, - Expr *SubExpr) { +Sema::ConditionResult Sema::ActOnCondition(Scope *S, SourceLocation Loc, + Expr *SubExpr, ConditionKind CK) { + // Empty conditions are valid in for-statements. if (!SubExpr) - return ExprError(); + return ConditionResult(); - return CheckBooleanCondition(SubExpr, Loc); + ExprResult Cond; + switch (CK) { + case ConditionKind::Boolean: + Cond = CheckBooleanCondition(Loc, SubExpr); + break; + + case ConditionKind::ConstexprIf: + Cond = CheckBooleanCondition(Loc, SubExpr, true); + break; + + case ConditionKind::Switch: + Cond = CheckSwitchCondition(Loc, SubExpr); + break; + } + if (Cond.isInvalid()) + return ConditionError(); + + // FIXME: FullExprArg doesn't have an invalid bit, so check nullness instead. + FullExprArg FullExpr = MakeFullExpr(Cond.get(), Loc); + if (!FullExpr.get()) + return ConditionError(); + + return ConditionResult(*this, nullptr, FullExpr, + CK == ConditionKind::ConstexprIf); } namespace { @@ -14457,6 +14863,12 @@ ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *E, ValueDecl *VD) { ExprResult Sema::checkUnknownAnyCast(SourceRange TypeRange, QualType CastType, Expr *CastExpr, CastKind &CastKind, ExprValueKind &VK, CXXCastPath &Path) { + // The type we're casting to must be either void or complete. + if (!CastType->isVoidType() && + RequireCompleteType(TypeRange.getBegin(), CastType, + diag::err_typecheck_cast_to_incomplete)) + return ExprError(); + // Rewrite the casted expression from scratch. ExprResult result = RebuildUnknownAnyExpr(*this, CastType).Visit(CastExpr); if (!result.isUsable()) return ExprError(); @@ -14559,16 +14971,20 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) { case BuiltinType::Overload: { // Try to resolve a single function template specialization. // This is obligatory. - ExprResult result = E; - if (ResolveAndFixSingleFunctionTemplateSpecialization(result, false)) { - return result; + ExprResult Result = E; + if (ResolveAndFixSingleFunctionTemplateSpecialization(Result, false)) + return Result; + + // No guarantees that ResolveAndFixSingleFunctionTemplateSpecialization + // leaves Result unchanged on failure. + Result = E; + if (resolveAndFixAddressOfOnlyViableOverloadCandidate(Result)) + return Result; // If that failed, try to recover with a call. - } else { - tryToRecoverWithCall(result, PDiag(diag::err_ovl_unresolvable), - /*complain*/ true); - return result; - } + tryToRecoverWithCall(Result, PDiag(diag::err_ovl_unresolvable), + /*complain*/ true); + return Result; } // Bound member functions. @@ -14627,8 +15043,10 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) { return ExprError(); // Everything else should be impossible. -#define BUILTIN_TYPE(Id, SingletonId) \ +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ case BuiltinType::Id: +#include "clang/Basic/OpenCLImageTypes.def" +#define BUILTIN_TYPE(Id, SingletonId) case BuiltinType::Id: #define PLACEHOLDER_TYPE(Id, SingletonId) #include "clang/AST/BuiltinTypes.def" break; @@ -14665,3 +15083,27 @@ Sema::ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) { return new (Context) ObjCBoolLiteralExpr(Kind == tok::kw___objc_yes, BoolT, OpLoc); } + +ExprResult Sema::ActOnObjCAvailabilityCheckExpr( + llvm::ArrayRef<AvailabilitySpec> AvailSpecs, SourceLocation AtLoc, + SourceLocation RParen) { + + StringRef Platform = getASTContext().getTargetInfo().getPlatformName(); + + auto Spec = std::find_if(AvailSpecs.begin(), AvailSpecs.end(), + [&](const AvailabilitySpec &Spec) { + return Spec.getPlatform() == Platform; + }); + + VersionTuple Version; + if (Spec != AvailSpecs.end()) + Version = Spec->getVersion(); + else + // This is the '*' case in @available. We should diagnose this; the + // programmer should explicitly account for this case if they target this + // platform. + Diag(AtLoc, diag::warn_available_using_star_case) << RParen << Platform; + + return new (Context) + ObjCAvailabilityCheckExpr(Version, AtLoc, RParen, Context.BoolTy); +} |