diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:04:05 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:04:05 +0000 |
commit | 676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63 (patch) | |
tree | 02a1ac369cb734d0abfa5000dd86e5b7797e6a74 /lib/Sema/SemaExpr.cpp | |
parent | c7e70c433efc6953dc3888b9fbf9f3512d7da2b0 (diff) | |
download | src-test2-676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63.tar.gz src-test2-676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63.zip |
Notes
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 1157 |
1 files changed, 749 insertions, 408 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 3dc6fb151cb7..d5416d4d057c 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -26,6 +26,7 @@ #include "clang/AST/ExprOpenMP.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/TypeLoc.h" +#include "clang/Basic/FixedPoint.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" @@ -65,6 +66,12 @@ bool Sema::CanUseDecl(NamedDecl *D, bool TreatUnavailableAsInvalid) { if (getLangOpts().CPlusPlus14 && FD->getReturnType()->isUndeducedType() && DeduceReturnType(FD, SourceLocation(), /*Diagnose*/ false)) return false; + + // See if this is an aligned allocation/deallocation function that is + // unavailable. + if (TreatUnavailableAsInvalid && + isUnavailableAlignedAllocationFunction(*FD)) + return false; } // See if this function is unavailable. @@ -114,7 +121,7 @@ void Sema::NoteDeletedFunction(FunctionDecl *Decl) { return NoteDeletedInheritingConstructor(Ctor); Diag(Decl->getLocation(), diag::note_availability_specified_here) - << Decl << true; + << Decl << 1; } /// Determine whether a FunctionDecl was ever declared with an @@ -205,7 +212,8 @@ void Sema::MaybeSuggestAddingStaticToDecl(const FunctionDecl *Cur) { bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs, const ObjCInterfaceDecl *UnknownObjCClass, bool ObjCPropertyAccess, - bool AvoidPartialAvailabilityChecks) { + bool AvoidPartialAvailabilityChecks, + ObjCInterfaceDecl *ClassReceiver) { SourceLocation Loc = Locs.front(); if (getLangOpts().CPlusPlus && isa<FunctionDecl>(D)) { // If there were any diagnostics suppressed by template argument deduction, @@ -226,6 +234,8 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs, // The function 'main' shall not be used within a program. if (cast<FunctionDecl>(D)->isMain()) Diag(Loc, diag::ext_main_used); + + diagnoseUnavailableAlignedAllocation(*cast<FunctionDecl>(D), Loc); } // See if this is an auto-typed variable whose initializer we are parsing. @@ -264,6 +274,17 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs, return true; } + if (auto *MD = dyn_cast<CXXMethodDecl>(D)) { + // Lambdas are only default-constructible or assignable in C++2a onwards. + if (MD->getParent()->isLambda() && + ((isa<CXXConstructorDecl>(MD) && + cast<CXXConstructorDecl>(MD)->isDefaultConstructor()) || + MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator())) { + Diag(Loc, diag::warn_cxx17_compat_lambda_def_ctor_assign) + << !isa<CXXConstructorDecl>(MD); + } + } + auto getReferencedObjCProp = [](const NamedDecl *D) -> const ObjCPropertyDecl * { if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) @@ -291,7 +312,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs, } DiagnoseAvailabilityOfDecl(D, Locs, UnknownObjCClass, ObjCPropertyAccess, - AvoidPartialAvailabilityChecks); + AvoidPartialAvailabilityChecks, ClassReceiver); DiagnoseUnusedOfDecl(*this, D, Loc); @@ -386,8 +407,7 @@ void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc, // 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 - = getLocForEndOfToken(sentinelExpr->getLocEnd()); + SourceLocation MissingNilLoc = getLocForEndOfToken(sentinelExpr->getEndLoc()); std::string NullValue; if (calleeType == CT_Method && PP.isMacroDefined("nil")) NullValue = "nil"; @@ -501,12 +521,13 @@ static void DiagnoseDirectIsaAccess(Sema &S, const ObjCIvarRefExpr *OIRE, &S.Context.Idents.get("object_setClass"), SourceLocation(), S.LookupOrdinaryName); if (ObjectSetClass) { - SourceLocation RHSLocEnd = S.getLocForEndOfToken(RHS->getLocEnd()); - S.Diag(OIRE->getExprLoc(), diag::warn_objc_isa_assign) << - FixItHint::CreateInsertion(OIRE->getLocStart(), "object_setClass(") << - FixItHint::CreateReplacement(SourceRange(OIRE->getOpLoc(), - AssignLoc), ",") << - FixItHint::CreateInsertion(RHSLocEnd, ")"); + SourceLocation RHSLocEnd = S.getLocForEndOfToken(RHS->getEndLoc()); + S.Diag(OIRE->getExprLoc(), diag::warn_objc_isa_assign) + << FixItHint::CreateInsertion(OIRE->getBeginLoc(), + "object_setClass(") + << FixItHint::CreateReplacement( + SourceRange(OIRE->getOpLoc(), AssignLoc), ",") + << FixItHint::CreateInsertion(RHSLocEnd, ")"); } else S.Diag(OIRE->getLocation(), diag::warn_objc_isa_assign); @@ -516,11 +537,11 @@ static void DiagnoseDirectIsaAccess(Sema &S, const ObjCIvarRefExpr *OIRE, &S.Context.Idents.get("object_getClass"), SourceLocation(), S.LookupOrdinaryName); if (ObjectGetClass) - S.Diag(OIRE->getExprLoc(), diag::warn_objc_isa_use) << - FixItHint::CreateInsertion(OIRE->getLocStart(), "object_getClass(") << - FixItHint::CreateReplacement( - SourceRange(OIRE->getOpLoc(), - OIRE->getLocEnd()), ")"); + S.Diag(OIRE->getExprLoc(), diag::warn_objc_isa_use) + << FixItHint::CreateInsertion(OIRE->getBeginLoc(), + "object_getClass(") + << FixItHint::CreateReplacement( + SourceRange(OIRE->getOpLoc(), OIRE->getEndLoc()), ")"); else S.Diag(OIRE->getLocation(), diag::warn_objc_isa_use); } @@ -575,10 +596,10 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) { &Context.Idents.get("object_getClass"), SourceLocation(), LookupOrdinaryName); if (ObjectGetClass) - Diag(E->getExprLoc(), diag::warn_objc_isa_use) << - FixItHint::CreateInsertion(OISA->getLocStart(), "object_getClass(") << - FixItHint::CreateReplacement( - SourceRange(OISA->getOpLoc(), OISA->getIsaMemberLoc()), ")"); + Diag(E->getExprLoc(), diag::warn_objc_isa_use) + << FixItHint::CreateInsertion(OISA->getBeginLoc(), "object_getClass(") + << FixItHint::CreateReplacement( + SourceRange(OISA->getOpLoc(), OISA->getIsaMemberLoc()), ")"); else Diag(E->getExprLoc(), diag::warn_objc_isa_use); } @@ -717,20 +738,33 @@ ExprResult Sema::DefaultArgumentPromotion(Expr *E) { return ExprError(); E = Res.get(); + QualType ScalarTy = Ty; + unsigned NumElts = 0; + if (const ExtVectorType *VecTy = Ty->getAs<ExtVectorType>()) { + NumElts = VecTy->getNumElements(); + ScalarTy = VecTy->getElementType(); + } + // If this is a 'float' or '__fp16' (CVR qualified or typedef) // promote to double. // Note that default argument promotion applies only to float (and // half/fp16); it does not apply to _Float16. - const BuiltinType *BTy = Ty->getAs<BuiltinType>(); + const BuiltinType *BTy = ScalarTy->getAs<BuiltinType>(); if (BTy && (BTy->getKind() == BuiltinType::Half || BTy->getKind() == BuiltinType::Float)) { if (getLangOpts().OpenCL && !getOpenCLOptions().isEnabled("cl_khr_fp64")) { - if (BTy->getKind() == BuiltinType::Half) { - E = ImpCastExprToType(E, Context.FloatTy, CK_FloatingCast).get(); - } + if (BTy->getKind() == BuiltinType::Half) { + QualType Ty = Context.FloatTy; + if (NumElts != 0) + Ty = Context.getExtVectorType(Ty, NumElts); + E = ImpCastExprToType(E, Ty, CK_FloatingCast).get(); + } } else { - E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).get(); + QualType Ty = Context.DoubleTy; + if (NumElts != 0) + Ty = Context.getExtVectorType(Ty, NumElts); + E = ImpCastExprToType(E, Ty, CK_FloatingCast).get(); } } @@ -819,40 +853,38 @@ void Sema::checkVariadicArgument(const Expr *E, VariadicCallType CT) { switch (VAK) { case VAK_ValidInCXX11: DiagRuntimeBehavior( - E->getLocStart(), nullptr, - PDiag(diag::warn_cxx98_compat_pass_non_pod_arg_to_vararg) - << Ty << CT); + E->getBeginLoc(), nullptr, + PDiag(diag::warn_cxx98_compat_pass_non_pod_arg_to_vararg) << Ty << CT); LLVM_FALLTHROUGH; case VAK_Valid: if (Ty->isRecordType()) { // This is unlikely to be what the user intended. If the class has a // 'c_str' member function, the user probably meant to call that. - DiagRuntimeBehavior(E->getLocStart(), nullptr, + DiagRuntimeBehavior(E->getBeginLoc(), nullptr, PDiag(diag::warn_pass_class_arg_to_vararg) - << Ty << CT << hasCStrMethod(E) << ".c_str()"); + << Ty << CT << hasCStrMethod(E) << ".c_str()"); } break; case VAK_Undefined: case VAK_MSVCUndefined: - DiagRuntimeBehavior( - E->getLocStart(), nullptr, - PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg) - << getLangOpts().CPlusPlus11 << Ty << CT); + DiagRuntimeBehavior(E->getBeginLoc(), nullptr, + PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg) + << getLangOpts().CPlusPlus11 << Ty << CT); break; case VAK_Invalid: if (Ty.isDestructedType() == QualType::DK_nontrivial_c_struct) - Diag(E->getLocStart(), - diag::err_cannot_pass_non_trivial_c_struct_to_vararg) << Ty << CT; + Diag(E->getBeginLoc(), + diag::err_cannot_pass_non_trivial_c_struct_to_vararg) + << Ty << CT; else if (Ty->isObjCObjectType()) - DiagRuntimeBehavior( - E->getLocStart(), nullptr, - PDiag(diag::err_cannot_pass_objc_interface_to_vararg) - << Ty << CT); + DiagRuntimeBehavior(E->getBeginLoc(), nullptr, + PDiag(diag::err_cannot_pass_objc_interface_to_vararg) + << Ty << CT); else - Diag(E->getLocStart(), diag::err_cannot_pass_to_vararg) - << isa<InitListExpr>(E) << Ty << CT; + Diag(E->getBeginLoc(), diag::err_cannot_pass_to_vararg) + << isa<InitListExpr>(E) << Ty << CT; break; } } @@ -890,20 +922,19 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, SourceLocation TemplateKWLoc; UnqualifiedId Name; Name.setIdentifier(PP.getIdentifierInfo("__builtin_trap"), - E->getLocStart()); + E->getBeginLoc()); ExprResult TrapFn = ActOnIdExpression(TUScope, SS, TemplateKWLoc, Name, true, false); if (TrapFn.isInvalid()) return ExprError(); - ExprResult Call = ActOnCallExpr(TUScope, TrapFn.get(), - E->getLocStart(), None, - E->getLocEnd()); + ExprResult Call = ActOnCallExpr(TUScope, TrapFn.get(), E->getBeginLoc(), + None, E->getEndLoc()); if (Call.isInvalid()) return ExprError(); - ExprResult Comma = ActOnBinOp(TUScope, E->getLocStart(), tok::comma, - Call.get(), E); + ExprResult Comma = + ActOnBinOp(TUScope, E->getBeginLoc(), tok::comma, Call.get(), E); if (Comma.isInvalid()) return ExprError(); return Comma.get(); @@ -1436,9 +1467,9 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc, // We strip parens here because the controlling expression is typically // parenthesized in macro definitions. ControllingExpr = ControllingExpr->IgnoreParens(); - Diag(ControllingExpr->getLocStart(), diag::err_generic_sel_multi_match) - << ControllingExpr->getSourceRange() << ControllingExpr->getType() - << (unsigned) CompatIndices.size(); + Diag(ControllingExpr->getBeginLoc(), diag::err_generic_sel_multi_match) + << ControllingExpr->getSourceRange() << ControllingExpr->getType() + << (unsigned)CompatIndices.size(); for (unsigned I : CompatIndices) { Diag(Types[I]->getTypeLoc().getBeginLoc(), diag::note_compat_assoc) @@ -1455,8 +1486,8 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc, // We strip parens here because the controlling expression is typically // parenthesized in macro definitions. ControllingExpr = ControllingExpr->IgnoreParens(); - Diag(ControllingExpr->getLocStart(), diag::err_generic_sel_no_match) - << ControllingExpr->getSourceRange() << ControllingExpr->getType(); + Diag(ControllingExpr->getBeginLoc(), diag::err_generic_sel_no_match) + << ControllingExpr->getSourceRange() << ControllingExpr->getType(); return ExprError(); } @@ -1549,6 +1580,32 @@ Sema::ActOnStringLiteral(ArrayRef<Token> StringToks, Scope *UDLScope) { CharTy = Context.UnsignedCharTy; } + // Warn on initializing an array of char from a u8 string literal; this + // becomes ill-formed in C++2a. + if (getLangOpts().CPlusPlus && !getLangOpts().CPlusPlus2a && + !getLangOpts().Char8 && Kind == StringLiteral::UTF8) { + Diag(StringTokLocs.front(), diag::warn_cxx2a_compat_utf8_string); + + // Create removals for all 'u8' prefixes in the string literal(s). This + // ensures C++2a compatibility (but may change the program behavior when + // built by non-Clang compilers for which the execution character set is + // not always UTF-8). + auto RemovalDiag = PDiag(diag::note_cxx2a_compat_utf8_string_remove_u8); + SourceLocation RemovalDiagLoc; + for (const Token &Tok : StringToks) { + if (Tok.getKind() == tok::utf8_string_literal) { + if (RemovalDiagLoc.isInvalid()) + RemovalDiagLoc = Tok.getLocation(); + RemovalDiag << FixItHint::CreateRemoval(CharSourceRange::getCharRange( + Tok.getLocation(), + Lexer::AdvanceToTokenCharacter(Tok.getLocation(), 2, + getSourceManager(), getLangOpts()))); + } + } + Diag(RemovalDiagLoc, RemovalDiag); + } + + QualType CharTyConst = CharTy; // A C++ string literal has a const-qualified element type (C++ 2.13.4p1). if (getLangOpts().CPlusPlus || getLangOpts().ConstStrings) @@ -1681,7 +1738,7 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, if (getLangOpts().ObjCWeak && isa<VarDecl>(D) && Ty.getObjCLifetime() == Qualifiers::OCL_Weak && !isUnevaluatedContext() && - !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, E->getLocStart())) + !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, E->getBeginLoc())) getCurFunction()->recordUseOfWeak(E); FieldDecl *FD = dyn_cast<FieldDecl>(D); @@ -2528,7 +2585,7 @@ Sema::PerformObjectMemberConversion(Expr *From, if (Method->isStatic()) return From; - DestType = Method->getThisType(Context); + DestType = Method->getThisType(); DestRecordType = DestType->getPointeeType(); if (FromType->getAs<PointerType>()) { @@ -3026,7 +3083,7 @@ static void ConvertUTF8ToWideString(unsigned CharByteWidth, StringRef Source, } ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc, - PredefinedExpr::IdentType IT) { + PredefinedExpr::IdentKind IK) { // Pick the current block, lambda, captured statement or function. Decl *currentDecl = nullptr; if (const BlockScopeInfo *BSI = getCurBlock()) @@ -3050,11 +3107,11 @@ ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc, else { // Pre-defined identifiers are of type char[x], where x is the length of // the string. - auto Str = PredefinedExpr::ComputeName(IT, currentDecl); + auto Str = PredefinedExpr::ComputeName(IK, currentDecl); unsigned Length = Str.length(); llvm::APInt LengthI(32, Length + 1); - if (IT == PredefinedExpr::LFunction || IT == PredefinedExpr::LFuncSig) { + if (IK == PredefinedExpr::LFunction || IK == PredefinedExpr::LFuncSig) { ResTy = Context.adjustStringLiteralBaseType(Context.WideCharTy.withConst()); SmallString<32> RawChars; @@ -3073,24 +3130,24 @@ ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc, } } - return new (Context) PredefinedExpr(Loc, ResTy, IT, SL); + return PredefinedExpr::Create(Context, Loc, ResTy, IK, SL); } ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) { - PredefinedExpr::IdentType IT; + PredefinedExpr::IdentKind IK; switch (Kind) { default: llvm_unreachable("Unknown simple primary expr!"); - case tok::kw___func__: IT = PredefinedExpr::Func; break; // [C99 6.4.2.2] - case tok::kw___FUNCTION__: IT = PredefinedExpr::Function; break; - case tok::kw___FUNCDNAME__: IT = PredefinedExpr::FuncDName; break; // [MS] - case tok::kw___FUNCSIG__: IT = PredefinedExpr::FuncSig; break; // [MS] - case tok::kw_L__FUNCTION__: IT = PredefinedExpr::LFunction; break; // [MS] - case tok::kw_L__FUNCSIG__: IT = PredefinedExpr::LFuncSig; break; // [MS] - case tok::kw___PRETTY_FUNCTION__: IT = PredefinedExpr::PrettyFunction; break; + case tok::kw___func__: IK = PredefinedExpr::Func; break; // [C99 6.4.2.2] + case tok::kw___FUNCTION__: IK = PredefinedExpr::Function; break; + case tok::kw___FUNCDNAME__: IK = PredefinedExpr::FuncDName; break; // [MS] + case tok::kw___FUNCSIG__: IK = PredefinedExpr::FuncSig; break; // [MS] + case tok::kw_L__FUNCTION__: IK = PredefinedExpr::LFunction; break; // [MS] + case tok::kw_L__FUNCSIG__: IK = PredefinedExpr::LFuncSig; break; // [MS] + case tok::kw___PRETTY_FUNCTION__: IK = PredefinedExpr::PrettyFunction; break; } - return BuildPredefinedExpr(Loc, IT); + return BuildPredefinedExpr(Loc, IK); } ExprResult Sema::ActOnCharacterConstant(const Token &Tok, Scope *UDLScope) { @@ -3363,16 +3420,14 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { bool isSigned = !Literal.isUnsigned; unsigned scale = Context.getFixedPointScale(Ty); - unsigned ibits = Context.getFixedPointIBits(Ty); unsigned bit_width = Context.getTypeInfo(Ty).Width; llvm::APInt Val(bit_width, 0, isSigned); bool Overflowed = Literal.GetFixedPointValue(Val, scale); + bool ValIsZero = Val.isNullValue() && !Overflowed; - // Do not use bit_width since some types may have padding like _Fract or - // unsigned _Accums if PaddingOnUnsignedFixedPoint is set. - auto MaxVal = llvm::APInt::getMaxValue(ibits + scale).zextOrSelf(bit_width); - if (Literal.isFract && Val == MaxVal + 1) + auto MaxVal = Context.getFixedPointMax(Ty).getValue(); + if (Literal.isFract && Val == MaxVal + 1 && !ValIsZero) // Clause 6.4.4 - The value of a constant shall be in the range of // representable values for its type, with exception for constants of a // fract type with a value of exactly 1; such a constant shall denote @@ -3588,7 +3643,8 @@ static bool CheckExtensionTraitOperandType(Sema &S, QualType T, // C99 6.5.3.4p1: if (T->isFunctionType() && - (TraitKind == UETT_SizeOf || TraitKind == UETT_AlignOf)) { + (TraitKind == UETT_SizeOf || TraitKind == UETT_AlignOf || + TraitKind == UETT_PreferredAlignOf)) { // sizeof(function)/alignof(function) is allowed as an extension. S.Diag(Loc, diag::ext_sizeof_alignof_function_type) << TraitKind << ArgRange; @@ -3666,7 +3722,7 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(Expr *E, // the expression to be complete. 'sizeof' requires the expression's type to // be complete (and will attempt to complete it if it's an array of unknown // bound). - if (ExprKind == UETT_AlignOf) { + if (ExprKind == UETT_AlignOf || ExprKind == UETT_PreferredAlignOf) { if (RequireCompleteType(E->getExprLoc(), Context.getBaseElementType(E->getType()), diag::err_sizeof_alignof_incomplete_type, ExprKind, @@ -3690,7 +3746,8 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(Expr *E, // 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) && + if ((ExprKind == UETT_SizeOf || ExprKind == UETT_AlignOf || + ExprKind == UETT_PreferredAlignOf) && !inTemplateInstantiation() && E->HasSideEffects(Context, false)) Diag(E->getExprLoc(), diag::warn_side_effects_unevaluated_context); @@ -3759,7 +3816,8 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(QualType ExprType, // C11 6.5.3.4/3, C++11 [expr.alignof]p3: // When alignof or _Alignof is applied to an array type, the result // is the alignment of the element type. - if (ExprKind == UETT_AlignOf || ExprKind == UETT_OpenMPRequiredSimdAlign) + if (ExprKind == UETT_AlignOf || ExprKind == UETT_PreferredAlignOf || + ExprKind == UETT_OpenMPRequiredSimdAlign) ExprType = Context.getBaseElementType(ExprType); if (ExprKind == UETT_VecStep) @@ -3788,7 +3846,7 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(QualType ExprType, return false; } -static bool CheckAlignOfExpr(Sema &S, Expr *E) { +static bool CheckAlignOfExpr(Sema &S, Expr *E, UnaryExprOrTypeTrait ExprKind) { E = E->IgnoreParens(); // Cannot know anything else if the expression is dependent. @@ -3842,7 +3900,7 @@ static bool CheckAlignOfExpr(Sema &S, Expr *E) { return false; } - return S.CheckUnaryExprOrTypeTraitOperand(E, UETT_AlignOf); + return S.CheckUnaryExprOrTypeTraitOperand(E, ExprKind); } bool Sema::CheckVecStepExpr(Expr *E) { @@ -4038,8 +4096,8 @@ Sema::CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc, bool isInvalid = false; if (E->isTypeDependent()) { // Delay type-checking for type-dependent expressions. - } else if (ExprKind == UETT_AlignOf) { - isInvalid = CheckAlignOfExpr(*this, E); + } else if (ExprKind == UETT_AlignOf || ExprKind == UETT_PreferredAlignOf) { + isInvalid = CheckAlignOfExpr(*this, E, ExprKind); } else if (ExprKind == UETT_VecStep) { isInvalid = CheckVecStepExpr(E); } else if (ExprKind == UETT_OpenMPRequiredSimdAlign) { @@ -4238,7 +4296,57 @@ Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc, return CreateOverloadedArraySubscriptExpr(lbLoc, rbLoc, base, idx); } - return CreateBuiltinArraySubscriptExpr(base, lbLoc, idx, rbLoc); + ExprResult Res = CreateBuiltinArraySubscriptExpr(base, lbLoc, idx, rbLoc); + + if (!Res.isInvalid() && isa<ArraySubscriptExpr>(Res.get())) + CheckSubscriptAccessOfNoDeref(cast<ArraySubscriptExpr>(Res.get())); + + return Res; +} + +void Sema::CheckAddressOfNoDeref(const Expr *E) { + ExpressionEvaluationContextRecord &LastRecord = ExprEvalContexts.back(); + const Expr *StrippedExpr = E->IgnoreParenImpCasts(); + + // For expressions like `&(*s).b`, the base is recorded and what should be + // checked. + const MemberExpr *Member = nullptr; + while ((Member = dyn_cast<MemberExpr>(StrippedExpr)) && !Member->isArrow()) + StrippedExpr = Member->getBase()->IgnoreParenImpCasts(); + + LastRecord.PossibleDerefs.erase(StrippedExpr); +} + +void Sema::CheckSubscriptAccessOfNoDeref(const ArraySubscriptExpr *E) { + QualType ResultTy = E->getType(); + ExpressionEvaluationContextRecord &LastRecord = ExprEvalContexts.back(); + + // Bail if the element is an array since it is not memory access. + if (isa<ArrayType>(ResultTy)) + return; + + if (ResultTy->hasAttr(attr::NoDeref)) { + LastRecord.PossibleDerefs.insert(E); + return; + } + + // Check if the base type is a pointer to a member access of a struct + // marked with noderef. + const Expr *Base = E->getBase(); + QualType BaseTy = Base->getType(); + if (!(isa<ArrayType>(BaseTy) || isa<PointerType>(BaseTy))) + // Not a pointer access + return; + + const MemberExpr *Member = nullptr; + while ((Member = dyn_cast<MemberExpr>(Base->IgnoreParenCasts())) && + Member->isArrow()) + Base = Member->getBase(); + + if (const auto *Ptr = dyn_cast<PointerType>(Base->getType())) { + if (Ptr->getPointeeType()->hasAttr(attr::NoDeref)) + LastRecord.PossibleDerefs.insert(E); + } } ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, @@ -4339,10 +4447,11 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, return ExprError(); if (LowerBound && !OriginalTy->isAnyPointerType()) { - llvm::APSInt LowerBoundValue; - if (LowerBound->EvaluateAsInt(LowerBoundValue, Context)) { + Expr::EvalResult Result; + if (LowerBound->EvaluateAsInt(Result, Context)) { // OpenMP 4.5, [2.4 Array Sections] // The array section must be a subset of the original array. + llvm::APSInt LowerBoundValue = Result.Val.getInt(); if (LowerBoundValue.isNegative()) { Diag(LowerBound->getExprLoc(), diag::err_omp_section_not_subset_of_array) << LowerBound->getSourceRange(); @@ -4352,10 +4461,11 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, } if (Length) { - llvm::APSInt LengthValue; - if (Length->EvaluateAsInt(LengthValue, Context)) { + Expr::EvalResult Result; + if (Length->EvaluateAsInt(Result, Context)) { // OpenMP 4.5, [2.4 Array Sections] // The length must evaluate to non-negative integers. + llvm::APSInt LengthValue = Result.Val.getInt(); if (LengthValue.isNegative()) { Diag(Length->getExprLoc(), diag::err_omp_section_length_negative) << LengthValue.toString(/*Radix=*/10, /*Signed=*/true) @@ -4488,8 +4598,8 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, // wasn't promoted because of the C90 rule that doesn't // allow promoting non-lvalue arrays. Warn, then // force the promotion here. - Diag(LHSExp->getLocStart(), diag::ext_subscript_non_lvalue) << - LHSExp->getSourceRange(); + Diag(LHSExp->getBeginLoc(), diag::ext_subscript_non_lvalue) + << LHSExp->getSourceRange(); LHSExp = ImpCastExprToType(LHSExp, Context.getArrayDecayedType(LHSTy), CK_ArrayToPointerDecay).get(); LHSTy = LHSExp->getType(); @@ -4499,8 +4609,8 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, ResultType = LHSTy->getAs<PointerType>()->getPointeeType(); } else if (RHSTy->isArrayType()) { // Same as previous, except for 123[f().a] case - Diag(RHSExp->getLocStart(), diag::ext_subscript_non_lvalue) << - RHSExp->getSourceRange(); + Diag(RHSExp->getBeginLoc(), diag::ext_subscript_non_lvalue) + << RHSExp->getSourceRange(); RHSExp = ImpCastExprToType(RHSExp, Context.getArrayDecayedType(RHSTy), CK_ArrayToPointerDecay).get(); RHSTy = RHSExp->getType(); @@ -4527,8 +4637,8 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, // type. Note that Functions are not objects, and that (in C99 parlance) // incomplete types are not object types. if (ResultType->isFunctionType()) { - Diag(BaseExpr->getLocStart(), diag::err_subscript_function_type) - << ResultType << BaseExpr->getSourceRange(); + Diag(BaseExpr->getBeginLoc(), diag::err_subscript_function_type) + << ResultType << BaseExpr->getSourceRange(); return ExprError(); } @@ -4594,7 +4704,7 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD, if (Inst.isInvalid()) return true; if (Inst.isAlreadyInstantiating()) { - Diag(Param->getLocStart(), diag::err_recursive_default_argument) << FD; + Diag(Param->getBeginLoc(), diag::err_recursive_default_argument) << FD; Param->setInvalidDecl(); return true; } @@ -4616,9 +4726,9 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD, // Check the expression as an initializer for the parameter. InitializedEntity Entity = InitializedEntity::InitializeParameter(Context, Param); - InitializationKind Kind - = InitializationKind::CreateCopy(Param->getLocation(), - /*FIXME:EqualLoc*/UninstExpr->getLocStart()); + InitializationKind Kind = InitializationKind::CreateCopy( + Param->getLocation(), + /*FIXME:EqualLoc*/ UninstExpr->getBeginLoc()); Expr *ResultE = Result.getAs<Expr>(); InitializationSequence InitSeq(*this, Entity, Kind, ResultE); @@ -4626,8 +4736,9 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD, if (Result.isInvalid()) return true; - Result = ActOnFinishFullExpr(Result.getAs<Expr>(), - Param->getOuterLocStart()); + Result = + ActOnFinishFullExpr(Result.getAs<Expr>(), Param->getOuterLocStart(), + /*DiscardedValue*/ false); if (Result.isInvalid()) return true; @@ -4640,7 +4751,7 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD, // 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; + Diag(Param->getBeginLoc(), diag::err_recursive_default_argument) << FD; Param->setInvalidDecl(); return true; } @@ -4725,7 +4836,7 @@ static TypoCorrection TryTypoCorrectionForCall(Sema &S, Expr *Fn, ArrayRef<Expr *> Args) { MemberExpr *ME = dyn_cast<MemberExpr>(Fn); DeclarationName FuncName = FDecl->getDeclName(); - SourceLocation NameLoc = ME ? ME->getMemberLoc() : Fn->getLocStart(); + SourceLocation NameLoc = ME ? ME->getMemberLoc() : Fn->getBeginLoc(); if (TypoCorrection Corrected = S.CorrectTypo( DeclarationNameInfo(FuncName, NameLoc), Sema::LookupOrdinaryName, @@ -4816,12 +4927,14 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, // Emit the location of the prototype. if (!TC && FDecl && !FDecl->getBuiltinID() && !IsExecConfig) - Diag(FDecl->getLocStart(), diag::note_callee_decl) - << FDecl; + Diag(FDecl->getBeginLoc(), diag::note_callee_decl) << FDecl; return true; } - Call->setNumArgs(Context, NumParams); + // We reserve space for the default arguments when we create + // the call expression, before calling ConvertArgumentsForCall. + assert((Call->getNumArgs() == NumParams) && + "We should have reserved space for the default arguments before!"); } // If too many are passed and not variadic, error on the extras and drop @@ -4839,39 +4952,38 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, << TC.getCorrectionRange()); } else if (NumParams == 1 && FDecl && FDecl->getParamDecl(0)->getDeclName()) - Diag(Args[NumParams]->getLocStart(), + Diag(Args[NumParams]->getBeginLoc(), MinArgs == NumParams ? diag::err_typecheck_call_too_many_args_one : diag::err_typecheck_call_too_many_args_at_most_one) << FnKind << FDecl->getParamDecl(0) << static_cast<unsigned>(Args.size()) << Fn->getSourceRange() - << SourceRange(Args[NumParams]->getLocStart(), - Args.back()->getLocEnd()); + << SourceRange(Args[NumParams]->getBeginLoc(), + Args.back()->getEndLoc()); else - Diag(Args[NumParams]->getLocStart(), + Diag(Args[NumParams]->getBeginLoc(), MinArgs == NumParams ? diag::err_typecheck_call_too_many_args : diag::err_typecheck_call_too_many_args_at_most) << FnKind << NumParams << static_cast<unsigned>(Args.size()) << Fn->getSourceRange() - << SourceRange(Args[NumParams]->getLocStart(), - Args.back()->getLocEnd()); + << SourceRange(Args[NumParams]->getBeginLoc(), + Args.back()->getEndLoc()); // Emit the location of the prototype. if (!TC && FDecl && !FDecl->getBuiltinID() && !IsExecConfig) - Diag(FDecl->getLocStart(), diag::note_callee_decl) - << FDecl; + Diag(FDecl->getBeginLoc(), diag::note_callee_decl) << FDecl; // This deletes the extra arguments. - Call->setNumArgs(Context, NumParams); + Call->shrinkNumArgs(NumParams); return true; } } SmallVector<Expr *, 8> AllArgs; VariadicCallType CallType = getVariadicCallType(FDecl, Proto, Fn); - Invalid = GatherArgumentsForCall(Call->getLocStart(), FDecl, - Proto, 0, Args, AllArgs, CallType); + Invalid = GatherArgumentsForCall(Call->getBeginLoc(), FDecl, Proto, 0, Args, + AllArgs, CallType); if (Invalid) return true; unsigned TotalNumArgs = AllArgs.size(); @@ -4899,8 +5011,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl, if (ArgIx < Args.size()) { Arg = Args[ArgIx++]; - if (RequireCompleteType(Arg->getLocStart(), - ProtoArgType, + if (RequireCompleteType(Arg->getBeginLoc(), ProtoArgType, diag::err_call_incomplete_argument, Arg)) return true; @@ -5058,6 +5169,9 @@ static bool isPlaceholderToRemoveAsArg(QualType type) { #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ case BuiltinType::Id: #include "clang/Basic/OpenCLImageTypes.def" +#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ + case BuiltinType::Id: +#include "clang/Basic/OpenCLExtensionTypes.def" #define PLACEHOLDER_TYPE(ID, SINGLETON_ID) #define BUILTIN_TYPE(ID, SINGLETON_ID) case BuiltinType::ID: #include "clang/AST/BuiltinTypes.def" @@ -5153,10 +5267,13 @@ static FunctionDecl *rewriteBuiltinFunctionDecl(Sema *Sema, ASTContext &Context, continue; } + QualType PointeeType = ParamType->getPointeeType(); + if (PointeeType.getQualifiers().hasAddressSpace()) + continue; + NeedsNewDecl = true; LangAS AS = ArgType->getPointeeType().getAddressSpace(); - QualType PointeeType = ParamType->getPointeeType(); PointeeType = Context.getAddrSpaceQualType(PointeeType, AS); OverloadParams.push_back(Context.getPointerType(PointeeType)); } @@ -5205,7 +5322,7 @@ static void checkDirectCallValidity(Sema &S, const Expr *Fn, return; if (const EnableIfAttr *Attr = S.CheckEnableIf(Callee, ArgExprs, true)) { - S.Diag(Fn->getLocStart(), + S.Diag(Fn->getBeginLoc(), isa<CXXMethodDecl>(Callee) ? diag::err_ovl_no_viable_member_function_in_call : diag::err_ovl_no_viable_function_in_call) @@ -5317,14 +5434,14 @@ ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc, if (isa<CXXPseudoDestructorExpr>(Fn)) { if (!ArgExprs.empty()) { // Pseudo-destructor calls should not have any arguments. - Diag(Fn->getLocStart(), diag::err_pseudo_dtor_call_with_args) + Diag(Fn->getBeginLoc(), diag::err_pseudo_dtor_call_with_args) << FixItHint::CreateRemoval( - SourceRange(ArgExprs.front()->getLocStart(), - ArgExprs.back()->getLocEnd())); + SourceRange(ArgExprs.front()->getBeginLoc(), + ArgExprs.back()->getEndLoc())); } - return new (Context) - CallExpr(Context, Fn, None, Context.VoidTy, VK_RValue, RParenLoc); + return CallExpr::Create(Context, Fn, /*Args=*/{}, Context.VoidTy, + VK_RValue, RParenLoc); } if (Fn->getType() == Context.PseudoObjectTy) { ExprResult result = CheckPlaceholderExpr(Fn); @@ -5334,25 +5451,19 @@ ExprResult Sema::ActOnCallExpr(Scope *Scope, 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. - bool Dependent = false; - if (Fn->isTypeDependent()) - Dependent = true; - else if (Expr::hasAnyTypeDependentArguments(ArgExprs)) - Dependent = true; - - if (Dependent) { + if (Fn->isTypeDependent() || Expr::hasAnyTypeDependentArguments(ArgExprs)) { if (ExecConfig) { - return new (Context) CUDAKernelCallExpr( + return CUDAKernelCallExpr::Create( Context, Fn, cast<CallExpr>(ExecConfig), ArgExprs, Context.DependentTy, VK_RValue, RParenLoc); } else { - tryImplicitlyCaptureThisIfImplicitMemberFunctionAccessWithDependentArgs( + tryImplicitlyCaptureThisIfImplicitMemberFunctionAccessWithDependentArgs( *this, dyn_cast<UnresolvedMemberExpr>(Fn->IgnoreParens()), - Fn->getLocStart()); + Fn->getBeginLoc()); - return new (Context) CallExpr( - Context, Fn, ArgExprs, Context.DependentTy, VK_RValue, RParenLoc); + return CallExpr::Create(Context, Fn, ArgExprs, Context.DependentTy, + VK_RValue, RParenLoc); } } @@ -5380,8 +5491,8 @@ ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc, // We aren't supposed to apply this logic if there's an '&' involved. if (!find.HasFormOfMemberPointer) { if (Expr::hasAnyTypeDependentArguments(ArgExprs)) - return new (Context) CallExpr( - Context, Fn, ArgExprs, Context.DependentTy, VK_RValue, RParenLoc); + return CallExpr::Create(Context, Fn, ArgExprs, Context.DependentTy, + VK_RValue, RParenLoc); OverloadExpr *ovl = find.Expression; if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(ovl)) return BuildOverloadedCallExpr( @@ -5430,9 +5541,8 @@ ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc, NDecl = cast<MemberExpr>(NakedFn)->getMemberDecl(); if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(NDecl)) { - if (CallingNDeclIndirectly && - !checkAddressOfFunctionIsAvailable(FD, /*Complain=*/true, - Fn->getLocStart())) + if (CallingNDeclIndirectly && !checkAddressOfFunctionIsAvailable( + FD, /*Complain=*/true, Fn->getBeginLoc())) return ExprError(); if (getLangOpts().OpenCL && checkOpenCLDisabledDecl(*FD, *Fn)) @@ -5484,12 +5594,11 @@ ExprResult Sema::ActOnConvertVectorExpr(Expr *E, ParsedType ParsedDestTy, /// block-pointer type. /// /// \param NDecl the declaration being called, if available -ExprResult -Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, - SourceLocation LParenLoc, - ArrayRef<Expr *> Args, - SourceLocation RParenLoc, - Expr *Config, bool IsExecConfig) { +ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, + SourceLocation LParenLoc, + ArrayRef<Expr *> Args, + SourceLocation RParenLoc, Expr *Config, + bool IsExecConfig, ADLCallKind UsesADL) { FunctionDecl *FDecl = dyn_cast_or_null<FunctionDecl>(NDecl); unsigned BuiltinID = (FDecl ? FDecl->getBuiltinID() : 0); @@ -5514,28 +5623,71 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, // We special-case function promotion here because we only allow promoting // builtin functions to function pointers in the callee of a call. ExprResult Result; + QualType ResultTy; if (BuiltinID && Fn->getType()->isSpecificBuiltinType(BuiltinType::BuiltinFn)) { - Result = ImpCastExprToType(Fn, Context.getPointerType(FDecl->getType()), - CK_BuiltinFnToFnPtr).get(); + // Extract the return type from the (builtin) function pointer type. + // FIXME Several builtins still have setType in + // Sema::CheckBuiltinFunctionCall. One should review their definitions in + // Builtins.def to ensure they are correct before removing setType calls. + QualType FnPtrTy = Context.getPointerType(FDecl->getType()); + Result = ImpCastExprToType(Fn, FnPtrTy, CK_BuiltinFnToFnPtr).get(); + ResultTy = FDecl->getCallResultType(); } else { Result = CallExprUnaryConversions(Fn); + ResultTy = Context.BoolTy; } if (Result.isInvalid()) return ExprError(); Fn = Result.get(); - // Make the call expr early, before semantic checks. This guarantees cleanup - // of arguments and function on error. + // Check for a valid function type, but only if it is not a builtin which + // requires custom type checking. These will be handled by + // CheckBuiltinFunctionCall below just after creation of the call expression. + const FunctionType *FuncT = nullptr; + if (!BuiltinID || !Context.BuiltinInfo.hasCustomTypechecking(BuiltinID)) { + retry: + if (const PointerType *PT = Fn->getType()->getAs<PointerType>()) { + // C99 6.5.2.2p1 - "The expression that denotes the called function shall + // have type pointer to function". + FuncT = PT->getPointeeType()->getAs<FunctionType>(); + if (!FuncT) + return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function) + << Fn->getType() << Fn->getSourceRange()); + } else if (const BlockPointerType *BPT = + Fn->getType()->getAs<BlockPointerType>()) { + FuncT = BPT->getPointeeType()->castAs<FunctionType>(); + } else { + // Handle calls to expressions of unknown-any type. + if (Fn->getType() == Context.UnknownAnyTy) { + ExprResult rewrite = rebuildUnknownAnyFunction(*this, Fn); + if (rewrite.isInvalid()) return ExprError(); + Fn = rewrite.get(); + goto retry; + } + + return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function) + << Fn->getType() << Fn->getSourceRange()); + } + } + + // Get the number of parameters in the function prototype, if any. + // We will allocate space for max(Args.size(), NumParams) arguments + // in the call expression. + const auto *Proto = dyn_cast_or_null<FunctionProtoType>(FuncT); + unsigned NumParams = Proto ? Proto->getNumParams() : 0; + CallExpr *TheCall; - if (Config) - TheCall = new (Context) CUDAKernelCallExpr(Context, Fn, - cast<CallExpr>(Config), Args, - Context.BoolTy, VK_RValue, - RParenLoc); - else - TheCall = new (Context) CallExpr(Context, Fn, Args, Context.BoolTy, - VK_RValue, RParenLoc); + if (Config) { + assert(UsesADL == ADLCallKind::NotADL && + "CUDAKernelCallExpr should not use ADL"); + TheCall = + CUDAKernelCallExpr::Create(Context, Fn, cast<CallExpr>(Config), Args, + ResultTy, VK_RValue, RParenLoc, NumParams); + } else { + TheCall = CallExpr::Create(Context, Fn, Args, ResultTy, VK_RValue, + RParenLoc, NumParams, UsesADL); + } if (!getLangOpts().CPlusPlus) { // C cannot always handle TypoExpr nodes in builtin calls and direct @@ -5546,39 +5698,16 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, if (!Result.isUsable()) return ExprError(); TheCall = dyn_cast<CallExpr>(Result.get()); if (!TheCall) return Result; - Args = llvm::makeArrayRef(TheCall->getArgs(), TheCall->getNumArgs()); + // TheCall at this point has max(Args.size(), NumParams) arguments, + // with extra arguments nulled. We don't want to introduce nulled + // arguments in Args and so we only take the first Args.size() arguments. + Args = llvm::makeArrayRef(TheCall->getArgs(), Args.size()); } - // Bail out early if calling a builtin with custom typechecking. + // Bail out early if calling a builtin with custom type checking. if (BuiltinID && Context.BuiltinInfo.hasCustomTypechecking(BuiltinID)) return CheckBuiltinFunctionCall(FDecl, BuiltinID, TheCall); - retry: - const FunctionType *FuncT; - if (const PointerType *PT = Fn->getType()->getAs<PointerType>()) { - // C99 6.5.2.2p1 - "The expression that denotes the called function shall - // have type pointer to function". - FuncT = PT->getPointeeType()->getAs<FunctionType>(); - if (!FuncT) - return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function) - << Fn->getType() << Fn->getSourceRange()); - } else if (const BlockPointerType *BPT = - Fn->getType()->getAs<BlockPointerType>()) { - FuncT = BPT->getPointeeType()->castAs<FunctionType>(); - } else { - // Handle calls to expressions of unknown-any type. - if (Fn->getType() == Context.UnknownAnyTy) { - ExprResult rewrite = rebuildUnknownAnyFunction(*this, Fn); - if (rewrite.isInvalid()) return ExprError(); - Fn = rewrite.get(); - TheCall->setCallee(Fn); - goto retry; - } - - return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function) - << Fn->getType() << Fn->getSourceRange()); - } - if (getLangOpts().CUDA) { if (Config) { // CUDA: Kernel calls must be to global functions @@ -5599,7 +5728,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, } // Check for a valid return type - if (CheckCallReturnType(FuncT->getReturnType(), Fn->getLocStart(), TheCall, + if (CheckCallReturnType(FuncT->getReturnType(), Fn->getBeginLoc(), TheCall, FDecl)) return ExprError(); @@ -5607,7 +5736,6 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, TheCall->setType(FuncT->getCallResultType(Context)); TheCall->setValueKind(Expr::getValueKindForType(FuncT->getReturnType())); - const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FuncT); if (Proto) { if (ConvertArgumentsForCall(TheCall, Fn, FDecl, Proto, Args, RParenLoc, IsExecConfig)) @@ -5655,8 +5783,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, Arg = ArgE.getAs<Expr>(); } - if (RequireCompleteType(Arg->getLocStart(), - Arg->getType(), + if (RequireCompleteType(Arg->getBeginLoc(), Arg->getType(), diag::err_call_incomplete_argument, Arg)) return ExprError(); @@ -5739,13 +5866,6 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, LiteralExpr = Result.get(); bool isFileScope = !CurContext->isFunctionOrMethod(); - if (isFileScope && - !LiteralExpr->isTypeDependent() && - !LiteralExpr->isValueDependent() && - !literalType->isDependentType()) { // 6.5.2.5p3 - if (CheckForConstantInitializer(LiteralExpr, literalType)) - return ExprError(); - } // In C, compound literals are l-values for some reason. // For GCC compatibility, in C++, file-scope array compound literals with @@ -5770,9 +5890,32 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, ? VK_RValue : VK_LValue; - return MaybeBindToTemporary( - new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, - VK, LiteralExpr, isFileScope)); + if (isFileScope) + if (auto ILE = dyn_cast<InitListExpr>(LiteralExpr)) + for (unsigned i = 0, j = ILE->getNumInits(); i != j; i++) { + Expr *Init = ILE->getInit(i); + ILE->setInit(i, ConstantExpr::Create(Context, Init)); + } + + Expr *E = new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, + VK, LiteralExpr, isFileScope); + if (isFileScope) { + if (!LiteralExpr->isTypeDependent() && + !LiteralExpr->isValueDependent() && + !literalType->isDependentType()) // C99 6.5.2.5p3 + if (CheckForConstantInitializer(LiteralExpr, literalType)) + return ExprError(); + } else if (literalType.getAddressSpace() != LangAS::opencl_private && + literalType.getAddressSpace() != LangAS::Default) { + // Embedded-C extensions to C99 6.5.2.5: + // "If the compound literal occurs inside the body of a function, the + // type name shall not be qualified by an address-space qualifier." + Diag(LParenLoc, diag::err_compound_literal_with_address_space) + << SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd()); + return ExprError(); + } + + return MaybeBindToTemporary(E); } ExprResult @@ -5854,6 +5997,8 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { LangAS DestAS = DestTy->getPointeeType().getAddressSpace(); if (SrcAS != DestAS) return CK_AddressSpaceConversion; + if (Context.hasCvrSimilarType(SrcTy, DestTy)) + return CK_NoOp; return CK_BitCast; } case Type::STK_BlockPointer: @@ -5874,10 +6019,33 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { case Type::STK_FloatingComplex: case Type::STK_IntegralComplex: case Type::STK_MemberPointer: + case Type::STK_FixedPoint: llvm_unreachable("illegal cast from pointer"); } llvm_unreachable("Should have returned before this"); + case Type::STK_FixedPoint: + switch (DestTy->getScalarTypeKind()) { + case Type::STK_FixedPoint: + return CK_FixedPointCast; + case Type::STK_Bool: + return CK_FixedPointToBoolean; + case Type::STK_Integral: + case Type::STK_Floating: + case Type::STK_IntegralComplex: + case Type::STK_FloatingComplex: + Diag(Src.get()->getExprLoc(), + diag::err_unimplemented_conversion_with_fixed_point_type) + << DestTy; + return CK_IntegralCast; + case Type::STK_CPointer: + case Type::STK_ObjCObjectPointer: + case Type::STK_BlockPointer: + case Type::STK_MemberPointer: + llvm_unreachable("illegal cast to pointer type"); + } + llvm_unreachable("Should have returned before this"); + case Type::STK_Bool: // casting from bool is like casting from an integer case Type::STK_Integral: switch (DestTy->getScalarTypeKind()) { @@ -5906,6 +6074,11 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { return CK_FloatingRealToComplex; case Type::STK_MemberPointer: llvm_unreachable("member pointer type in C"); + case Type::STK_FixedPoint: + Diag(Src.get()->getExprLoc(), + diag::err_unimplemented_conversion_with_fixed_point_type) + << SrcTy; + return CK_IntegralCast; } llvm_unreachable("Should have returned before this"); @@ -5933,6 +6106,11 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { llvm_unreachable("valid float->pointer cast?"); case Type::STK_MemberPointer: llvm_unreachable("member pointer type in C"); + case Type::STK_FixedPoint: + Diag(Src.get()->getExprLoc(), + diag::err_unimplemented_conversion_with_fixed_point_type) + << SrcTy; + return CK_IntegralCast; } llvm_unreachable("Should have returned before this"); @@ -5962,6 +6140,11 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { llvm_unreachable("valid complex float->pointer cast?"); case Type::STK_MemberPointer: llvm_unreachable("member pointer type in C"); + case Type::STK_FixedPoint: + Diag(Src.get()->getExprLoc(), + diag::err_unimplemented_conversion_with_fixed_point_type) + << SrcTy; + return CK_IntegralCast; } llvm_unreachable("Should have returned before this"); @@ -5991,6 +6174,11 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { llvm_unreachable("valid complex int->pointer cast?"); case Type::STK_MemberPointer: llvm_unreachable("member pointer type in C"); + case Type::STK_FixedPoint: + Diag(Src.get()->getExprLoc(), + diag::err_unimplemented_conversion_with_fixed_point_type) + << SrcTy; + return CK_IntegralCast; } llvm_unreachable("Should have returned before this"); } @@ -6323,8 +6511,7 @@ Sema::MaybeConvertParenListExprToParenExpr(Scope *S, Expr *OrigExpr) { ExprResult Sema::ActOnParenListExpr(SourceLocation L, SourceLocation R, MultiExprArg Val) { - Expr *expr = new (Context) ParenListExpr(Context, L, Val, R); - return expr; + return ParenListExpr::Create(Context, L, Val, R); } /// Emit a specialized diagnostic when one expression is a null pointer @@ -6394,11 +6581,11 @@ static QualType checkConditionalVoidType(Sema &S, ExprResult &LHS, Expr *RHSExpr = RHS.get(); if (!LHSExpr->getType()->isVoidType()) - S.Diag(RHSExpr->getLocStart(), diag::ext_typecheck_cond_one_void) - << RHSExpr->getSourceRange(); + S.Diag(RHSExpr->getBeginLoc(), diag::ext_typecheck_cond_one_void) + << RHSExpr->getSourceRange(); if (!RHSExpr->getType()->isVoidType()) - S.Diag(LHSExpr->getLocStart(), diag::ext_typecheck_cond_one_void) - << LHSExpr->getSourceRange(); + S.Diag(LHSExpr->getBeginLoc(), diag::ext_typecheck_cond_one_void) + << LHSExpr->getSourceRange(); LHS = S.ImpCastExprToType(LHS.get(), S.Context.VoidTy, CK_ToVoid); RHS = S.ImpCastExprToType(RHS.get(), S.Context.VoidTy, CK_ToVoid); return S.Context.VoidTy; @@ -6458,20 +6645,18 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS, LangAS ResultAddrSpace = LangAS::Default; LangAS LAddrSpace = lhQual.getAddressSpace(); LangAS RAddrSpace = rhQual.getAddressSpace(); - if (S.getLangOpts().OpenCL) { - // OpenCL v1.1 s6.5 - Conversion between pointers to distinct address - // spaces is disallowed. - if (lhQual.isAddressSpaceSupersetOf(rhQual)) - ResultAddrSpace = LAddrSpace; - else if (rhQual.isAddressSpaceSupersetOf(lhQual)) - ResultAddrSpace = RAddrSpace; - else { - S.Diag(Loc, - diag::err_typecheck_op_on_nonoverlapping_address_space_pointers) - << LHSTy << RHSTy << 2 << LHS.get()->getSourceRange() - << RHS.get()->getSourceRange(); - return QualType(); - } + + // OpenCL v1.1 s6.5 - Conversion between pointers to distinct address + // spaces is disallowed. + if (lhQual.isAddressSpaceSupersetOf(rhQual)) + ResultAddrSpace = LAddrSpace; + else if (rhQual.isAddressSpaceSupersetOf(lhQual)) + ResultAddrSpace = RAddrSpace; + else { + S.Diag(Loc, diag::err_typecheck_op_on_nonoverlapping_address_space_pointers) + << LHSTy << RHSTy << 2 << LHS.get()->getSourceRange() + << RHS.get()->getSourceRange(); + return QualType(); } unsigned MergedCVRQual = lhQual.getCVRQualifiers() | rhQual.getCVRQualifiers(); @@ -6489,16 +6674,12 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS, // Thus for conditional operator we merge CVR and address space unqualified // pointees and if there is a composite type we return a pointer to it with // merged qualifiers. - if (S.getLangOpts().OpenCL) { - LHSCastKind = LAddrSpace == ResultAddrSpace - ? CK_BitCast - : CK_AddressSpaceConversion; - RHSCastKind = RAddrSpace == ResultAddrSpace - ? CK_BitCast - : CK_AddressSpaceConversion; - lhQual.removeAddressSpace(); - rhQual.removeAddressSpace(); - } + LHSCastKind = + LAddrSpace == ResultAddrSpace ? CK_BitCast : CK_AddressSpaceConversion; + RHSCastKind = + RAddrSpace == ResultAddrSpace ? CK_BitCast : CK_AddressSpaceConversion; + lhQual.removeAddressSpace(); + rhQual.removeAddressSpace(); lhptee = S.Context.getQualifiedType(lhptee.getUnqualifiedType(), lhQual); rhptee = S.Context.getQualifiedType(rhptee.getUnqualifiedType(), rhQual); @@ -6514,6 +6695,7 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS, S.Context.getAddrSpaceQualType(S.Context.VoidTy, ResultAddrSpace)); LHS = S.ImpCastExprToType(LHS.get(), incompatTy, LHSCastKind); RHS = S.ImpCastExprToType(RHS.get(), incompatTy, RHSCastKind); + // FIXME: For OpenCL the warning emission and cast to void* leaves a room // for casts between types with incompatible address space qualifiers. // For the following code the compiler produces casts between global and @@ -6524,6 +6706,7 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS, S.Diag(Loc, diag::ext_typecheck_cond_incompatible_pointers) << LHSTy << RHSTy << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); + return incompatTy; } @@ -7219,14 +7402,15 @@ static void DiagnoseConditionalPrecedence(Sema &Self, << Condition->getSourceRange() << BinaryOperator::getOpcodeStr(CondOpcode); - SuggestParentheses(Self, OpLoc, - Self.PDiag(diag::note_precedence_silence) - << BinaryOperator::getOpcodeStr(CondOpcode), - SourceRange(Condition->getLocStart(), Condition->getLocEnd())); + SuggestParentheses( + Self, OpLoc, + Self.PDiag(diag::note_precedence_silence) + << BinaryOperator::getOpcodeStr(CondOpcode), + SourceRange(Condition->getBeginLoc(), Condition->getEndLoc())); SuggestParentheses(Self, OpLoc, - Self.PDiag(diag::note_precedence_conditional_first), - SourceRange(CondRHS->getLocStart(), RHSExpr->getLocEnd())); + Self.PDiag(diag::note_precedence_conditional_first), + SourceRange(CondRHS->getBeginLoc(), RHSExpr->getEndLoc())); } /// Compute the nullability of a conditional expression. @@ -7757,7 +7941,12 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, if (isa<PointerType>(RHSType)) { LangAS AddrSpaceL = LHSPointer->getPointeeType().getAddressSpace(); LangAS AddrSpaceR = RHSType->getPointeeType().getAddressSpace(); - Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion : CK_BitCast; + if (AddrSpaceL != AddrSpaceR) + Kind = CK_AddressSpaceConversion; + else if (Context.hasCvrSimilarType(RHSType, LHSType)) + Kind = CK_NoOp; + else + Kind = CK_BitCast; return checkPointerTypesForAssignment(*this, LHSType, RHSType); } @@ -7825,7 +8014,7 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, } // id -> T^ - if (getLangOpts().ObjC1 && RHSType->isObjCIdType()) { + if (getLangOpts().ObjC && RHSType->isObjCIdType()) { Kind = CK_AnyPointerToBlockPointerCast; return Compatible; } @@ -8029,6 +8218,17 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS, ExprResult LocalRHS = CallerRHS; ExprResult &RHS = ConvertRHS ? CallerRHS : LocalRHS; + if (const auto *LHSPtrType = LHSType->getAs<PointerType>()) { + if (const auto *RHSPtrType = RHS.get()->getType()->getAs<PointerType>()) { + if (RHSPtrType->getPointeeType()->hasAttr(attr::NoDeref) && + !LHSPtrType->getPointeeType()->hasAttr(attr::NoDeref)) { + Diag(RHS.get()->getExprLoc(), + diag::warn_noderef_to_dereferenceable_pointer) + << RHS.get()->getSourceRange(); + } + } + } + if (getLangOpts().CPlusPlus) { if (!LHSType->isRecordType() && !LHSType->isAtomicType()) { // C++ 5.17p3: If the left operand is not of class type, the @@ -8092,6 +8292,13 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS, return Compatible; } + // OpenCL queue_t type assignment. + if (LHSType->isQueueT() && RHS.get()->isNullPointerConstant( + Context, Expr::NPC_ValueDependentIsNull)) { + RHS = ImpCastExprToType(RHS.get(), LHSType, CK_NullToPointer); + return Compatible; + } + // This check seems unnatural, however it is necessary to ensure the proper // conversion of functions/arrays. If the conversion were done for all // DeclExpr's (created by ActOnIdExpression), it would mess up the unary @@ -8104,16 +8311,6 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS, if (RHS.isInvalid()) return Incompatible; } - - Expr *PRE = RHS.get()->IgnoreParenCasts(); - if (Diagnose && isa<ObjCProtocolExpr>(PRE)) { - ObjCProtocolDecl *PDecl = cast<ObjCProtocolExpr>(PRE)->getProtocol(); - if (PDecl && !PDecl->hasDefinition()) { - Diag(PRE->getExprLoc(), diag::warn_atprotocol_protocol) << PDecl; - Diag(PDecl->getLocation(), diag::note_entity_declared_at) << PDecl; - } - } - CastKind Kind; Sema::AssignConvertType result = CheckAssignmentConstraints(LHSType, RHS, Kind, ConvertRHS); @@ -8137,8 +8334,8 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS, if (!Diagnose) return Incompatible; } - if (getLangOpts().ObjC1 && - (CheckObjCBridgeRelatedConversions(E->getLocStart(), LHSType, + if (getLangOpts().ObjC && + (CheckObjCBridgeRelatedConversions(E->getBeginLoc(), LHSType, E->getType(), E, Diagnose) || ConversionToObjCStringLiteralCheck(LHSType, E, Diagnose))) { if (!Diagnose) @@ -8152,6 +8349,7 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS, if (ConvertRHS) RHS = ImpCastExprToType(E, Ty, Kind); } + return result; } @@ -8314,8 +8512,8 @@ static bool canConvertIntToOtherIntTy(Sema &S, ExprResult *Int, // Reject cases where the value of the Int is unknown as that would // possibly cause truncation, but accept cases where the scalar can be // demoted without loss of precision. - llvm::APSInt Result; - bool CstInt = Int->get()->EvaluateAsInt(Result, S.Context); + Expr::EvalResult EVResult; + bool CstInt = Int->get()->EvaluateAsInt(EVResult, S.Context); int Order = S.Context.getIntegerTypeOrder(OtherIntTy, IntTy); bool IntSigned = IntTy->hasSignedIntegerRepresentation(); bool OtherIntSigned = OtherIntTy->hasSignedIntegerRepresentation(); @@ -8323,6 +8521,7 @@ static bool canConvertIntToOtherIntTy(Sema &S, ExprResult *Int, if (CstInt) { // If the scalar is constant and is of a higher order and has more active // bits that the vector element type, reject it. + llvm::APSInt Result = EVResult.Val.getInt(); unsigned NumBits = IntSigned ? (Result.isNegative() ? Result.getMinSignedBits() : Result.getActiveBits()) @@ -8350,8 +8549,9 @@ static bool canConvertIntTyToFloatTy(Sema &S, ExprResult *Int, // Determine if the integer constant can be expressed as a floating point // number of the appropriate type. - llvm::APSInt Result; - bool CstInt = Int->get()->EvaluateAsInt(Result, S.Context); + Expr::EvalResult EVResult; + bool CstInt = Int->get()->EvaluateAsInt(EVResult, S.Context); + uint64_t Bits = 0; if (CstInt) { // Reject constants that would be truncated if they were converted to @@ -8359,6 +8559,7 @@ static bool canConvertIntTyToFloatTy(Sema &S, ExprResult *Int, // FIXME: Ideally the conversion to an APFloat and from an APFloat // could be avoided if there was a convertFromAPInt method // which could signal back if implicit truncation occurred. + llvm::APSInt Result = EVResult.Val.getInt(); llvm::APFloat Float(S.Context.getFloatTypeSemantics(FloatTy)); Float.convertFromAPInt(Result, IntTy->hasSignedIntegerRepresentation(), llvm::APFloat::rmTowardZero); @@ -8668,13 +8869,40 @@ static void checkArithmeticNull(Sema &S, ExprResult &LHS, ExprResult &RHS, << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); } +static void DiagnoseDivisionSizeofPointer(Sema &S, Expr *LHS, Expr *RHS, + SourceLocation Loc) { + const auto *LUE = dyn_cast<UnaryExprOrTypeTraitExpr>(LHS); + const auto *RUE = dyn_cast<UnaryExprOrTypeTraitExpr>(RHS); + if (!LUE || !RUE) + return; + if (LUE->getKind() != UETT_SizeOf || LUE->isArgumentType() || + RUE->getKind() != UETT_SizeOf) + return; + + QualType LHSTy = LUE->getArgumentExpr()->IgnoreParens()->getType(); + QualType RHSTy; + + if (RUE->isArgumentType()) + RHSTy = RUE->getArgumentType(); + else + RHSTy = RUE->getArgumentExpr()->IgnoreParens()->getType(); + + if (!LHSTy->isPointerType() || RHSTy->isPointerType()) + return; + if (LHSTy->getPointeeType() != RHSTy) + return; + + S.Diag(Loc, diag::warn_division_sizeof_ptr) << LHS << LHS->getSourceRange(); +} + static void DiagnoseBadDivideOrRemainderValues(Sema& S, ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsDiv) { // Check for division/remainder by zero. - llvm::APSInt RHSValue; + Expr::EvalResult RHSValue; if (!RHS.get()->isValueDependent() && - RHS.get()->EvaluateAsInt(RHSValue, S.Context) && RHSValue == 0) + RHS.get()->EvaluateAsInt(RHSValue, S.Context) && + RHSValue.Val.getInt() == 0) S.DiagRuntimeBehavior(Loc, RHS.get(), S.PDiag(diag::warn_remainder_division_by_zero) << IsDiv << RHS.get()->getSourceRange()); @@ -8698,8 +8926,10 @@ QualType Sema::CheckMultiplyDivideOperands(ExprResult &LHS, ExprResult &RHS, if (compType.isNull() || !compType->isArithmeticType()) return InvalidOperands(Loc, LHS, RHS); - if (IsDiv) + if (IsDiv) { DiagnoseBadDivideOrRemainderValues(*this, LHS, RHS, Loc, IsDiv); + DiagnoseDivisionSizeofPointer(*this, LHS.get(), RHS.get(), Loc); + } return compType; } @@ -8914,24 +9144,15 @@ static void diagnoseStringPlusInt(Sema &Self, SourceLocation OpLoc, if (!IsStringPlusInt || IndexExpr->isValueDependent()) return; - llvm::APSInt index; - if (IndexExpr->EvaluateAsInt(index, Self.getASTContext())) { - unsigned StrLenWithNull = StrExpr->getLength() + 1; - if (index.isNonNegative() && - index <= llvm::APSInt(llvm::APInt(index.getBitWidth(), StrLenWithNull), - index.isUnsigned())) - return; - } - - SourceRange DiagRange(LHSExpr->getLocStart(), RHSExpr->getLocEnd()); + SourceRange DiagRange(LHSExpr->getBeginLoc(), RHSExpr->getEndLoc()); Self.Diag(OpLoc, diag::warn_string_plus_int) << DiagRange << IndexExpr->IgnoreImpCasts()->getType(); // Only print a fixit for "str" + int, not for int + "str". if (IndexExpr == RHSExpr) { - SourceLocation EndLoc = Self.getLocForEndOfToken(RHSExpr->getLocEnd()); + SourceLocation EndLoc = Self.getLocForEndOfToken(RHSExpr->getEndLoc()); Self.Diag(OpLoc, diag::note_string_plus_scalar_silence) - << FixItHint::CreateInsertion(LHSExpr->getLocStart(), "&") + << FixItHint::CreateInsertion(LHSExpr->getBeginLoc(), "&") << FixItHint::CreateReplacement(SourceRange(OpLoc), "[") << FixItHint::CreateInsertion(EndLoc, "]"); } else @@ -8964,7 +9185,7 @@ static void diagnoseStringPlusChar(Sema &Self, SourceLocation OpLoc, return; ASTContext &Ctx = Self.getASTContext(); - SourceRange DiagRange(LHSExpr->getLocStart(), RHSExpr->getLocEnd()); + SourceRange DiagRange(LHSExpr->getBeginLoc(), RHSExpr->getEndLoc()); const QualType CharType = CharExpr->getType(); if (!CharType->isAnyCharacterType() && @@ -8979,9 +9200,9 @@ static void diagnoseStringPlusChar(Sema &Self, SourceLocation OpLoc, // Only print a fixit for str + char, not for char + str. if (isa<CharacterLiteral>(RHSExpr->IgnoreImpCasts())) { - SourceLocation EndLoc = Self.getLocForEndOfToken(RHSExpr->getLocEnd()); + SourceLocation EndLoc = Self.getLocForEndOfToken(RHSExpr->getEndLoc()); Self.Diag(OpLoc, diag::note_string_plus_scalar_silence) - << FixItHint::CreateInsertion(LHSExpr->getLocStart(), "&") + << FixItHint::CreateInsertion(LHSExpr->getBeginLoc(), "&") << FixItHint::CreateReplacement(SourceRange(OpLoc), "[") << FixItHint::CreateInsertion(EndLoc, "]"); } else { @@ -9059,10 +9280,11 @@ QualType Sema::CheckAdditionOperands(ExprResult &LHS, ExprResult &RHS, if (PExp->IgnoreParenCasts()->isNullPointerConstant( Context, Expr::NPC_ValueDependentIsNotNull)) { // In C++ adding zero to a null pointer is defined. - llvm::APSInt KnownVal; + Expr::EvalResult KnownVal; if (!getLangOpts().CPlusPlus || (!IExp->isValueDependent() && - (!IExp->EvaluateAsInt(KnownVal, Context) || KnownVal != 0))) { + (!IExp->EvaluateAsInt(KnownVal, Context) || + KnownVal.Val.getInt() != 0))) { // Check the conditions to see if this is the 'p = nullptr + n' idiom. bool IsGNUIdiom = BinaryOperator::isNullPointerArithmeticExtension( Context, BO_Add, PExp, IExp); @@ -9137,10 +9359,11 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS, if (LHS.get()->IgnoreParenCasts()->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull)) { // In C++ adding zero to a null pointer is defined. - llvm::APSInt KnownVal; + Expr::EvalResult KnownVal; if (!getLangOpts().CPlusPlus || (!RHS.get()->isValueDependent() && - (!RHS.get()->EvaluateAsInt(KnownVal, Context) || KnownVal != 0))) { + (!RHS.get()->EvaluateAsInt(KnownVal, Context) || + KnownVal.Val.getInt() != 0))) { diagnoseArithmeticOnNullPointer(*this, Loc, LHS.get(), false); } } @@ -9216,11 +9439,12 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS, if (S.getLangOpts().OpenCL) return; - llvm::APSInt Right; // Check right/shifter operand + Expr::EvalResult RHSResult; if (RHS.get()->isValueDependent() || - !RHS.get()->EvaluateAsInt(Right, S.Context)) + !RHS.get()->EvaluateAsInt(RHSResult, S.Context)) return; + llvm::APSInt Right = RHSResult.Val.getInt(); if (Right.isNegative()) { S.DiagRuntimeBehavior(Loc, RHS.get(), @@ -9243,11 +9467,12 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS, // according to C++ has undefined behavior ([expr.shift] 5.8/2). Unsigned // integers have defined behavior modulo one more than the maximum value // representable in the result type, so never warn for those. - llvm::APSInt Left; + Expr::EvalResult LHSResult; if (LHS.get()->isValueDependent() || LHSType->hasUnsignedIntegerRepresentation() || - !LHS.get()->EvaluateAsInt(Left, S.Context)) + !LHS.get()->EvaluateAsInt(LHSResult, S.Context)) return; + llvm::APSInt Left = LHSResult.Val.getInt(); // If LHS does not have a signed type and non-negative value // then, the behavior is undefined. Warn about it. @@ -9653,8 +9878,8 @@ static void diagnoseObjCLiteralComparison(Sema &S, SourceLocation Loc, if (BinaryOperator::isEqualityOp(Opc) && hasIsEqualMethod(S, LHS.get(), RHS.get())) { - SourceLocation Start = LHS.get()->getLocStart(); - SourceLocation End = S.getLocForEndOfToken(RHS.get()->getLocEnd()); + SourceLocation Start = LHS.get()->getBeginLoc(); + SourceLocation End = S.getLocForEndOfToken(RHS.get()->getEndLoc()); CharSourceRange OpRange = CharSourceRange::getCharRange(Loc, S.getLocForEndOfToken(Loc)); @@ -9686,8 +9911,8 @@ static void diagnoseLogicalNotOnLHSofCheck(Sema &S, ExprResult &LHS, << Loc << IsBitwiseOp; // First note suggest !(x < y) - SourceLocation FirstOpen = SubExpr->getLocStart(); - SourceLocation FirstClose = RHS.get()->getLocEnd(); + SourceLocation FirstOpen = SubExpr->getBeginLoc(); + SourceLocation FirstClose = RHS.get()->getEndLoc(); FirstClose = S.getLocForEndOfToken(FirstClose); if (FirstClose.isInvalid()) FirstOpen = SourceLocation(); @@ -9697,8 +9922,8 @@ static void diagnoseLogicalNotOnLHSofCheck(Sema &S, ExprResult &LHS, << FixItHint::CreateInsertion(FirstClose, ")"); // Second note suggests (!x) < y - SourceLocation SecondOpen = LHS.get()->getLocStart(); - SourceLocation SecondClose = LHS.get()->getLocEnd(); + SourceLocation SecondOpen = LHS.get()->getBeginLoc(); + SourceLocation SecondClose = LHS.get()->getEndLoc(); SecondClose = S.getLocForEndOfToken(SecondClose); if (SecondClose.isInvalid()) SecondOpen = SourceLocation(); @@ -9734,7 +9959,7 @@ static void diagnoseTautologicalComparison(Sema &S, SourceLocation Loc, QualType RHSType = RHS->getType(); if (LHSType->hasFloatingRepresentation() || (LHSType->isBlockPointerType() && !BinaryOperator::isEqualityOp(Opc)) || - LHS->getLocStart().isMacroID() || RHS->getLocStart().isMacroID() || + LHS->getBeginLoc().isMacroID() || RHS->getBeginLoc().isMacroID() || S.inTemplateInstantiation()) return; @@ -9888,7 +10113,7 @@ static bool checkThreeWayNarrowingConversion(Sema &S, QualType ToType, Expr *E, case NK_Constant_Narrowing: // Implicit conversion to a narrower type, and the value is not a constant // expression. - S.Diag(E->getLocStart(), diag::err_spaceship_argument_narrowing) + S.Diag(E->getBeginLoc(), diag::err_spaceship_argument_narrowing) << /*Constant*/ 1 << PreNarrowingValue.getAsString(S.Context, PreNarrowingType) << ToType; return true; @@ -9897,7 +10122,7 @@ static bool checkThreeWayNarrowingConversion(Sema &S, QualType ToType, Expr *E, // Implicit conversion to a narrower type, and the value is not a constant // expression. case NK_Type_Narrowing: - S.Diag(E->getLocStart(), diag::err_spaceship_argument_narrowing) + S.Diag(E->getBeginLoc(), diag::err_spaceship_argument_narrowing) << /*Constant*/ 0 << FromType << ToType; // TODO: It's not a constant expression, but what if the user intended it // to be? Can we produce notes to help them figure out why it isn't? @@ -9972,9 +10197,9 @@ static QualType checkArithmeticOrEnumeralThreeWayCompare(Sema &S, assert(Type->isArithmeticType() || Type->isEnumeralType()); bool HasNarrowing = checkThreeWayNarrowingConversion( - S, Type, LHS.get(), LHSType, LHS.get()->getLocStart()); - HasNarrowing |= checkThreeWayNarrowingConversion( - S, Type, RHS.get(), RHSType, RHS.get()->getLocStart()); + S, Type, LHS.get(), LHSType, LHS.get()->getBeginLoc()); + HasNarrowing |= checkThreeWayNarrowingConversion(S, Type, RHS.get(), RHSType, + RHS.get()->getBeginLoc()); if (HasNarrowing) return QualType(); @@ -10439,6 +10664,14 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, } if (getLangOpts().OpenCLVersion >= 200) { + if (LHSType->isClkEventT() && RHSType->isClkEventT()) { + return computeResultTy(); + } + + if (LHSType->isQueueT() && RHSType->isQueueT()) { + return computeResultTy(); + } + if (LHSIsNull && RHSType->isQueueT()) { LHS = ImpCastExprToType(LHS.get(), RHSType, CK_NullToPointer); return computeResultTy(); @@ -10609,8 +10842,9 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS, // that isn't 0 or 1 (which indicate a potential logical operation that // happened to fold to true/false) then warn. // Parens on the RHS are ignored. - llvm::APSInt Result; - if (RHS.get()->EvaluateAsInt(Result, Context)) + Expr::EvalResult EVResult; + if (RHS.get()->EvaluateAsInt(EVResult, Context)) { + llvm::APSInt Result = EVResult.Val.getInt(); if ((getLangOpts().Bool && !RHS.get()->getType()->isBooleanType() && !RHS.get()->getExprLoc().isMacroID()) || (Result != 0 && Result != 1)) { @@ -10627,9 +10861,10 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS, // Suggest replacing "Foo() && kNonZero" with "Foo()" Diag(Loc, diag::note_logical_instead_of_bitwise_remove_constant) << FixItHint::CreateRemoval( - SourceRange(getLocForEndOfToken(LHS.get()->getLocEnd()), - RHS.get()->getLocEnd())); + SourceRange(getLocForEndOfToken(LHS.get()->getEndLoc()), + RHS.get()->getEndLoc())); } + } } if (!Context.getLangOpts().CPlusPlus) { @@ -10880,30 +11115,38 @@ static void DiagnoseRecursiveConstFields(Sema &S, const ValueDecl *VD, const RecordType *Ty, SourceLocation Loc, SourceRange Range, OriginalExprKind OEK, - bool &DiagnosticEmitted, - bool IsNested = false) { + bool &DiagnosticEmitted) { + std::vector<const RecordType *> RecordTypeList; + RecordTypeList.push_back(Ty); + unsigned NextToCheckIndex = 0; // We walk the record hierarchy breadth-first to ensure that we print // diagnostics in field nesting order. - // First, check every field for constness. - for (const FieldDecl *Field : Ty->getDecl()->fields()) { - if (Field->getType().isConstQualified()) { - if (!DiagnosticEmitted) { - S.Diag(Loc, diag::err_typecheck_assign_const) - << Range << NestedConstMember << OEK << VD - << IsNested << Field; - DiagnosticEmitted = true; + while (RecordTypeList.size() > NextToCheckIndex) { + bool IsNested = NextToCheckIndex > 0; + for (const FieldDecl *Field : + RecordTypeList[NextToCheckIndex]->getDecl()->fields()) { + // First, check every field for constness. + QualType FieldTy = Field->getType(); + if (FieldTy.isConstQualified()) { + if (!DiagnosticEmitted) { + S.Diag(Loc, diag::err_typecheck_assign_const) + << Range << NestedConstMember << OEK << VD + << IsNested << Field; + DiagnosticEmitted = true; + } + S.Diag(Field->getLocation(), diag::note_typecheck_assign_const) + << NestedConstMember << IsNested << Field + << FieldTy << Field->getSourceRange(); + } + + // Then we append it to the list to check next in order. + FieldTy = FieldTy.getCanonicalType(); + if (const auto *FieldRecTy = FieldTy->getAs<RecordType>()) { + if (llvm::find(RecordTypeList, FieldRecTy) == RecordTypeList.end()) + RecordTypeList.push_back(FieldRecTy); } - S.Diag(Field->getLocation(), diag::note_typecheck_assign_const) - << NestedConstMember << IsNested << Field - << Field->getType() << Field->getSourceRange(); } - } - // Then, recurse. - for (const FieldDecl *Field : Ty->getDecl()->fields()) { - QualType FTy = Field->getType(); - if (const RecordType *FieldRecTy = FTy->getAs<RecordType>()) - DiagnoseRecursiveConstFields(S, VD, FieldRecTy, Loc, Range, - OEK, DiagnosticEmitted, true); + ++NextToCheckIndex; } } @@ -10971,17 +11214,23 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) { if (var->isARCPseudoStrong() && (!var->getTypeSourceInfo() || !var->getTypeSourceInfo()->getType().isConstQualified())) { - // There are two pseudo-strong cases: + // There are three pseudo-strong cases: // - self ObjCMethodDecl *method = S.getCurMethodDecl(); - if (method && var == method->getSelfDecl()) + if (method && var == method->getSelfDecl()) { DiagID = method->isClassMethod() ? diag::err_typecheck_arc_assign_self_class_method : diag::err_typecheck_arc_assign_self; + // - Objective-C externally_retained attribute. + } else if (var->hasAttr<ObjCExternallyRetainedAttr>() || + isa<ParmVarDecl>(var)) { + DiagID = diag::err_typecheck_arc_assign_externally_retained; + // - fast enumeration variables - else + } else { DiagID = diag::err_typecheck_arr_assign_enumeration; + } SourceRange Assign; if (Loc != OrigLoc) @@ -11150,15 +11399,14 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS, if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(RHSCheck)) RHSCheck = ICE->getSubExpr(); if (UnaryOperator *UO = dyn_cast<UnaryOperator>(RHSCheck)) { - if ((UO->getOpcode() == UO_Plus || - UO->getOpcode() == UO_Minus) && + if ((UO->getOpcode() == UO_Plus || UO->getOpcode() == UO_Minus) && Loc.isFileID() && UO->getOperatorLoc().isFileID() && // Only if the two operators are exactly adjacent. Loc.getLocWithOffset(1) == UO->getOperatorLoc() && // And there is a space or other character before the subexpr of the // unary +/-. We don't want to warn on "x=-1". - Loc.getLocWithOffset(2) != UO->getSubExpr()->getLocStart() && - UO->getSubExpr()->getLocStart().isFileID()) { + Loc.getLocWithOffset(2) != UO->getSubExpr()->getBeginLoc() && + UO->getSubExpr()->getBeginLoc().isFileID()) { Diag(Loc, diag::warn_not_compound_assign) << (UO->getOpcode() == UO_Plus ? "+" : "-") << SourceRange(UO->getOperatorLoc(), UO->getOperatorLoc()); @@ -11188,7 +11436,7 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS, // For ObjCWeak only, we do not warn if the assign is to a non-weak // variable, which will be valid for the current autorelease scope. if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, - RHS.get()->getLocStart())) + RHS.get()->getBeginLoc())) getCurFunction()->markSafeWeakUse(RHS.get()); } else if (getLangOpts().ObjCAutoRefCount || getLangOpts().ObjCWeak) { @@ -11225,6 +11473,12 @@ static bool IgnoreCommaOperand(const Expr *E) { if (CE->getCastKind() == CK_ToVoid) { return true; } + + // static_cast<void> on a dependent type will not show up as CK_ToVoid. + if (CE->getCastKind() == CK_Dependent && E->getType()->isVoidType() && + CE->getSubExpr()->getType()->isDependentType()) { + return true; + } } return false; @@ -11248,8 +11502,11 @@ void Sema::DiagnoseCommaOperator(const Expr *LHS, SourceLocation Loc) { // 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. + // Differences in scope flags for C89 mode requires the extra logic. const unsigned ForIncrementFlags = - Scope::ControlScope | Scope::ContinueScope | Scope::BreakScope; + getLangOpts().C99 || getLangOpts().CPlusPlus + ? Scope::ControlScope | Scope::ContinueScope | Scope::BreakScope + : Scope::ContinueScope | Scope::BreakScope; const unsigned ForInitFlags = Scope::ControlScope | Scope::DeclScope; const unsigned ScopeFlags = getCurScope()->getFlags(); if ((ScopeFlags & ForIncrementFlags) == ForIncrementFlags || @@ -11269,12 +11526,12 @@ void Sema::DiagnoseCommaOperator(const Expr *LHS, SourceLocation Loc) { return; Diag(Loc, diag::warn_comma_operator); - Diag(LHS->getLocStart(), diag::note_cast_to_void) + Diag(LHS->getBeginLoc(), diag::note_cast_to_void) << LHS->getSourceRange() - << FixItHint::CreateInsertion(LHS->getLocStart(), + << FixItHint::CreateInsertion(LHS->getBeginLoc(), LangOpts.CPlusPlus ? "static_cast<void>(" : "(void)(") - << FixItHint::CreateInsertion(PP.getLocForEndOfToken(LHS->getLocEnd()), + << FixItHint::CreateInsertion(PP.getLocForEndOfToken(LHS->getEndLoc()), ")"); } @@ -11551,7 +11808,7 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) { if (auto *FD = dyn_cast_or_null<FunctionDecl>(dcl)) if (!checkAddressOfFunctionIsAvailable(FD, /*Complain=*/true, - op->getLocStart())) + op->getBeginLoc())) return QualType(); Expr::LValueClassification lval = op->ClassifyLValue(Context); @@ -11877,7 +12134,7 @@ static void DiagnoseSelfAssignment(Sema &S, Expr *LHSExpr, Expr *RHSExpr, /// is usually indicative of introspection within the Objective-C pointer. static void checkObjCPointerIntrospection(Sema &S, ExprResult &L, ExprResult &R, SourceLocation OpLoc) { - if (!S.getLangOpts().ObjC1) + if (!S.getLangOpts().ObjC) return; const Expr *ObjCPointerExpr = nullptr, *OtherExpr = nullptr; @@ -12006,7 +12263,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, // The meaning of x = {v} [...] is that of x = T(v) [...]. The meaning // of x = {} is x = T(). InitializationKind Kind = InitializationKind::CreateDirectList( - RHSExpr->getLocStart(), RHSExpr->getLocStart(), RHSExpr->getLocEnd()); + RHSExpr->getBeginLoc(), RHSExpr->getBeginLoc(), RHSExpr->getEndLoc()); InitializedEntity Entity = InitializedEntity::InitializeTemporary(LHSExpr->getType()); InitializationSequence InitSeq(*this, Entity, Kind, RHSExpr); @@ -12035,7 +12292,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, // OpenCLC v2.0 s6.13.11.1 allows atomic variables to be initialized by // the ATOMIC_VAR_INIT macro. if (LHSTy->isAtomicType() || RHSTy->isAtomicType()) { - SourceRange SR(LHSExpr->getLocStart(), RHSExpr->getLocEnd()); + SourceRange SR(LHSExpr->getBeginLoc(), RHSExpr->getEndLoc()); if (BO_Assign == Opc) Diag(OpLoc, diag::err_opencl_atomic_init) << 0 << SR; else @@ -12197,11 +12454,13 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, &Context.Idents.get("object_setClass"), SourceLocation(), LookupOrdinaryName); if (ObjectSetClass && isa<ObjCIsaExpr>(LHS.get())) { - SourceLocation RHSLocEnd = getLocForEndOfToken(RHS.get()->getLocEnd()); - Diag(LHS.get()->getExprLoc(), diag::warn_objc_isa_assign) << - FixItHint::CreateInsertion(LHS.get()->getLocStart(), "object_setClass(") << - FixItHint::CreateReplacement(SourceRange(OISA->getOpLoc(), OpLoc), ",") << - FixItHint::CreateInsertion(RHSLocEnd, ")"); + SourceLocation RHSLocEnd = getLocForEndOfToken(RHS.get()->getEndLoc()); + Diag(LHS.get()->getExprLoc(), diag::warn_objc_isa_assign) + << FixItHint::CreateInsertion(LHS.get()->getBeginLoc(), + "object_setClass(") + << FixItHint::CreateReplacement(SourceRange(OISA->getOpLoc(), OpLoc), + ",") + << FixItHint::CreateInsertion(RHSLocEnd, ")"); } else Diag(LHS.get()->getExprLoc(), diag::warn_objc_isa_assign); @@ -12258,13 +12517,14 @@ static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperatorKind Opc, if (isLeftBitwise || isRightBitwise) return; - SourceRange DiagRange = isLeftComp ? SourceRange(LHSExpr->getLocStart(), - OpLoc) - : SourceRange(OpLoc, RHSExpr->getLocEnd()); + SourceRange DiagRange = isLeftComp + ? SourceRange(LHSExpr->getBeginLoc(), OpLoc) + : SourceRange(OpLoc, RHSExpr->getEndLoc()); StringRef OpStr = isLeftComp ? LHSBO->getOpcodeStr() : RHSBO->getOpcodeStr(); - SourceRange ParensRange = isLeftComp ? - SourceRange(LHSBO->getRHS()->getLocStart(), RHSExpr->getLocEnd()) - : SourceRange(LHSExpr->getLocStart(), RHSBO->getLHS()->getLocEnd()); + SourceRange ParensRange = + isLeftComp + ? SourceRange(LHSBO->getRHS()->getBeginLoc(), RHSExpr->getEndLoc()) + : SourceRange(LHSExpr->getBeginLoc(), RHSBO->getLHS()->getEndLoc()); Self.Diag(OpLoc, diag::warn_precedence_bitwise_rel) << DiagRange << BinaryOperator::getOpcodeStr(Opc) << OpStr; @@ -12398,10 +12658,9 @@ static void DiagnoseShiftCompare(Sema &S, SourceLocation OpLoc, S.PDiag(diag::note_precedence_silence) << (Kind == OO_LessLess ? "<<" : ">>"), OCE->getSourceRange()); - SuggestParentheses(S, OpLoc, - S.PDiag(diag::note_evaluate_comparison_first), - SourceRange(OCE->getArg(1)->getLocStart(), - RHSExpr->getLocEnd())); + SuggestParentheses( + S, OpLoc, S.PDiag(diag::note_evaluate_comparison_first), + SourceRange(OCE->getArg(1)->getBeginLoc(), RHSExpr->getEndLoc())); } /// DiagnoseBinOpPrecedence - Emit warnings for expressions with tricky @@ -12643,6 +12902,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, break; case UO_AddrOf: resultType = CheckAddressOfOperand(Input, OpLoc); + CheckAddressOfNoDeref(InputExpr); RecordModifiableNonNullParam(*this, InputExpr); break; case UO_Deref: { @@ -12807,6 +13067,11 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, auto *UO = new (Context) UnaryOperator(Input.get(), Opc, resultType, VK, OK, OpLoc, CanOverflow); + + if (Opc == UO_Deref && UO->getType()->hasAttr(attr::NoDeref) && + !isa<ArrayType>(UO->getType().getDesugaredType(Context))) + ExprEvalContexts.back().PossibleDerefs.insert(UO); + // Convert the result back to a half vector. if (ConvertHalfVec) return convertVector(UO, Context.HalfTy, *this); @@ -13071,9 +13336,9 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, // FIXME: An integral constant expression? if (!Idx->isTypeDependent() && !Idx->isValueDependent() && !Idx->getType()->isIntegerType()) - return ExprError(Diag(Idx->getLocStart(), - diag::err_typecheck_subscript_not_integer) - << Idx->getSourceRange()); + return ExprError( + Diag(Idx->getBeginLoc(), diag::err_typecheck_subscript_not_integer) + << Idx->getSourceRange()); // Record this array index. Comps.push_back(OffsetOfNode(OC.LocStart, Exprs.size(), OC.LocEnd)); @@ -13294,7 +13559,7 @@ void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo, // Drop the parameters. FunctionProtoType::ExtProtoInfo EPI; EPI.HasTrailingReturn = false; - EPI.TypeQuals |= DeclSpec::TQ_const; + EPI.TypeQuals.addConst(); T = Context.getFunctionType(Context.DependentTy, None, EPI); Sig = Context.getTrivialTypeSourceInfo(T); } @@ -13365,7 +13630,7 @@ void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo, } else if (const FunctionProtoType *Fn = T->getAs<FunctionProtoType>()) { for (const auto &I : Fn->param_types()) { ParmVarDecl *Param = BuildParmVarDeclForTypedef( - CurBlock->TheDecl, ParamInfo.getLocStart(), I); + CurBlock->TheDecl, ParamInfo.getBeginLoc(), I); Params.push_back(Param); } } @@ -13421,6 +13686,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, PopExpressionEvaluationContext(); BlockScopeInfo *BSI = cast<BlockScopeInfo>(FunctionScopes.back()); + BlockDecl *BD = BSI->TheDecl; if (BSI->HasImplicitReturnType) deduceClosureReturnType(*BSI); @@ -13431,7 +13697,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, if (!BSI->ReturnType.isNull()) RetTy = BSI->ReturnType; - bool NoReturn = BSI->TheDecl->hasAttr<NoReturnAttr>(); + bool NoReturn = BD->hasAttr<NoReturnAttr>(); QualType BlockTy; // Set the captured variables on the block. @@ -13444,7 +13710,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, Cap.isNested(), Cap.getInitExpr()); Captures.push_back(NewCap); } - BSI->TheDecl->setCaptures(Context, Captures, BSI->CXXThisCaptureIndex != 0); + BD->setCaptures(Context, Captures, BSI->CXXThisCaptureIndex != 0); // If the user wrote a function type in some form, try to use that. if (!BSI->FunctionType.isNull()) { @@ -13469,7 +13735,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, } else { const FunctionProtoType *FPT = cast<FunctionProtoType>(FTy); FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); - EPI.TypeQuals = 0; // FIXME: silently? + EPI.TypeQuals = Qualifiers(); EPI.ExtInfo = Ext; BlockTy = Context.getFunctionType(RetTy, FPT->getParamTypes(), EPI); } @@ -13481,7 +13747,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, BlockTy = Context.getFunctionType(RetTy, None, EPI); } - DiagnoseUnusedParameters(BSI->TheDecl->parameters()); + DiagnoseUnusedParameters(BD->parameters()); BlockTy = Context.getBlockPointerType(BlockTy); // If needed, diagnose invalid gotos and switches in the block. @@ -13489,19 +13755,19 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, !PP.isCodeCompletionEnabled()) DiagnoseInvalidJumps(cast<CompoundStmt>(Body)); - BSI->TheDecl->setBody(cast<CompoundStmt>(Body)); + BD->setBody(cast<CompoundStmt>(Body)); if (Body && getCurFunction()->HasPotentialAvailabilityViolations) - DiagnoseUnguardedAvailabilityViolations(BSI->TheDecl); + DiagnoseUnguardedAvailabilityViolations(BD); // Try to apply the named return value optimization. We have to check again // if we can do this, though, because blocks keep return statements around // to deduce an implicit return type. if (getLangOpts().CPlusPlus && RetTy->isRecordType() && - !BSI->TheDecl->isDependentContext()) + !BD->isDependentContext()) computeNRVO(Body, BSI); - BlockExpr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy); + BlockExpr *Result = new (Context) BlockExpr(BD, BlockTy); AnalysisBasedWarnings::Policy WP = AnalysisWarnings.getDefaultPolicy(); PopFunctionScopeInfo(&WP, Result->getBlockDecl(), Result); @@ -13523,6 +13789,9 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, } } + if (getCurFunction()) + getCurFunction()->addBlock(BD); + return Result; } @@ -13544,7 +13813,7 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc, 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)); + return ExprError(Diag(E->getBeginLoc(), diag::err_va_arg_in_device)); } } @@ -13594,9 +13863,10 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc, if (!IsMS && !E->isTypeDependent() && !Context.hasSameType(VaListType, E->getType())) - return ExprError(Diag(E->getLocStart(), - diag::err_first_argument_to_va_arg_not_of_type_va_list) - << OrigExpr->getType() << E->getSourceRange()); + return ExprError( + Diag(E->getBeginLoc(), + diag::err_first_argument_to_va_arg_not_of_type_va_list) + << OrigExpr->getType() << E->getSourceRange()); if (!TInfo->getType()->isDependentType()) { if (RequireCompleteType(TInfo->getTypeLoc().getBeginLoc(), TInfo->getType(), @@ -13661,7 +13931,7 @@ ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) { bool Sema::ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&Exp, bool Diagnose) { - if (!getLangOpts().ObjC1) + if (!getLangOpts().ObjC) return false; const ObjCObjectPointerType *PT = DstType->getAs<ObjCObjectPointerType>(); @@ -13687,9 +13957,9 @@ bool Sema::ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&Exp, if (!SL || !SL->isAscii()) return false; if (Diagnose) { - Diag(SL->getLocStart(), diag::err_missing_atsign_prefix) - << FixItHint::CreateInsertion(SL->getLocStart(), "@"); - Exp = BuildObjCStringLiteral(SL->getLocStart(), SL).get(); + Diag(SL->getBeginLoc(), diag::err_missing_atsign_prefix) + << FixItHint::CreateInsertion(SL->getBeginLoc(), "@"); + Exp = BuildObjCStringLiteral(SL->getBeginLoc(), SL).get(); } return true; } @@ -13710,7 +13980,7 @@ static bool maybeDiagnoseAssignmentToFunction(Sema &S, QualType DstType, return !S.checkAddressOfFunctionIsAvailable(FD, /*Complain=*/true, - SrcExpr->getLocStart()); + SrcExpr->getBeginLoc()); } bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, @@ -13963,7 +14233,7 @@ ExprResult Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, VerifyICEDiagnoser &Diagnoser, bool AllowFold) { - SourceLocation DiagLoc = E->getLocStart(); + SourceLocation DiagLoc = E->getBeginLoc(); if (getLangOpts().CPlusPlus11) { // C++11 [expr.const]p5: @@ -14030,11 +14300,14 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, return ExprError(); } + if (!isa<ConstantExpr>(E)) + E = ConstantExpr::Create(Context, E); + // Circumvent ICE checking in C++11 to avoid evaluating the expression twice // in the non-ICE case. if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) { if (Result) - *Result = E->EvaluateKnownConstInt(Context); + *Result = E->EvaluateKnownConstIntCheckOverflow(Context); return E; } @@ -14165,6 +14438,51 @@ Sema::PushExpressionEvaluationContext( PushExpressionEvaluationContext(NewContext, ClosureContextDecl, ExprContext); } +namespace { + +const DeclRefExpr *CheckPossibleDeref(Sema &S, const Expr *PossibleDeref) { + PossibleDeref = PossibleDeref->IgnoreParenImpCasts(); + if (const auto *E = dyn_cast<UnaryOperator>(PossibleDeref)) { + if (E->getOpcode() == UO_Deref) + return CheckPossibleDeref(S, E->getSubExpr()); + } else if (const auto *E = dyn_cast<ArraySubscriptExpr>(PossibleDeref)) { + return CheckPossibleDeref(S, E->getBase()); + } else if (const auto *E = dyn_cast<MemberExpr>(PossibleDeref)) { + return CheckPossibleDeref(S, E->getBase()); + } else if (const auto E = dyn_cast<DeclRefExpr>(PossibleDeref)) { + QualType Inner; + QualType Ty = E->getType(); + if (const auto *Ptr = Ty->getAs<PointerType>()) + Inner = Ptr->getPointeeType(); + else if (const auto *Arr = S.Context.getAsArrayType(Ty)) + Inner = Arr->getElementType(); + else + return nullptr; + + if (Inner->hasAttr(attr::NoDeref)) + return E; + } + return nullptr; +} + +} // namespace + +void Sema::WarnOnPendingNoDerefs(ExpressionEvaluationContextRecord &Rec) { + for (const Expr *E : Rec.PossibleDerefs) { + const DeclRefExpr *DeclRef = CheckPossibleDeref(*this, E); + if (DeclRef) { + const ValueDecl *Decl = DeclRef->getDecl(); + Diag(E->getExprLoc(), diag::warn_dereference_of_noderef_type) + << Decl->getName() << E->getSourceRange(); + Diag(Decl->getLocation(), diag::note_previous_decl) << Decl->getName(); + } else { + Diag(E->getExprLoc(), diag::warn_dereference_of_noderef_type_no_decl) + << E->getSourceRange(); + } + } + Rec.PossibleDerefs.clear(); +} + void Sema::PopExpressionEvaluationContext() { ExpressionEvaluationContextRecord& Rec = ExprEvalContexts.back(); unsigned NumTypos = Rec.NumTypos; @@ -14193,7 +14511,7 @@ void Sema::PopExpressionEvaluationContext() { llvm_unreachable("Couldn't infer lambda error message."); for (const auto *L : Rec.Lambdas) - Diag(L->getLocStart(), D); + Diag(L->getBeginLoc(), D); } else { // Mark the capture expressions odr-used. This was deferred // during lambda expression creation. @@ -14204,6 +14522,8 @@ void Sema::PopExpressionEvaluationContext() { } } + WarnOnPendingNoDerefs(Rec); + // When are coming out of an unevaluated context, clear out any // temporaries that we may have created as part of the evaluation of // the expression in that context: they aren't relevant because they @@ -14224,11 +14544,8 @@ 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"); + // The global expression evaluation context record is never popped. + ExprEvalContexts.back().NumTypos += NumTypos; } void Sema::DiscardCleanupsInEvaluationContext() { @@ -14240,6 +14557,10 @@ void Sema::DiscardCleanupsInEvaluationContext() { } ExprResult Sema::HandleExprEvaluationContextForTypeof(Expr *E) { + ExprResult Result = CheckPlaceholderExpr(E); + if (Result.isInvalid()) + return ExprError(); + E = Result.get(); if (!E->getType()->isVariablyModifiedType()) return E; return TransformToPotentiallyEvaluated(E); @@ -14641,8 +14962,10 @@ static bool captureInBlock(BlockScopeInfo *BSI, VarDecl *Var, Expr *CopyExpr = nullptr; bool ByRef = false; - // Blocks are not allowed to capture arrays. - if (CaptureType->isArrayType()) { + // Blocks are not allowed to capture arrays, excepting OpenCL. + // OpenCL v2.0 s1.12.5 (revision 40): arrays are captured by reference + // (decayed to pointers). + if (!S.getLangOpts().OpenCL && CaptureType->isArrayType()) { if (BuildAndDiagnose) { S.Diag(Loc, diag::err_ref_array_type); S.Diag(Var->getLocation(), diag::note_previous_decl) @@ -14665,15 +14988,15 @@ static bool captureInBlock(BlockScopeInfo *BSI, VarDecl *Var, // Warn about implicitly autoreleasing indirect parameters captured by blocks. if (const auto *PT = CaptureType->getAs<PointerType>()) { // This function finds out whether there is an AttributedType of kind - // attr_objc_ownership in Ty. The existence of AttributedType of kind - // attr_objc_ownership implies __autoreleasing was explicitly specified + // attr::ObjCOwnership in Ty. The existence of AttributedType of kind + // attr::ObjCOwnership implies __autoreleasing was explicitly specified // rather than being added implicitly by the compiler. auto IsObjCOwnershipAttributedType = [](QualType Ty) { while (const auto *AttrTy = Ty->getAs<AttributedType>()) { - if (AttrTy->getAttrKind() == AttributedType::attr_objc_ownership) + if (AttrTy->getAttrKind() == attr::ObjCOwnership) return true; - // Peel off AttributedTypes that are not of kind objc_ownership. + // Peel off AttributedTypes that are not of kind ObjCOwnership. Ty = AttrTy->getModifiedType(); } @@ -14722,9 +15045,8 @@ static bool captureInBlock(BlockScopeInfo *BSI, VarDecl *Var, // According to the blocks spec, the capture of a variable from // the stack requires a const copy constructor. This is not true // of the copy/move done to move a __block variable to the heap. - Expr *DeclRef = new (S.Context) DeclRefExpr(Var, Nested, - DeclRefType.withConst(), - VK_LValue, Loc); + Expr *DeclRef = new (S.Context) DeclRefExpr( + S.Context, Var, Nested, DeclRefType.withConst(), VK_LValue, Loc); ExprResult Result = S.PerformCopyInitialization( @@ -14800,8 +15122,8 @@ static bool captureInCapturedRegion(CapturedRegionScopeInfo *RSI, if (S.getLangOpts().OpenMP && RSI->CapRegionKind == CR_OpenMP) S.setOpenMPCaptureKind(Field, Var, RSI->OpenMPLevel); - CopyExpr = new (S.Context) DeclRefExpr(Var, RefersToCapturedVariable, - DeclRefType, VK_LValue, Loc); + CopyExpr = new (S.Context) DeclRefExpr( + S.Context, Var, RefersToCapturedVariable, DeclRefType, VK_LValue, Loc); Var->setReferenced(true); Var->markUsed(S.Context); } @@ -14828,6 +15150,21 @@ static void addAsFieldToClosureType(Sema &S, LambdaScopeInfo *LSI, = FieldDecl::Create(S.Context, Lambda, Loc, Loc, nullptr, FieldType, S.Context.getTrivialTypeSourceInfo(FieldType, Loc), nullptr, false, ICIS_NoInit); + // If the variable being captured has an invalid type, mark the lambda class + // as invalid as well. + if (!FieldType->isDependentType()) { + if (S.RequireCompleteType(Loc, FieldType, diag::err_field_incomplete)) { + Lambda->setInvalidDecl(); + Field->setInvalidDecl(); + } else { + NamedDecl *Def; + FieldType->isIncompleteType(&Def); + if (Def && Def->isInvalidDecl()) { + Lambda->setInvalidDecl(); + Field->setInvalidDecl(); + } + } + } Field->setImplicit(true); Field->setAccess(AS_private); Lambda->addDecl(Field); @@ -15023,7 +15360,7 @@ bool Sema::tryCaptureVariable( Diag(ExprLoc, diag::err_lambda_impcap) << Var->getDeclName(); Diag(Var->getLocation(), diag::note_previous_decl) << Var->getDeclName(); - Diag(LSI->Lambda->getLocStart(), diag::note_lambda_decl); + Diag(LSI->Lambda->getBeginLoc(), diag::note_lambda_decl); } else diagnoseUncapturableValueReference(*this, ExprLoc, Var, DC); } @@ -15077,7 +15414,7 @@ bool Sema::tryCaptureVariable( Diag(Var->getLocation(), diag::note_previous_decl) << Var->getDeclName(); if (cast<LambdaScopeInfo>(CSI)->Lambda) - Diag(cast<LambdaScopeInfo>(CSI)->Lambda->getLocStart(), + Diag(cast<LambdaScopeInfo>(CSI)->Lambda->getBeginLoc(), 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 @@ -15435,8 +15772,8 @@ void Sema::MarkMemberReferenced(MemberExpr *E) { if (Method->isPure()) MightBeOdrUse = false; } - SourceLocation Loc = E->getMemberLoc().isValid() ? - E->getMemberLoc() : E->getLocStart(); + SourceLocation Loc = + E->getMemberLoc().isValid() ? E->getMemberLoc() : E->getBeginLoc(); MarkExprReferenced(*this, Loc, E->getMemberDecl(), E, MightBeOdrUse); } @@ -15532,34 +15869,34 @@ namespace { } void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { - S.MarkFunctionReferenced(E->getLocStart(), - const_cast<CXXDestructorDecl*>(E->getTemporary()->getDestructor())); + S.MarkFunctionReferenced( + E->getBeginLoc(), + const_cast<CXXDestructorDecl *>(E->getTemporary()->getDestructor())); Visit(E->getSubExpr()); } void VisitCXXNewExpr(CXXNewExpr *E) { if (E->getOperatorNew()) - S.MarkFunctionReferenced(E->getLocStart(), E->getOperatorNew()); + S.MarkFunctionReferenced(E->getBeginLoc(), E->getOperatorNew()); if (E->getOperatorDelete()) - S.MarkFunctionReferenced(E->getLocStart(), E->getOperatorDelete()); + S.MarkFunctionReferenced(E->getBeginLoc(), E->getOperatorDelete()); Inherited::VisitCXXNewExpr(E); } void VisitCXXDeleteExpr(CXXDeleteExpr *E) { if (E->getOperatorDelete()) - S.MarkFunctionReferenced(E->getLocStart(), E->getOperatorDelete()); + S.MarkFunctionReferenced(E->getBeginLoc(), E->getOperatorDelete()); QualType Destroyed = S.Context.getBaseElementType(E->getDestroyedType()); if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) { CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl()); - S.MarkFunctionReferenced(E->getLocStart(), - S.LookupDestructor(Record)); + S.MarkFunctionReferenced(E->getBeginLoc(), S.LookupDestructor(Record)); } Inherited::VisitCXXDeleteExpr(E); } void VisitCXXConstructExpr(CXXConstructExpr *E) { - S.MarkFunctionReferenced(E->getLocStart(), E->getConstructor()); + S.MarkFunctionReferenced(E->getBeginLoc(), E->getConstructor()); Inherited::VisitCXXConstructExpr(E); } @@ -15730,7 +16067,7 @@ void Sema::DiagnoseAssignmentAsCondition(Expr *E) { Diag(Loc, diagnostic) << E->getSourceRange(); - SourceLocation Open = E->getLocStart(); + SourceLocation Open = E->getBeginLoc(); SourceLocation Close = getLocForEndOfToken(E->getSourceRange().getEnd()); Diag(Loc, diag::note_condition_assign_silence) << FixItHint::CreateInsertion(Open, "(") @@ -15748,7 +16085,7 @@ void Sema::DiagnoseAssignmentAsCondition(Expr *E) { /// that the user intended an assignment used as condition. void Sema::DiagnoseEqualityWithExtraParens(ParenExpr *ParenE) { // Don't warn if the parens came from a macro. - SourceLocation parenLoc = ParenE->getLocStart(); + SourceLocation parenLoc = ParenE->getBeginLoc(); if (parenLoc.isInvalid() || parenLoc.isMacroID()) return; // Don't warn for dependent expressions. @@ -16211,7 +16548,7 @@ ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *E, ValueDecl *VD) { DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E); if (DRE && Proto && Proto->getParamTypes().empty() && Proto->isVariadic()) { SourceLocation Loc = FD->getLocation(); - FunctionDecl *NewFD = FunctionDecl::Create(FD->getASTContext(), + FunctionDecl *NewFD = FunctionDecl::Create(S.Context, FD->getDeclContext(), Loc, Loc, FD->getNameInfo().getName(), DestType, FD->getTypeSourceInfo(), @@ -16439,25 +16776,29 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) { auto *FD = cast<FunctionDecl>(DRE->getDecl()); if (FD->getBuiltinID() == Builtin::BI__noop) { E = ImpCastExprToType(E, Context.getPointerType(FD->getType()), - CK_BuiltinFnToFnPtr).get(); - return new (Context) CallExpr(Context, E, None, Context.IntTy, - VK_RValue, SourceLocation()); + CK_BuiltinFnToFnPtr) + .get(); + return CallExpr::Create(Context, E, /*Args=*/{}, Context.IntTy, + VK_RValue, SourceLocation()); } } - Diag(E->getLocStart(), diag::err_builtin_fn_use); + Diag(E->getBeginLoc(), diag::err_builtin_fn_use); return ExprError(); } // Expressions of unknown type. case BuiltinType::OMPArraySection: - Diag(E->getLocStart(), diag::err_omp_array_section_use); + Diag(E->getBeginLoc(), diag::err_omp_array_section_use); return ExprError(); // Everything else should be impossible. #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ case BuiltinType::Id: #include "clang/Basic/OpenCLImageTypes.def" +#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ + case BuiltinType::Id: +#include "clang/Basic/OpenCLExtensionTypes.def" #define BUILTIN_TYPE(Id, SingletonId) case BuiltinType::Id: #define PLACEHOLDER_TYPE(Id, SingletonId) #include "clang/AST/BuiltinTypes.def" |