diff options
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 798 |
1 files changed, 533 insertions, 265 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 35dad82..fba7a2d 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -42,6 +42,7 @@ #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaFixItUtils.h" #include "clang/Sema/Template.h" +#include "llvm/Support/ConvertUTF.h" using namespace clang; using namespace sema; @@ -59,7 +60,7 @@ bool Sema::CanUseDecl(NamedDecl *D) { // If the function has a deduced return type, and we can't deduce it, // then we can't use it either. - if (getLangOpts().CPlusPlus1y && FD->getReturnType()->isUndeducedType() && + if (getLangOpts().CPlusPlus14 && FD->getReturnType()->isUndeducedType() && DeduceReturnType(FD, SourceLocation(), /*Diagnose*/ false)) return false; } @@ -302,7 +303,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, // If the function has a deduced return type, and we can't deduce it, // then we can't use it either. - if (getLangOpts().CPlusPlus1y && FD->getReturnType()->isUndeducedType() && + if (getLangOpts().CPlusPlus14 && FD->getReturnType()->isUndeducedType() && DeduceReturnType(FD, Loc)) return true; } @@ -397,8 +398,8 @@ void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc, if (sentinelExpr->isValueDependent()) return; if (Context.isSentinelNullExpr(sentinelExpr)) return; - // Pick a reasonable string to insert. Optimistically use 'nil' or - // 'NULL' if those are actually defined in the context. Only use + // Pick a reasonable string to insert. Optimistically use 'nil', 'nullptr', + // or 'NULL' if those are actually defined in the context. Only use // 'nil' for ObjC methods, where it's much more likely that the // variadic arguments form a list of object pointers. SourceLocation MissingNilLoc @@ -407,6 +408,8 @@ void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc, if (calleeType == CT_Method && PP.getIdentifierInfo("nil")->hasMacroDefinition()) NullValue = "nil"; + else if (getLangOpts().CPlusPlus11) + NullValue = "nullptr"; else if (PP.getIdentifierInfo("NULL")->hasMacroDefinition()) NullValue = "NULL"; else @@ -800,6 +803,9 @@ Sema::VarArgKind Sema::isValidVarArgType(const QualType &Ty) { if (Ty->isObjCObjectType()) return VAK_Invalid; + if (getLangOpts().MSVCCompat) + return VAK_MSVCUndefined; + // FIXME: In C++11, these cases are conditionally-supported, meaning we're // permitted to reject them. We should consider doing so. return VAK_Undefined; @@ -829,6 +835,7 @@ void Sema::checkVariadicArgument(const Expr *E, VariadicCallType CT) { break; case VAK_Undefined: + case VAK_MSVCUndefined: DiagRuntimeBehavior( E->getLocStart(), nullptr, PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg) @@ -933,68 +940,6 @@ static bool handleIntegerToComplexFloatConversion(Sema &S, ExprResult &IntExpr, return false; } -/// \brief Takes two complex float types and converts them to the same type. -/// Helper function of UsualArithmeticConversions() -static QualType -handleComplexFloatToComplexFloatConverstion(Sema &S, ExprResult &LHS, - ExprResult &RHS, QualType LHSType, - QualType RHSType, - bool IsCompAssign) { - int order = S.Context.getFloatingTypeOrder(LHSType, RHSType); - - if (order < 0) { - // _Complex float -> _Complex double - if (!IsCompAssign) - LHS = S.ImpCastExprToType(LHS.get(), RHSType, CK_FloatingComplexCast); - return RHSType; - } - if (order > 0) - // _Complex float -> _Complex double - RHS = S.ImpCastExprToType(RHS.get(), LHSType, CK_FloatingComplexCast); - return LHSType; -} - -/// \brief Converts otherExpr to complex float and promotes complexExpr if -/// necessary. Helper function of UsualArithmeticConversions() -static QualType handleOtherComplexFloatConversion(Sema &S, - ExprResult &ComplexExpr, - ExprResult &OtherExpr, - QualType ComplexTy, - QualType OtherTy, - bool ConvertComplexExpr, - bool ConvertOtherExpr) { - int order = S.Context.getFloatingTypeOrder(ComplexTy, OtherTy); - - // If just the complexExpr is complex, the otherExpr needs to be converted, - // and the complexExpr might need to be promoted. - if (order > 0) { // complexExpr is wider - // float -> _Complex double - if (ConvertOtherExpr) { - QualType fp = cast<ComplexType>(ComplexTy)->getElementType(); - OtherExpr = S.ImpCastExprToType(OtherExpr.get(), fp, CK_FloatingCast); - OtherExpr = S.ImpCastExprToType(OtherExpr.get(), ComplexTy, - CK_FloatingRealToComplex); - } - return ComplexTy; - } - - // otherTy is at least as wide. Find its corresponding complex type. - QualType result = (order == 0 ? ComplexTy : - S.Context.getComplexType(OtherTy)); - - // double -> _Complex double - if (ConvertOtherExpr) - OtherExpr = S.ImpCastExprToType(OtherExpr.get(), result, - CK_FloatingRealToComplex); - - // _Complex float -> _Complex double - if (ConvertComplexExpr && order < 0) - ComplexExpr = S.ImpCastExprToType(ComplexExpr.get(), result, - CK_FloatingComplexCast); - - return result; -} - /// \brief Handle arithmetic conversion with complex types. Helper function of /// UsualArithmeticConversions() static QualType handleComplexFloatConversion(Sema &S, ExprResult &LHS, @@ -1020,26 +965,35 @@ static QualType handleComplexFloatConversion(Sema &S, ExprResult &LHS, // when combining a "long double" with a "double _Complex", the // "double _Complex" is promoted to "long double _Complex". - bool LHSComplexFloat = LHSType->isComplexType(); - bool RHSComplexFloat = RHSType->isComplexType(); - - // If both are complex, just cast to the more precise type. - if (LHSComplexFloat && RHSComplexFloat) - return handleComplexFloatToComplexFloatConverstion(S, LHS, RHS, - LHSType, RHSType, - IsCompAssign); - - // If only one operand is complex, promote it if necessary and convert the - // other operand to complex. - if (LHSComplexFloat) - return handleOtherComplexFloatConversion( - S, LHS, RHS, LHSType, RHSType, /*convertComplexExpr*/!IsCompAssign, - /*convertOtherExpr*/ true); - - assert(RHSComplexFloat); - return handleOtherComplexFloatConversion( - S, RHS, LHS, RHSType, LHSType, /*convertComplexExpr*/true, - /*convertOtherExpr*/ !IsCompAssign); + // Compute the rank of the two types, regardless of whether they are complex. + int Order = S.Context.getFloatingTypeOrder(LHSType, RHSType); + + auto *LHSComplexType = dyn_cast<ComplexType>(LHSType); + auto *RHSComplexType = dyn_cast<ComplexType>(RHSType); + QualType LHSElementType = + LHSComplexType ? LHSComplexType->getElementType() : LHSType; + QualType RHSElementType = + RHSComplexType ? RHSComplexType->getElementType() : RHSType; + + QualType ResultType = S.Context.getComplexType(LHSElementType); + if (Order < 0) { + // Promote the precision of the LHS if not an assignment. + ResultType = S.Context.getComplexType(RHSElementType); + if (!IsCompAssign) { + if (LHSComplexType) + LHS = + S.ImpCastExprToType(LHS.get(), ResultType, CK_FloatingComplexCast); + else + LHS = S.ImpCastExprToType(LHS.get(), RHSElementType, CK_FloatingCast); + } + } else if (Order > 0) { + // Promote the precision of the RHS. + if (RHSComplexType) + RHS = S.ImpCastExprToType(RHS.get(), ResultType, CK_FloatingComplexCast); + else + RHS = S.ImpCastExprToType(RHS.get(), LHSElementType, CK_FloatingCast); + } + return ResultType; } /// \brief Hande arithmetic conversion from integer to float. Helper function @@ -1336,6 +1290,13 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc, ControllingExpr = result.get(); } + // The controlling expression is an unevaluated operand, so side effects are + // likely unintended. + if (ActiveTemplateInstantiations.empty() && + ControllingExpr->HasSideEffects(Context, false)) + Diag(ControllingExpr->getExprLoc(), + diag::warn_side_effects_unevaluated_context); + bool TypeErrorFound = false, IsResultDependent = ControllingExpr->isTypeDependent(), ContainsUnexpandedParameterPack @@ -1636,40 +1597,37 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, if (getLangOpts().CUDA) if (const FunctionDecl *Caller = dyn_cast<FunctionDecl>(CurContext)) if (const FunctionDecl *Callee = dyn_cast<FunctionDecl>(D)) { - CUDAFunctionTarget CallerTarget = IdentifyCUDATarget(Caller), - CalleeTarget = IdentifyCUDATarget(Callee); - if (CheckCUDATarget(CallerTarget, CalleeTarget)) { + if (CheckCUDATarget(Caller, Callee)) { Diag(NameInfo.getLoc(), diag::err_ref_bad_target) - << CalleeTarget << D->getIdentifier() << CallerTarget; + << IdentifyCUDATarget(Callee) << D->getIdentifier() + << IdentifyCUDATarget(Caller); Diag(D->getLocation(), diag::note_previous_decl) << D->getIdentifier(); return ExprError(); } } - bool refersToEnclosingScope = - (CurContext != D->getDeclContext() && - D->getDeclContext()->isFunctionOrMethod()) || - (isa<VarDecl>(D) && - cast<VarDecl>(D)->isInitCapture()); + bool RefersToCapturedVariable = + isa<VarDecl>(D) && + NeedToCaptureVariable(cast<VarDecl>(D), NameInfo.getLoc()); DeclRefExpr *E; if (isa<VarTemplateSpecializationDecl>(D)) { VarTemplateSpecializationDecl *VarSpec = cast<VarTemplateSpecializationDecl>(D); - E = DeclRefExpr::Create( - Context, - SS ? SS->getWithLocInContext(Context) : NestedNameSpecifierLoc(), - VarSpec->getTemplateKeywordLoc(), D, refersToEnclosingScope, - NameInfo.getLoc(), Ty, VK, FoundD, TemplateArgs); + E = DeclRefExpr::Create(Context, SS ? SS->getWithLocInContext(Context) + : NestedNameSpecifierLoc(), + VarSpec->getTemplateKeywordLoc(), D, + RefersToCapturedVariable, NameInfo.getLoc(), Ty, VK, + FoundD, TemplateArgs); } else { assert(!TemplateArgs && "No template arguments for non-variable" " template specialization references"); - E = DeclRefExpr::Create( - Context, - SS ? SS->getWithLocInContext(Context) : NestedNameSpecifierLoc(), - SourceLocation(), D, refersToEnclosingScope, NameInfo, Ty, VK, FoundD); + E = DeclRefExpr::Create(Context, SS ? SS->getWithLocInContext(Context) + : NestedNameSpecifierLoc(), + SourceLocation(), D, RefersToCapturedVariable, + NameInfo, Ty, VK, FoundD); } MarkDeclRefReferenced(E); @@ -1719,13 +1677,48 @@ Sema::DecomposeUnqualifiedId(const UnqualifiedId &Id, } } +static void emitEmptyLookupTypoDiagnostic( + const TypoCorrection &TC, Sema &SemaRef, const CXXScopeSpec &SS, + DeclarationName Typo, SourceLocation TypoLoc, ArrayRef<Expr *> Args, + unsigned DiagnosticID, unsigned DiagnosticSuggestID) { + DeclContext *Ctx = + SS.isEmpty() ? nullptr : SemaRef.computeDeclContext(SS, false); + if (!TC) { + // Emit a special diagnostic for failed member lookups. + // FIXME: computing the declaration context might fail here (?) + if (Ctx) + SemaRef.Diag(TypoLoc, diag::err_no_member) << Typo << Ctx + << SS.getRange(); + else + SemaRef.Diag(TypoLoc, DiagnosticID) << Typo; + return; + } + + std::string CorrectedStr = TC.getAsString(SemaRef.getLangOpts()); + bool DroppedSpecifier = + TC.WillReplaceSpecifier() && Typo.getAsString() == CorrectedStr; + unsigned NoteID = + (TC.getCorrectionDecl() && isa<ImplicitParamDecl>(TC.getCorrectionDecl())) + ? diag::note_implicit_param_decl + : diag::note_previous_decl; + if (!Ctx) + SemaRef.diagnoseTypo(TC, SemaRef.PDiag(DiagnosticSuggestID) << Typo, + SemaRef.PDiag(NoteID)); + else + SemaRef.diagnoseTypo(TC, SemaRef.PDiag(diag::err_no_member_suggest) + << Typo << Ctx << DroppedSpecifier + << SS.getRange(), + SemaRef.PDiag(NoteID)); +} + /// Diagnose an empty lookup. /// /// \return false if new lookup candidates were found -bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, - CorrectionCandidateCallback &CCC, - TemplateArgumentListInfo *ExplicitTemplateArgs, - ArrayRef<Expr *> Args) { +bool +Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, + std::unique_ptr<CorrectionCandidateCallback> CCC, + TemplateArgumentListInfo *ExplicitTemplateArgs, + ArrayRef<Expr *> Args, TypoExpr **Out) { DeclarationName Name = R.getLookupName(); unsigned diagnostic = diag::err_undeclared_var_use; @@ -1842,8 +1835,22 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, // We didn't find anything, so try to correct for a typo. TypoCorrection Corrected; - if (S && (Corrected = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), - S, &SS, CCC, CTK_ErrorRecovery))) { + if (S && Out) { + SourceLocation TypoLoc = R.getNameLoc(); + assert(!ExplicitTemplateArgs && + "Diagnosing an empty lookup with explicit template args!"); + *Out = CorrectTypoDelayed( + R.getLookupNameInfo(), R.getLookupKind(), S, &SS, std::move(CCC), + [=](const TypoCorrection &TC) { + emitEmptyLookupTypoDiagnostic(TC, *this, SS, Name, TypoLoc, Args, + diagnostic, diagnostic_suggest); + }, + nullptr, CTK_ErrorRecovery); + if (*Out) + return true; + } else if (S && (Corrected = + CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, + &SS, std::move(CCC), CTK_ErrorRecovery))) { std::string CorrectedStr(Corrected.getAsString(getLangOpts())); bool DroppedSpecifier = Corrected.WillReplaceSpecifier() && Name.getAsString() == CorrectedStr; @@ -1990,14 +1997,12 @@ recoverFromMSUnqualifiedLookup(Sema &S, ASTContext &Context, TemplateArgs); } -ExprResult Sema::ActOnIdExpression(Scope *S, - CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - UnqualifiedId &Id, - bool HasTrailingLParen, - bool IsAddressOfOperand, - CorrectionCandidateCallback *CCC, - bool IsInlineAsmIdentifier) { +ExprResult +Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, UnqualifiedId &Id, + bool HasTrailingLParen, bool IsAddressOfOperand, + std::unique_ptr<CorrectionCandidateCallback> CCC, + bool IsInlineAsmIdentifier, Token *KeywordReplacement) { assert(!(IsAddressOfOperand && HasTrailingLParen) && "cannot be direct & operand and have a trailing lparen"); if (SS.isInvalid()) @@ -2109,12 +2114,43 @@ ExprResult Sema::ActOnIdExpression(Scope *S, // If this name wasn't predeclared and if this is not a function // call, diagnose the problem. - CorrectionCandidateCallback DefaultValidator; - DefaultValidator.IsAddressOfOperand = IsAddressOfOperand; + TypoExpr *TE = nullptr; + auto DefaultValidator = llvm::make_unique<CorrectionCandidateCallback>( + II, SS.isValid() ? SS.getScopeRep() : nullptr); + DefaultValidator->IsAddressOfOperand = IsAddressOfOperand; assert((!CCC || CCC->IsAddressOfOperand == IsAddressOfOperand) && "Typo correction callback misconfigured"); - if (DiagnoseEmptyLookup(S, SS, R, CCC ? *CCC : DefaultValidator)) - return ExprError(); + if (CCC) { + // Make sure the callback knows what the typo being diagnosed is. + CCC->setTypoName(II); + if (SS.isValid()) + CCC->setTypoNNS(SS.getScopeRep()); + } + if (DiagnoseEmptyLookup(S, SS, R, + CCC ? std::move(CCC) : std::move(DefaultValidator), + nullptr, None, &TE)) { + if (TE && KeywordReplacement) { + auto &State = getTypoExprState(TE); + auto BestTC = State.Consumer->getNextCorrection(); + if (BestTC.isKeyword()) { + auto *II = BestTC.getCorrectionAsIdentifierInfo(); + if (State.DiagHandler) + State.DiagHandler(BestTC); + KeywordReplacement->startToken(); + KeywordReplacement->setKind(II->getTokenID()); + KeywordReplacement->setIdentifierInfo(II); + KeywordReplacement->setLocation(BestTC.getCorrectionRange().getBegin()); + // Clean up the state associated with the TypoExpr, since it has + // now been diagnosed (without a call to CorrectDelayedTyposInExpr). + clearDelayedTypo(TE); + // Signal that a correction to a keyword was performed by returning a + // valid-but-null ExprResult. + return (Expr*)nullptr; + } + State.Consumer->resetCorrectionStream(); + } + return TE ? TE : ExprError(); + } assert(!R.empty() && "DiagnoseEmptyLookup returned false but added no results"); @@ -2364,10 +2400,9 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, !IvarBacksCurrentMethodAccessor(IFace, CurMethod, IV)) Diag(Loc, diag::warn_direct_ivar_access) << IV->getDeclName(); - ObjCIvarRefExpr *Result = new (Context) ObjCIvarRefExpr(IV, IV->getType(), - Loc, IV->getLocation(), - SelfExpr.get(), - true, true); + ObjCIvarRefExpr *Result = new (Context) + ObjCIvarRefExpr(IV, IV->getType(), Loc, IV->getLocation(), + SelfExpr.get(), true, true); if (getLangOpts().ObjCAutoRefCount) { if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) { @@ -2660,15 +2695,15 @@ static bool CheckDeclInExpr(Sema &S, SourceLocation Loc, NamedDecl *D) { return false; } -ExprResult -Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, - LookupResult &R, - bool NeedsADL) { +ExprResult Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, + LookupResult &R, bool NeedsADL, + bool AcceptInvalidDecl) { // If this is a single, fully-resolved result and we don't need ADL, // just build an ordinary singleton decl ref. if (!NeedsADL && R.isSingleResult() && !R.getAsSingle<FunctionTemplateDecl>()) return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), R.getFoundDecl(), - R.getRepresentativeDecl()); + R.getRepresentativeDecl(), nullptr, + AcceptInvalidDecl); // We only need to check the declaration if there's exactly one // result, because in the overloaded case the results can only be @@ -2695,7 +2730,8 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, /// \brief Complete semantic analysis for a reference to the given declaration. ExprResult Sema::BuildDeclarationNameExpr( const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl *D, - NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs) { + NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs, + bool AcceptInvalidDecl) { assert(D && "Cannot refer to a NULL declaration"); assert(!isa<FunctionTemplateDecl>(D) && "Cannot refer unambiguously to a function template"); @@ -2730,7 +2766,7 @@ ExprResult Sema::BuildDeclarationNameExpr( return ExprError(); // Only create DeclRefExpr's for valid Decl's. - if (VD->isInvalidDecl()) + if (VD->isInvalidDecl() && !AcceptInvalidDecl) return ExprError(); // Handle members of anonymous structs and unions. If we got here, @@ -2902,6 +2938,17 @@ ExprResult Sema::BuildDeclarationNameExpr( } } +static void ConvertUTF8ToWideString(unsigned CharByteWidth, StringRef Source, + SmallString<32> &Target) { + Target.resize(CharByteWidth * (Source.size() + 1)); + char *ResultPtr = &Target[0]; + const UTF8 *ErrorPtr; + bool success = ConvertUTF8toWide(CharByteWidth, Source, ResultPtr, ErrorPtr); + (void)success; + assert(success); + Target.resize(ResultPtr - &Target[0]); +} + ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc, PredefinedExpr::IdentType IT) { // Pick the current block, lambda, captured statement or function. @@ -2921,22 +2968,35 @@ ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc, } QualType ResTy; + StringLiteral *SL = nullptr; if (cast<DeclContext>(currentDecl)->isDependentContext()) ResTy = Context.DependentTy; else { // Pre-defined identifiers are of type char[x], where x is the length of // the string. - unsigned Length = PredefinedExpr::ComputeName(IT, currentDecl).length(); + auto Str = PredefinedExpr::ComputeName(IT, currentDecl); + unsigned Length = Str.length(); llvm::APInt LengthI(32, Length + 1); - if (IT == PredefinedExpr::LFunction) + if (IT == PredefinedExpr::LFunction) { ResTy = Context.WideCharTy.withConst(); - else + SmallString<32> RawChars; + ConvertUTF8ToWideString(Context.getTypeSizeInChars(ResTy).getQuantity(), + Str, RawChars); + ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, + /*IndexTypeQuals*/ 0); + SL = StringLiteral::Create(Context, RawChars, StringLiteral::Wide, + /*Pascal*/ false, ResTy, Loc); + } else { ResTy = Context.CharTy.withConst(); - ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, 0); + ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, + /*IndexTypeQuals*/ 0); + SL = StringLiteral::Create(Context, Str, StringLiteral::Ascii, + /*Pascal*/ false, ResTy, Loc); + } } - return new (Context) PredefinedExpr(Loc, ResTy, IT); + return new (Context) PredefinedExpr(Loc, ResTy, IT, SL); } ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) { @@ -3046,6 +3106,34 @@ static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal, return FloatingLiteral::Create(S.Context, Val, isExact, Ty, Loc); } +bool Sema::CheckLoopHintExpr(Expr *E, SourceLocation Loc) { + assert(E && "Invalid expression"); + + if (E->isValueDependent()) + return false; + + QualType QT = E->getType(); + if (!QT->isIntegerType() || QT->isBooleanType() || QT->isCharType()) { + Diag(E->getExprLoc(), diag::err_pragma_loop_invalid_argument_type) << QT; + return true; + } + + llvm::APSInt ValueAPS; + ExprResult R = VerifyIntegerConstantExpression(E, &ValueAPS); + + if (R.isInvalid()) + return true; + + bool ValueIsPositive = ValueAPS.isStrictlyPositive(); + if (!ValueIsPositive || ValueAPS.getActiveBits() > 31) { + Diag(E->getExprLoc(), diag::err_pragma_loop_invalid_argument_value) + << ValueAPS.toString(10) << ValueIsPositive; + return true; + } + + return false; +} + ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { // Fast path for a single digit (which is quite common). A single digit // cannot have a trigraph, escaped newline, radix prefix, or suffix. @@ -3117,7 +3205,8 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { } else { llvm::APInt ResultVal(Context.getTargetInfo().getLongLongWidth(), 0); if (Literal.GetIntegerValue(ResultVal)) - Diag(Tok.getLocation(), diag::err_integer_too_large); + Diag(Tok.getLocation(), diag::err_integer_literal_too_large) + << /* Unsigned */ 1; Lit = IntegerLiteral::Create(Context, ResultVal, CookedTy, Tok.getLocation()); } @@ -3210,7 +3299,8 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { if (Literal.GetIntegerValue(ResultVal)) { // If this value didn't fit into uintmax_t, error and force to ull. - Diag(Tok.getLocation(), diag::err_integer_too_large); + Diag(Tok.getLocation(), diag::err_integer_literal_too_large) + << /* Unsigned */ 1; Ty = Context.UnsignedLongLongTy; assert(Context.getTypeSize(Ty) == ResultVal.getBitWidth() && "long long is not intmax_t?"); @@ -3290,7 +3380,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { // If we still couldn't decide a type, we probably have something that // does not fit in a signed long long, but has no U suffix. if (Ty.isNull()) { - Diag(Tok.getLocation(), diag::ext_integer_too_large_for_signed); + Diag(Tok.getLocation(), diag::ext_integer_literal_too_large_for_signed); Ty = Context.UnsignedLongLongTy; Width = Context.getTargetInfo().getLongLongWidth(); } @@ -3442,6 +3532,12 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(Expr *E, return true; } + // The operand for sizeof and alignof is in an unevaluated expression context, + // so side effects could result in unintended consequences. + if ((ExprKind == UETT_SizeOf || ExprKind == UETT_AlignOf) && + ActiveTemplateInstantiations.empty() && E->HasSideEffects(Context, false)) + Diag(E->getExprLoc(), diag::warn_side_effects_unevaluated_context); + if (CheckObjCTraitOperandConstraints(*this, ExprTy, E->getExprLoc(), E->getSourceRange(), ExprKind)) return true; @@ -4083,11 +4179,12 @@ static TypoCorrection TryTypoCorrectionForCall(Sema &S, Expr *Fn, MemberExpr *ME = dyn_cast<MemberExpr>(Fn); DeclarationName FuncName = FDecl->getDeclName(); SourceLocation NameLoc = ME ? ME->getMemberLoc() : Fn->getLocStart(); - FunctionCallCCC CCC(S, FuncName.getAsIdentifierInfo(), Args.size(), ME); if (TypoCorrection Corrected = S.CorrectTypo( DeclarationNameInfo(FuncName, NameLoc), Sema::LookupOrdinaryName, - S.getScopeForContext(S.CurContext), nullptr, CCC, + S.getScopeForContext(S.CurContext), nullptr, + llvm::make_unique<FunctionCallCCC>(S, FuncName.getAsIdentifierInfo(), + Args.size(), ME), Sema::CTK_ErrorRecovery)) { if (NamedDecl *ND = Corrected.getCorrectionDecl()) { if (Corrected.isOverloaded()) { @@ -4454,6 +4551,8 @@ static bool checkArgsForPlaceholders(Sema &S, MultiExprArg args) { ExprResult result = S.CheckPlaceholderExpr(args[i]); if (result.isInvalid()) hasInvalid = true; else args[i] = result.get(); + } else if (hasInvalid) { + (void)S.CorrectDelayedTyposInExpr(args[i]); } } return hasInvalid; @@ -4587,23 +4686,6 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, ExecConfig, IsExecConfig); } -ExprResult -Sema::ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc, - MultiExprArg ExecConfig, SourceLocation GGGLoc) { - FunctionDecl *ConfigDecl = Context.getcudaConfigureCallDecl(); - if (!ConfigDecl) - return ExprError(Diag(LLLLoc, diag::err_undeclared_var_use) - << "cudaConfigureCall"); - QualType ConfigQTy = ConfigDecl->getType(); - - DeclRefExpr *ConfigDR = new (Context) DeclRefExpr( - ConfigDecl, false, ConfigQTy, VK_LValue, LLLLoc); - MarkFunctionReferenced(LLLLoc, ConfigDecl); - - return ActOnCallExpr(S, ConfigDR, LLLLoc, ExecConfig, GGGLoc, nullptr, - /*IsExecConfig=*/true); -} - /// ActOnAsTypeExpr - create a new asType (bitcast) from the arguments. /// /// __builtin_astype( value, dst type ) @@ -4680,8 +4762,12 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, VK_RValue, RParenLoc); // Bail out early if calling a builtin with custom typechecking. - if (BuiltinID && Context.BuiltinInfo.hasCustomTypechecking(BuiltinID)) - return CheckBuiltinFunctionCall(BuiltinID, TheCall); + if (BuiltinID && Context.BuiltinInfo.hasCustomTypechecking(BuiltinID)) { + ExprResult Res = CorrectDelayedTyposInExpr(TheCall); + if (!Res.isUsable() || !isa<CallExpr>(Res.get())) + return Res; + return CheckBuiltinFunctionCall(FDecl, BuiltinID, cast<CallExpr>(Res.get())); + } retry: const FunctionType *FuncT; @@ -4809,7 +4895,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, return ExprError(); if (BuiltinID) - return CheckBuiltinFunctionCall(BuiltinID, TheCall); + return CheckBuiltinFunctionCall(FDecl, BuiltinID, TheCall); } else if (NDecl) { if (CheckPointerCall(NDecl, TheCall, Proto)) return ExprError(); @@ -5227,6 +5313,12 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, if (getLangOpts().CPlusPlus) { // Check that there are no default arguments (C++ only). CheckExtraCXXDefaultArguments(D); + } else { + // Make sure any TypoExprs have been dealt with. + ExprResult Res = CorrectDelayedTyposInExpr(CastExpr); + if (!Res.isUsable()) + return ExprError(); + CastExpr = Res.get(); } checkUnusedDeclAttributes(D); @@ -5693,6 +5785,15 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, ExprObjectKind &OK, SourceLocation QuestionLoc) { + if (!getLangOpts().CPlusPlus) { + // C cannot handle TypoExpr nodes on either side of a binop because it + // doesn't handle dependent types properly, so make sure any TypoExprs have + // been dealt with before checking the operands. + ExprResult CondResult = CorrectDelayedTyposInExpr(Cond); + if (!CondResult.isUsable()) return QualType(); + Cond = CondResult; + } + ExprResult LHSResult = CheckPlaceholderExpr(LHS.get()); if (!LHSResult.isUsable()) return QualType(); LHS = LHSResult; @@ -5720,7 +5821,7 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, RHS.get()->getType()->isVectorType()) return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false); - UsualArithmeticConversions(LHS, RHS); + QualType ResTy = UsualArithmeticConversions(LHS, RHS); if (LHS.isInvalid() || RHS.isInvalid()) return QualType(); @@ -5737,8 +5838,12 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, // 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()) - return LHS.get()->getType(); + if (LHSTy->isArithmeticType() && RHSTy->isArithmeticType()) { + LHS = ImpCastExprToType(LHS.get(), ResTy, PrepareScalarCast(LHS, ResTy)); + RHS = ImpCastExprToType(RHS.get(), ResTy, PrepareScalarCast(RHS, ResTy)); + + return ResTy; + } // If both operands are the same structure or union type, the result is that // type. @@ -6161,7 +6266,7 @@ checkPointerTypesForAssignment(Sema &S, QualType LHSType, QualType RHSType) { if (!lhq.compatiblyIncludes(rhq)) { // Treat address-space mismatches as fatal. TODO: address subspaces - if (lhq.getAddressSpace() != rhq.getAddressSpace()) + if (!lhq.isAddressSpaceSupersetOf(rhq)) ConvTy = Sema::IncompatiblePointerDiscardsQualifiers; // It's okay to add or remove GC or lifetime qualifiers when converting to @@ -6446,7 +6551,9 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, if (const PointerType *LHSPointer = dyn_cast<PointerType>(LHSType)) { // U* -> T* if (isa<PointerType>(RHSType)) { - Kind = CK_BitCast; + unsigned AddrSpaceL = LHSPointer->getPointeeType().getAddressSpace(); + unsigned AddrSpaceR = RHSType->getPointeeType().getAddressSpace(); + Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion : CK_BitCast; return checkPointerTypesForAssignment(*this, LHSType, RHSType); } @@ -6754,6 +6861,15 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, return Incompatible; } + Expr *PRE = RHS.get()->IgnoreParenCasts(); + if (ObjCProtocolExpr *OPE = dyn_cast<ObjCProtocolExpr>(PRE)) { + ObjCProtocolDecl *PDecl = OPE->getProtocol(); + if (PDecl && !PDecl->hasDefinition()) { + Diag(PRE->getExprLoc(), diag::warn_atprotocol_protocol) << PDecl->getName(); + Diag(PDecl->getLocation(), diag::note_entity_declared_at) << PDecl; + } + } + CastKind Kind = CK_Invalid; Sema::AssignConvertType result = CheckAssignmentConstraints(LHSType, RHS, Kind); @@ -7120,6 +7236,19 @@ static bool checkArithmeticBinOpPointerOperands(Sema &S, SourceLocation Loc, if (isLHSPointer) LHSPointeeTy = LHSExpr->getType()->getPointeeType(); if (isRHSPointer) RHSPointeeTy = RHSExpr->getType()->getPointeeType(); + // if both are pointers check if operation is valid wrt address spaces + if (isLHSPointer && isRHSPointer) { + const PointerType *lhsPtr = LHSExpr->getType()->getAs<PointerType>(); + const PointerType *rhsPtr = RHSExpr->getType()->getAs<PointerType>(); + if (!lhsPtr->isAddressSpaceOverlapping(*rhsPtr)) { + S.Diag(Loc, + diag::err_typecheck_op_on_nonoverlapping_address_space_pointers) + << LHSExpr->getType() << RHSExpr->getType() << 1 /*arithmetic op*/ + << LHSExpr->getSourceRange() << RHSExpr->getSourceRange(); + return false; + } + } + // Check for arithmetic on pointers to incomplete types. bool isLHSVoidPtr = isLHSPointer && LHSPointeeTy->isVoidType(); bool isRHSVoidPtr = isRHSPointer && RHSPointeeTy->isVoidType(); @@ -7163,7 +7292,7 @@ static void diagnoseStringPlusInt(Sema &Self, SourceLocation OpLoc, bool IsStringPlusInt = StrExpr && IndexExpr->getType()->isIntegralOrUnscopedEnumerationType(); - if (!IsStringPlusInt) + if (!IsStringPlusInt || IndexExpr->isValueDependent()) return; llvm::APSInt index; @@ -7193,13 +7322,13 @@ static void diagnoseStringPlusInt(Sema &Self, SourceLocation OpLoc, /// \brief Emit a warning when adding a char literal to a string. static void diagnoseStringPlusChar(Sema &Self, SourceLocation OpLoc, Expr *LHSExpr, Expr *RHSExpr) { - const DeclRefExpr *StringRefExpr = - dyn_cast<DeclRefExpr>(LHSExpr->IgnoreImpCasts()); + const Expr *StringRefExpr = LHSExpr; const CharacterLiteral *CharExpr = dyn_cast<CharacterLiteral>(RHSExpr->IgnoreImpCasts()); - if (!StringRefExpr) { - StringRefExpr = dyn_cast<DeclRefExpr>(RHSExpr->IgnoreImpCasts()); + + if (!CharExpr) { CharExpr = dyn_cast<CharacterLiteral>(LHSExpr->IgnoreImpCasts()); + StringRefExpr = RHSExpr; } if (!CharExpr || !StringRefExpr) @@ -7417,7 +7546,7 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS, } static bool isScopedEnumerationType(QualType T) { - if (const EnumType *ET = dyn_cast<EnumType>(T)) + if (const EnumType *ET = T->getAs<EnumType>()) return ET->getDecl()->isScoped(); return false; } @@ -8048,6 +8177,13 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, diagnoseDistinctPointerComparison(*this, Loc, LHS, RHS, /*isError*/false); } if (LCanPointeeTy != RCanPointeeTy) { + const PointerType *lhsPtr = LHSType->getAs<PointerType>(); + if (!lhsPtr->isAddressSpaceOverlapping(*RHSType->getAs<PointerType>())) { + Diag(Loc, + diag::err_typecheck_op_on_nonoverlapping_address_space_pointers) + << LHSType << RHSType << 0 /* comparison */ + << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); + } unsigned AddrSpaceL = LCanPointeeTy.getAddressSpace(); unsigned AddrSpaceR = RCanPointeeTy.getAddressSpace(); CastKind Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion @@ -8462,7 +8598,7 @@ static NonConstCaptureKind isReferenceToNonConstCapture(Sema &S, Expr *E) { // Must be a reference to a declaration from an enclosing scope. DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E); if (!DRE) return NCCK_None; - if (!DRE->refersToEnclosingLocal()) return NCCK_None; + if (!DRE->refersToEnclosingVariableOrCapture()) return NCCK_None; // The declaration must be a variable which is not declared 'const'. VarDecl *var = dyn_cast<VarDecl>(DRE->getDecl()); @@ -8494,19 +8630,19 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) { if (IsLV == Expr::MLV_Valid) return false; - unsigned Diag = 0; + unsigned DiagID = 0; bool NeedType = false; switch (IsLV) { // C99 6.5.16p2 case Expr::MLV_ConstQualified: - Diag = diag::err_typecheck_assign_const; + DiagID = diag::err_typecheck_assign_const; // Use a specialized diagnostic when we're assigning to an object // from an enclosing function or block. if (NonConstCaptureKind NCCK = isReferenceToNonConstCapture(S, E)) { if (NCCK == NCCK_Block) - Diag = diag::err_block_decl_ref_not_modifiable_lvalue; + DiagID = diag::err_block_decl_ref_not_modifiable_lvalue; else - Diag = diag::err_lambda_decl_ref_not_modifiable_lvalue; + DiagID = diag::err_lambda_decl_ref_not_modifiable_lvalue; break; } @@ -8526,18 +8662,18 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) { // - self ObjCMethodDecl *method = S.getCurMethodDecl(); if (method && var == method->getSelfDecl()) - Diag = method->isClassMethod() + DiagID = method->isClassMethod() ? diag::err_typecheck_arc_assign_self_class_method : diag::err_typecheck_arc_assign_self; // - fast enumeration variables else - Diag = diag::err_typecheck_arr_assign_enumeration; + DiagID = diag::err_typecheck_arr_assign_enumeration; SourceRange Assign; if (Loc != OrigLoc) Assign = SourceRange(OrigLoc, OrigLoc); - S.Diag(Loc, Diag) << E->getSourceRange() << Assign; + S.Diag(Loc, DiagID) << E->getSourceRange() << Assign; // We need to preserve the AST regardless, so migration tool // can do its job. return false; @@ -8548,37 +8684,37 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) { break; case Expr::MLV_ArrayType: case Expr::MLV_ArrayTemporary: - Diag = diag::err_typecheck_array_not_modifiable_lvalue; + DiagID = diag::err_typecheck_array_not_modifiable_lvalue; NeedType = true; break; case Expr::MLV_NotObjectType: - Diag = diag::err_typecheck_non_object_not_modifiable_lvalue; + DiagID = diag::err_typecheck_non_object_not_modifiable_lvalue; NeedType = true; break; case Expr::MLV_LValueCast: - Diag = diag::err_typecheck_lvalue_casts_not_supported; + DiagID = diag::err_typecheck_lvalue_casts_not_supported; break; case Expr::MLV_Valid: llvm_unreachable("did not take early return for MLV_Valid"); case Expr::MLV_InvalidExpression: case Expr::MLV_MemberFunction: case Expr::MLV_ClassTemporary: - Diag = diag::err_typecheck_expression_not_modifiable_lvalue; + DiagID = diag::err_typecheck_expression_not_modifiable_lvalue; break; case Expr::MLV_IncompleteType: case Expr::MLV_IncompleteVoidType: return S.RequireCompleteType(Loc, E->getType(), diag::err_typecheck_incomplete_type_not_modifiable_lvalue, E); case Expr::MLV_DuplicateVectorComponents: - Diag = diag::err_typecheck_duplicate_vector_components_not_mlvalue; + DiagID = diag::err_typecheck_duplicate_vector_components_not_mlvalue; break; case Expr::MLV_NoSetterProperty: llvm_unreachable("readonly properties should be processed differently"); case Expr::MLV_InvalidMessageExpression: - Diag = diag::error_readonly_message_assignment; + DiagID = diag::error_readonly_message_assignment; break; case Expr::MLV_SubObjCPropertySetting: - Diag = diag::error_no_subobject_property_setting; + DiagID = diag::error_no_subobject_property_setting; break; } @@ -8586,9 +8722,9 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) { if (Loc != OrigLoc) Assign = SourceRange(OrigLoc, OrigLoc); if (NeedType) - S.Diag(Loc, Diag) << E->getType() << E->getSourceRange() << Assign; + S.Diag(Loc, DiagID) << E->getType() << E->getSourceRange() << Assign; else - S.Diag(Loc, Diag) << E->getSourceRange() << Assign; + S.Diag(Loc, DiagID) << E->getSourceRange() << Assign; return true; } @@ -8754,6 +8890,7 @@ static QualType CheckCommaOperands(Sema &S, ExprResult &LHS, ExprResult &RHS, /// doesn't need to call UsualUnaryConversions or UsualArithmeticConversions. static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op, ExprValueKind &VK, + ExprObjectKind &OK, SourceLocation OpLoc, bool IsInc, bool IsPrefix) { if (Op->isTypeDependent()) @@ -8799,7 +8936,7 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op, } else if (ResType->isPlaceholderType()) { ExprResult PR = S.CheckPlaceholderExpr(Op); if (PR.isInvalid()) return QualType(); - return CheckIncrementDecrementOperand(S, PR.get(), VK, OpLoc, + return CheckIncrementDecrementOperand(S, PR.get(), VK, OK, OpLoc, IsInc, IsPrefix); } else if (S.getLangOpts().AltiVec && ResType->isVectorType()) { // OK! ( C/C++ Language Extensions for CBEA(Version 2.6) 10.3 ) @@ -8820,6 +8957,7 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op, // operand. if (IsPrefix && S.getLangOpts().CPlusPlus) { VK = VK_LValue; + OK = Op->getObjectKind(); return ResType; } else { VK = VK_RValue; @@ -9104,6 +9242,24 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) { return Context.getPointerType(op->getType()); } +static void RecordModifiableNonNullParam(Sema &S, const Expr *Exp) { + const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Exp); + if (!DRE) + return; + const Decl *D = DRE->getDecl(); + if (!D) + return; + const ParmVarDecl *Param = dyn_cast<ParmVarDecl>(D); + if (!Param) + return; + if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(Param->getDeclContext())) + if (!FD->hasAttr<NonNullAttr>() && !Param->hasAttr<NonNullAttr>()) + return; + if (FunctionScopeInfo *FD = S.getCurFunction()) + if (!FD->ModifiedNonNullParams.count(Param)) + FD->ModifiedNonNullParams.insert(Param); +} + /// CheckIndirectionOperand - Type check unary indirection (prefix '*'). static QualType CheckIndirectionOperand(Sema &S, Expr *Op, ExprValueKind &VK, SourceLocation OpLoc) { @@ -9164,8 +9320,7 @@ static QualType CheckIndirectionOperand(Sema &S, Expr *Op, ExprValueKind &VK, return Result; } -static inline BinaryOperatorKind ConvertTokenKindToBinaryOpcode( - tok::TokenKind Kind) { +BinaryOperatorKind Sema::ConvertTokenKindToBinaryOpcode(tok::TokenKind Kind) { BinaryOperatorKind Opc; switch (Kind) { default: llvm_unreachable("Unknown binop!"); @@ -9334,6 +9489,16 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, ExprValueKind VK = VK_RValue; ExprObjectKind OK = OK_Ordinary; + if (!getLangOpts().CPlusPlus) { + // C cannot handle TypoExpr nodes on either side of a binop because it + // doesn't handle dependent types properly, so make sure any TypoExprs have + // been dealt with before checking the operands. + LHS = CorrectDelayedTyposInExpr(LHSExpr); + RHS = CorrectDelayedTyposInExpr(RHSExpr); + if (!LHS.isUsable() || !RHS.isUsable()) + return ExprError(); + } + switch (Opc) { case BO_Assign: ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, QualType()); @@ -9342,8 +9507,11 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, VK = LHS.get()->getValueKind(); OK = LHS.get()->getObjectKind(); } - if (!ResultTy.isNull()) + if (!ResultTy.isNull()) { DiagnoseSelfAssignment(*this, LHS.get(), RHS.get(), OpLoc); + DiagnoseSelfMove(LHS.get(), RHS.get(), OpLoc); + } + RecordModifiableNonNullParam(*this, LHS.get()); break; case BO_PtrMemD: case BO_PtrMemI: @@ -9503,7 +9671,7 @@ static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperatorKind Opc, StringRef OpStr = isLeftComp ? LHSBO->getOpcodeStr() : RHSBO->getOpcodeStr(); SourceRange ParensRange = isLeftComp ? SourceRange(LHSBO->getRHS()->getLocStart(), RHSExpr->getLocEnd()) - : SourceRange(LHSExpr->getLocStart(), RHSBO->getLHS()->getLocStart()); + : SourceRange(LHSExpr->getLocStart(), RHSBO->getLHS()->getLocEnd()); Self.Diag(OpLoc, diag::warn_precedence_bitwise_rel) << DiagRange << BinaryOperator::getOpcodeStr(Opc) << OpStr; @@ -9709,7 +9877,7 @@ static ExprResult BuildOverloadedBinOp(Sema &S, Scope *Sc, SourceLocation OpLoc, UnresolvedSet<16> Functions; OverloadedOperatorKind OverOp = BinaryOperator::getOverloadedOperator(Opc); - if (Sc && OverOp != OO_None) + if (Sc && OverOp != OO_None && OverOp != OO_Equal) S.LookupOverloadedOperatorName(OverOp, Sc, LHS->getType(), RHS->getType(), Functions); @@ -9808,7 +9976,8 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, case UO_PreDec: case UO_PostInc: case UO_PostDec: - resultType = CheckIncrementDecrementOperand(*this, Input.get(), VK, OpLoc, + resultType = CheckIncrementDecrementOperand(*this, Input.get(), VK, OK, + OpLoc, Opc == UO_PreInc || Opc == UO_PostInc, Opc == UO_PreInc || @@ -9816,6 +9985,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, break; case UO_AddrOf: resultType = CheckAddressOfOperand(Input, OpLoc); + RecordModifiableNonNullParam(*this, InputExpr); break; case UO_Deref: { Input = DefaultFunctionArrayLvalueConversion(Input.get()); @@ -10107,11 +10277,6 @@ Sema::ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, assert(!ExprNeedsCleanups && "cleanups within StmtExpr not correctly bound!"); PopExpressionEvaluationContext(); - bool isFileScope - = (getCurFunctionOrMethodDecl() == nullptr) && (getCurBlock() == nullptr); - if (isFileScope) - return ExprError(Diag(LPLoc, diag::err_stmtexpr_file_scope)); - // FIXME: there are a variety of strange constraints to enforce here, for // example, it is not possible to goto into a stmt expression apparently. // More semantic analysis is needed. @@ -10998,7 +11163,7 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, PartialDiagnostic FDiag = PDiag(DiagKind); if (Action == AA_Passing_CFAudited) - FDiag << FirstType << SecondType << SrcExpr->getSourceRange(); + FDiag << FirstType << SecondType << AA_Passing << SrcExpr->getSourceRange(); else FDiag << FirstType << SecondType << Action << SrcExpr->getSourceRange(); @@ -11285,6 +11450,7 @@ Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, void Sema::PopExpressionEvaluationContext() { ExpressionEvaluationContextRecord& Rec = ExprEvalContexts.back(); + unsigned NumTypos = Rec.NumTypos; if (!Rec.Lambdas.empty()) { if (Rec.isUnevaluated() || Rec.Context == ConstantEvaluated) { @@ -11301,19 +11467,14 @@ void Sema::PopExpressionEvaluationContext() { // evaluate [...] a lambda-expression. D = diag::err_lambda_in_constant_expression; } - for (unsigned I = 0, N = Rec.Lambdas.size(); I != N; ++I) - Diag(Rec.Lambdas[I]->getLocStart(), D); + for (const auto *L : Rec.Lambdas) + Diag(L->getLocStart(), D); } else { // Mark the capture expressions odr-used. This was deferred // during lambda expression creation. - for (unsigned I = 0, N = Rec.Lambdas.size(); I != N; ++I) { - LambdaExpr *Lambda = Rec.Lambdas[I]; - for (LambdaExpr::capture_init_iterator - C = Lambda->capture_init_begin(), - CEnd = Lambda->capture_init_end(); - C != CEnd; ++C) { - MarkDeclarationsReferencedInExpr(*C); - } + for (auto *Lambda : Rec.Lambdas) { + for (auto *C : Lambda->capture_inits()) + MarkDeclarationsReferencedInExpr(C); } } } @@ -11337,6 +11498,12 @@ void Sema::PopExpressionEvaluationContext() { // Pop the current expression evaluation context off the stack. ExprEvalContexts.pop_back(); + + if (!ExprEvalContexts.empty()) + ExprEvalContexts.back().NumTypos += NumTypos; + else + assert(NumTypos == 0 && "There are outstanding typos after popping the " + "last ExpressionEvaluationContextRecord"); } void Sema::DiscardCleanupsInEvaluationContext() { @@ -11385,7 +11552,8 @@ 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) { +void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, + bool OdrUse) { assert(Func && "No function?"); Func->setReferenced(); @@ -11484,6 +11652,8 @@ 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()) { @@ -11636,7 +11806,7 @@ static DeclContext *getParentOfCapturingContextOrNull(DeclContext *DC, VarDecl * const bool Diagnose, Sema &S) { if (isa<BlockDecl>(DC) || isa<CapturedDecl>(DC) || isLambdaCallOperator(DC)) return getLambdaAwareParentOfDeclContext(DC); - else { + else if (Var->hasLocalStorage()) { if (Diagnose) diagnoseUncapturableValueReference(S, Loc, Var, DC); } @@ -11665,13 +11835,10 @@ static bool isVariableCapturable(CapturingScopeInfo *CSI, VarDecl *Var, return false; } - // Prohibit variably-modified types; they're difficult to deal with. - if (Var->getType()->isVariablyModifiedType() && (IsBlock || IsLambda)) { + // Prohibit variably-modified types in blocks; they're difficult to deal with. + if (Var->getType()->isVariablyModifiedType() && IsBlock) { if (Diagnose) { - if (IsBlock) - S.Diag(Loc, diag::err_ref_vm_type); - else - S.Diag(Loc, diag::err_lambda_capture_vm_type) << Var->getDeclName(); + S.Diag(Loc, diag::err_ref_vm_type); S.Diag(Var->getLocation(), diag::note_previous_decl) << Var->getDeclName(); } @@ -11807,7 +11974,7 @@ static bool captureInCapturedRegion(CapturedRegionScopeInfo *RSI, const bool BuildAndDiagnose, QualType &CaptureType, QualType &DeclRefType, - const bool RefersToEnclosingLocal, + const bool RefersToCapturedVariable, Sema &S) { // By default, capture variables by reference. @@ -11829,7 +11996,7 @@ static bool captureInCapturedRegion(CapturedRegionScopeInfo *RSI, Field->setAccess(AS_private); RD->addDecl(Field); - CopyExpr = new (S.Context) DeclRefExpr(Var, RefersToEnclosingLocal, + CopyExpr = new (S.Context) DeclRefExpr(Var, RefersToCapturedVariable, DeclRefType, VK_LValue, Loc); Var->setReferenced(true); Var->markUsed(S.Context); @@ -11837,7 +12004,7 @@ static bool captureInCapturedRegion(CapturedRegionScopeInfo *RSI, // Actually capture the variable. if (BuildAndDiagnose) - RSI->addCapture(Var, /*isBlock*/false, ByRef, RefersToEnclosingLocal, Loc, + RSI->addCapture(Var, /*isBlock*/false, ByRef, RefersToCapturedVariable, Loc, SourceLocation(), CaptureType, CopyExpr); @@ -11851,7 +12018,7 @@ static ExprResult addAsFieldToClosureType(Sema &S, VarDecl *Var, QualType FieldType, QualType DeclRefType, SourceLocation Loc, - bool RefersToEnclosingLocal) { + bool RefersToCapturedVariable) { CXXRecordDecl *Lambda = LSI->Lambda; // Build the non-static data member. @@ -11880,7 +12047,7 @@ static ExprResult addAsFieldToClosureType(Sema &S, // C++ [expr.prim.labda]p12: // An entity captured by a lambda-expression is odr-used (3.2) in // the scope containing the lambda-expression. - Expr *Ref = new (S.Context) DeclRefExpr(Var, RefersToEnclosingLocal, + Expr *Ref = new (S.Context) DeclRefExpr(Var, RefersToCapturedVariable, DeclRefType, VK_LValue, Loc); Var->setReferenced(true); Var->markUsed(S.Context); @@ -11974,7 +12141,7 @@ static bool captureInLambda(LambdaScopeInfo *LSI, const bool BuildAndDiagnose, QualType &CaptureType, QualType &DeclRefType, - const bool RefersToEnclosingLocal, + const bool RefersToCapturedVariable, const Sema::TryCaptureKind Kind, SourceLocation EllipsisLoc, const bool IsTopScope, @@ -12048,7 +12215,7 @@ static bool captureInLambda(LambdaScopeInfo *LSI, if (BuildAndDiagnose) { ExprResult Result = addAsFieldToClosureType(S, LSI, Var, CaptureType, DeclRefType, Loc, - RefersToEnclosingLocal); + RefersToCapturedVariable); if (!Result.isInvalid()) CopyExpr = Result.get(); } @@ -12069,20 +12236,19 @@ static bool captureInLambda(LambdaScopeInfo *LSI, // Add the capture. if (BuildAndDiagnose) - LSI->addCapture(Var, /*IsBlock=*/false, ByRef, RefersToEnclosingLocal, + LSI->addCapture(Var, /*IsBlock=*/false, ByRef, RefersToCapturedVariable, Loc, EllipsisLoc, CaptureType, CopyExpr); return true; } - bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation ExprLoc, TryCaptureKind Kind, SourceLocation EllipsisLoc, bool BuildAndDiagnose, QualType &CaptureType, QualType &DeclRefType, const unsigned *const FunctionScopeIndexToStopAt) { - bool Nested = false; + bool Nested = Var->isInitCapture(); DeclContext *DC = CurContext; const unsigned MaxFunctionScopesIndex = FunctionScopeIndexToStopAt @@ -12100,8 +12266,13 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation ExprLoc, // If the variable is declared in the current context (and is not an // init-capture), there is no need to capture it. - if (!Var->isInitCapture() && Var->getDeclContext() == DC) return true; - if (!Var->hasLocalStorage()) return true; + if (!Nested && Var->getDeclContext() == DC) return true; + + // Capture global variables if it is required to use private copy of this + // variable. + bool IsGlobal = !Var->hasLocalStorage(); + if (IsGlobal && !(LangOpts.OpenMP && IsOpenMPCapturedVar(Var))) + return true; // Walk up the stack to determine whether we can capture the variable, // performing the "simple" checks that don't depend on type. We stop when @@ -12122,8 +12293,17 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation ExprLoc, ExprLoc, BuildAndDiagnose, *this); - if (!ParentDC) return true; - + // We need to check for the parent *first* because, if we *have* + // private-captured a global variable, we need to recursively capture it in + // intermediate blocks, lambdas, etc. + if (!ParentDC) { + if (IsGlobal) { + FunctionScopesIndex = MaxFunctionScopesIndex - 1; + break; + } + return true; + } + FunctionScopeInfo *FSI = FunctionScopes[FunctionScopesIndex]; CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FSI); @@ -12212,14 +12392,37 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation ExprLoc, break; case Type::VariableArray: { // Losing element qualification here is fine. - const VariableArrayType *Vat = cast<VariableArrayType>(Ty); + const VariableArrayType *VAT = cast<VariableArrayType>(Ty); // Unknown size indication requires no size computation. // Otherwise, evaluate and record it. - if (Expr *Size = Vat->getSizeExpr()) { - MarkDeclarationsReferencedInExpr(Size); + if (auto Size = VAT->getSizeExpr()) { + if (!CSI->isVLATypeCaptured(VAT)) { + RecordDecl *CapRecord = nullptr; + if (auto LSI = dyn_cast<LambdaScopeInfo>(CSI)) { + CapRecord = LSI->Lambda; + } else if (auto CRSI = dyn_cast<CapturedRegionScopeInfo>(CSI)) { + CapRecord = CRSI->TheRecordDecl; + } + if (CapRecord) { + auto ExprLoc = Size->getExprLoc(); + auto SizeType = Context.getSizeType(); + // Build the non-static data member. + auto Field = FieldDecl::Create( + Context, CapRecord, ExprLoc, ExprLoc, + /*Id*/ nullptr, SizeType, /*TInfo*/ nullptr, + /*BW*/ nullptr, /*Mutable*/ false, + /*InitStyle*/ ICIS_NoInit); + Field->setImplicit(true); + Field->setAccess(AS_private); + Field->setCapturedVLAType(VAT); + CapRecord->addDecl(Field); + + CSI->addVLATypeCapture(ExprLoc, SizeType); + } + } } - QTy = Vat->getElementType(); + QTy = VAT->getElementType(); break; } case Type::FunctionProto: @@ -12326,6 +12529,14 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc, DeclRefType, nullptr); } +bool Sema::NeedToCaptureVariable(VarDecl *Var, SourceLocation Loc) { + QualType CaptureType; + QualType DeclRefType; + return !tryCaptureVariable(Var, Loc, TryCapture_Implicit, SourceLocation(), + /*BuildAndDiagnose=*/false, CaptureType, + DeclRefType, nullptr); +} + QualType Sema::getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc) { QualType CaptureType; QualType DeclRefType; @@ -12388,6 +12599,8 @@ void Sema::UpdateMarkingForLValueToRValue(Expr *E) { } ExprResult Sema::ActOnConstantExpression(ExprResult Res) { + Res = CorrectDelayedTyposInExpr(Res); + if (!Res.isUsable()) return Res; @@ -12412,7 +12625,7 @@ void Sema::CleanupVarDeclMarking() { Var = cast<VarDecl>(ME->getMemberDecl()); Loc = ME->getMemberLoc(); } else { - llvm_unreachable("Unexpcted expression"); + llvm_unreachable("Unexpected expression"); } MarkVarDeclODRUsed(Var, Loc, *this, @@ -12429,6 +12642,9 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc, "Invalid Expr argument to DoMarkVarDeclReferenced"); Var->setReferenced(); + TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind(); + bool MarkODRUsed = true; + // If the context is not potentially evaluated, this is not an odr-use and // does not trigger instantiation. if (!IsPotentiallyEvaluatedContext(SemaRef)) { @@ -12443,25 +12659,29 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc, // arguments, where local variables can't be used. const bool RefersToEnclosingScope = (SemaRef.CurContext != Var->getDeclContext() && - Var->getDeclContext()->isFunctionOrMethod() && - Var->hasLocalStorage()); - if (!RefersToEnclosingScope) - return; - - if (LambdaScopeInfo *const LSI = SemaRef.getCurLambda()) { - // If a variable could potentially be odr-used, defer marking it so - // until we finish analyzing the full expression for any lvalue-to-rvalue - // or discarded value conversions that would obviate odr-use. - // Add it to the list of potential captures that will be analyzed - // later (ActOnFinishFullExpr) for eventual capture and odr-use marking - // unless the variable is a reference that was initialized by a constant - // expression (this will never need to be captured or odr-used). - assert(E && "Capture variable should be used in an expression."); - if (!Var->getType()->isReferenceType() || - !IsVariableNonDependentAndAConstantExpression(Var, SemaRef.Context)) - LSI->addPotentialCapture(E->IgnoreParens()); + Var->getDeclContext()->isFunctionOrMethod() && Var->hasLocalStorage()); + if (RefersToEnclosingScope) { + if (LambdaScopeInfo *const LSI = SemaRef.getCurLambda()) { + // If a variable could potentially be odr-used, defer marking it so + // until we finish analyzing the full expression for any + // lvalue-to-rvalue + // or discarded value conversions that would obviate odr-use. + // Add it to the list of potential captures that will be analyzed + // later (ActOnFinishFullExpr) for eventual capture and odr-use marking + // unless the variable is a reference that was initialized by a constant + // expression (this will never need to be captured or odr-used). + assert(E && "Capture variable should be used in an expression."); + if (!Var->getType()->isReferenceType() || + !IsVariableNonDependentAndAConstantExpression(Var, SemaRef.Context)) + LSI->addPotentialCapture(E->IgnoreParens()); + } } - return; + + if (!isTemplateInstantiation(TSK)) + return; + + // Instantiate, but do not mark as odr-used, variable templates. + MarkODRUsed = false; } VarTemplateSpecializationDecl *VarSpec = @@ -12473,7 +12693,6 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc, // templates of class templates, and variable template specializations. Delay // instantiations of variable templates, except for those that could be used // in a constant expression. - TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind(); if (isTemplateInstantiation(TSK)) { bool TryInstantiating = TSK == TSK_ImplicitInstantiation; @@ -12513,6 +12732,8 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc, } } + 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 // it is an object, the lvalue-to-rvalue conversion (4.1) @@ -12555,6 +12776,10 @@ static void MarkExprReferenced(Sema &SemaRef, SourceLocation Loc, CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(ME->getMemberDecl()); if (!MD) return; + // Only attempt to devirtualize if this is truly a virtual call. + bool IsVirtualCall = MD->isVirtual() && !ME->hasQualifier(); + if (!IsVirtualCall) + return; const Expr *Base = ME->getBase(); const CXXRecordDecl *MostDerivedClassDecl = Base->getBestDynamicClassType(); if (!MostDerivedClassDecl) @@ -12602,14 +12827,14 @@ void Sema::MarkMemberReferenced(MemberExpr *E) { /// normal expression which refers to a variable. void Sema::MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse) { if (OdrUse) { - if (VarDecl *VD = dyn_cast<VarDecl>(D)) { + if (auto *VD = dyn_cast<VarDecl>(D)) { MarkVariableReferenced(Loc, VD); return; } - if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { - MarkFunctionReferenced(Loc, FD); - return; - } + } + if (auto *FD = dyn_cast<FunctionDecl>(D)) { + MarkFunctionReferenced(Loc, FD, OdrUse); + return; } D->setReferenced(); } @@ -12935,6 +13160,7 @@ ExprResult Sema::CheckBooleanCondition(Expr *E, SourceLocation Loc) { << T << E->getSourceRange(); return ExprError(); } + CheckBoolLikeConversion(E, Loc); } return E; @@ -13306,6 +13532,39 @@ ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *E, ValueDecl *VD) { << VD << E->getSourceRange(); return ExprError(); } + if (const FunctionProtoType *FT = Type->getAs<FunctionProtoType>()) { + // We must match the FunctionDecl's type to the hack introduced in + // RebuildUnknownAnyExpr::VisitCallExpr to vararg functions of unknown + // type. See the lengthy commentary in that routine. + QualType FDT = FD->getType(); + const FunctionType *FnType = FDT->castAs<FunctionType>(); + const FunctionProtoType *Proto = dyn_cast_or_null<FunctionProtoType>(FnType); + DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E); + if (DRE && Proto && Proto->getParamTypes().empty() && Proto->isVariadic()) { + SourceLocation Loc = FD->getLocation(); + FunctionDecl *NewFD = FunctionDecl::Create(FD->getASTContext(), + FD->getDeclContext(), + Loc, Loc, FD->getNameInfo().getName(), + DestType, FD->getTypeSourceInfo(), + SC_None, false/*isInlineSpecified*/, + FD->hasPrototype(), + false/*isConstexprSpecified*/); + + if (FD->getQualifier()) + NewFD->setQualifierInfo(FD->getQualifierLoc()); + + SmallVector<ParmVarDecl*, 16> Params; + for (const auto &AI : FT->param_types()) { + ParmVarDecl *Param = + S.BuildParmVarDeclForTypedef(FD, Loc, AI); + Param->setScopeInfo(0, Params.size()); + Params.push_back(Param); + } + NewFD->setParams(Params); + DRE->setDecl(NewFD); + VD = DRE->getDecl(); + } + } if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) if (MD->isInstance()) { @@ -13431,6 +13690,15 @@ static ExprResult diagnoseUnknownAnyExpr(Sema &S, Expr *E) { /// Check for operands with placeholder types and complain if found. /// Returns true if there was an error and no recovery was possible. ExprResult Sema::CheckPlaceholderExpr(Expr *E) { + if (!getLangOpts().CPlusPlus) { + // C cannot handle TypoExpr nodes on either side of a binop because it + // doesn't handle dependent types properly, so make sure any TypoExprs have + // been dealt with before checking the operands. + ExprResult Result = CorrectDelayedTyposInExpr(E); + if (!Result.isUsable()) return ExprError(); + E = Result.get(); + } + const BuiltinType *placeholderType = E->getType()->getAsPlaceholderType(); if (!placeholderType) return E; |