diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp | 948 |
1 files changed, 596 insertions, 352 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp index 6499cb5..5d0c605 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp @@ -24,6 +24,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" +#include "clang/AST/ExprOpenMP.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/PartialDiagnostic.h" @@ -326,18 +327,16 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, if (getLangOpts().CPlusPlus && isa<FunctionDecl>(D)) { // If there were any diagnostics suppressed by template argument deduction, // emit them now. - SuppressedDiagnosticsMap::iterator - Pos = SuppressedDiagnostics.find(D->getCanonicalDecl()); + auto Pos = SuppressedDiagnostics.find(D->getCanonicalDecl()); if (Pos != SuppressedDiagnostics.end()) { - SmallVectorImpl<PartialDiagnosticAt> &Suppressed = Pos->second; - for (unsigned I = 0, N = Suppressed.size(); I != N; ++I) - Diag(Suppressed[I].first, Suppressed[I].second); + for (const PartialDiagnosticAt &Suppressed : Pos->second) + Diag(Suppressed.first, Suppressed.second); // Clear out the list of suppressed diagnostics, so that we don't emit // them again for this specialization. However, we don't obsolete this // entry from the table, because we want to avoid ever emitting these // diagnostics again. - Suppressed.clear(); + Pos->second.clear(); } // C++ [basic.start.main]p3: @@ -348,8 +347,10 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, // See if this is an auto-typed variable whose initializer we are parsing. if (ParsingInitForAutoVars.count(D)) { + const AutoType *AT = cast<VarDecl>(D)->getType()->getContainedAutoType(); + Diag(Loc, diag::err_auto_variable_cannot_appear_in_own_initializer) - << D->getDeclName(); + << D->getDeclName() << (unsigned)AT->getKeyword(); return true; } @@ -464,7 +465,7 @@ void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc, // 'nil' for ObjC methods, where it's much more likely that the // variadic arguments form a list of object pointers. SourceLocation MissingNilLoc - = PP.getLocForEndOfToken(sentinelExpr->getLocEnd()); + = getLocForEndOfToken(sentinelExpr->getLocEnd()); std::string NullValue; if (calleeType == CT_Method && PP.isMacroDefined("nil")) NullValue = "nil"; @@ -493,7 +494,7 @@ SourceRange Sema::getExprRange(Expr *E) const { //===----------------------------------------------------------------------===// /// DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4). -ExprResult Sema::DefaultFunctionArrayConversion(Expr *E) { +ExprResult Sema::DefaultFunctionArrayConversion(Expr *E, bool Diagnose) { // Handle any placeholder expressions which made it here. if (E->getType()->isPlaceholderType()) { ExprResult result = CheckPlaceholderExpr(E); @@ -508,9 +509,16 @@ ExprResult Sema::DefaultFunctionArrayConversion(Expr *E) { // If we are here, we are not calling a function but taking // its address (which is not allowed in OpenCL v1.0 s6.8.a.3). if (getLangOpts().OpenCL) { - Diag(E->getExprLoc(), diag::err_opencl_taking_function_address); + if (Diagnose) + Diag(E->getExprLoc(), diag::err_opencl_taking_function_address); return ExprError(); } + + if (auto *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts())) + if (auto *FD = dyn_cast<FunctionDecl>(DRE->getDecl())) + if (!checkAddressOfFunctionIsAvailable(FD, Diagnose, E->getExprLoc())) + return ExprError(); + E = ImpCastExprToType(E, Context.getPointerType(Ty), CK_FunctionToPointerDecay).get(); } else if (Ty->isArrayType()) { @@ -579,7 +587,7 @@ static void DiagnoseDirectIsaAccess(Sema &S, const ObjCIvarRefExpr *OIRE, &S.Context.Idents.get("object_setClass"), SourceLocation(), S.LookupOrdinaryName); if (ObjectSetClass) { - SourceLocation RHSLocEnd = S.PP.getLocForEndOfToken(RHS->getLocEnd()); + 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(), @@ -676,6 +684,11 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) { if (T.hasQualifiers()) T = T.getUnqualifiedType(); + // Under the MS ABI, lock down the inheritance model now. + if (T->isMemberPointerType() && + Context.getTargetInfo().getCXXABI().isMicrosoft()) + (void)isCompleteType(E->getExprLoc(), T); + UpdateMarkingForLValueToRValue(E); // Loading a __weak object implicitly retains the value, so we need a cleanup to @@ -699,8 +712,8 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) { return Res; } -ExprResult Sema::DefaultFunctionArrayLvalueConversion(Expr *E) { - ExprResult Res = DefaultFunctionArrayConversion(E); +ExprResult Sema::DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose) { + ExprResult Res = DefaultFunctionArrayConversion(E, Diagnose); if (Res.isInvalid()) return ExprError(); Res = DefaultLvalueConversion(Res.get()); @@ -1349,11 +1362,13 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc, ArrayRef<Expr *> Exprs) { unsigned NumAssocs = Types.size(); assert(NumAssocs == Exprs.size()); - if (ControllingExpr->getType()->isPlaceholderType()) { - ExprResult result = CheckPlaceholderExpr(ControllingExpr); - if (result.isInvalid()) return ExprError(); - ControllingExpr = result.get(); - } + + // Decay and strip qualifiers for the controlling expression type, and handle + // placeholder type replacement. See committee discussion from WG14 DR423. + ExprResult R = DefaultFunctionArrayLvalueConversion(ControllingExpr); + if (R.isInvalid()) + return ExprError(); + ControllingExpr = R.get(); // The controlling expression is an unevaluated operand, so side effects are // likely unintended. @@ -1445,12 +1460,11 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc, Diag(ControllingExpr->getLocStart(), diag::err_generic_sel_multi_match) << ControllingExpr->getSourceRange() << ControllingExpr->getType() << (unsigned) CompatIndices.size(); - for (SmallVectorImpl<unsigned>::iterator I = CompatIndices.begin(), - E = CompatIndices.end(); I != E; ++I) { - Diag(Types[*I]->getTypeLoc().getBeginLoc(), + for (unsigned I : CompatIndices) { + Diag(Types[I]->getTypeLoc().getBeginLoc(), diag::note_compat_assoc) - << Types[*I]->getTypeLoc().getSourceRange() - << Types[*I]->getType(); + << Types[I]->getTypeLoc().getSourceRange() + << Types[I]->getType(); } return ExprError(); } @@ -1533,8 +1547,8 @@ Sema::ActOnStringLiteral(ArrayRef<Token> StringToks, Scope *UDLScope) { return ExprError(); SmallVector<SourceLocation, 4> StringTokLocs; - for (unsigned i = 0; i != StringToks.size(); ++i) - StringTokLocs.push_back(StringToks[i].getLocation()); + for (const Token &Tok : StringToks) + StringTokLocs.push_back(Tok.getLocation()); QualType CharTy = Context.CharTy; StringLiteral::StringKind Kind = StringLiteral::Ascii; @@ -1697,7 +1711,7 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, MarkDeclRefReferenced(E); - if (getLangOpts().ObjCARCWeak && isa<VarDecl>(D) && + if (getLangOpts().ObjCWeak && isa<VarDecl>(D) && Ty.getObjCLifetime() == Qualifiers::OCL_Weak && !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, E->getLocStart())) recordUseOfEvaluatedWeak(E); @@ -1762,10 +1776,9 @@ static void emitEmptyLookupTypoDiagnostic( std::string CorrectedStr = TC.getAsString(SemaRef.getLangOpts()); bool DroppedSpecifier = TC.WillReplaceSpecifier() && Typo.getAsString() == CorrectedStr; - unsigned NoteID = - (TC.getCorrectionDecl() && isa<ImplicitParamDecl>(TC.getCorrectionDecl())) - ? diag::note_implicit_param_decl - : diag::note_previous_decl; + unsigned NoteID = TC.getCorrectionDeclAs<ImplicitParamDecl>() + ? diag::note_implicit_param_decl + : diag::note_previous_decl; if (!Ctx) SemaRef.diagnoseTypo(TC, SemaRef.PDiag(DiagnosticSuggestID) << Typo, SemaRef.PDiag(NoteID)); @@ -1799,8 +1812,7 @@ Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, // unqualified lookup. This is useful when (for example) the // original lookup would not have found something because it was a // dependent name. - DeclContext *DC = (SS.isEmpty() && !CallsUndergoingInstantiation.empty()) - ? CurContext : nullptr; + DeclContext *DC = SS.isEmpty() ? CurContext : nullptr; while (DC) { if (isa<CXXRecordDecl>(DC)) { LookupQualifiedName(R, DC); @@ -1819,7 +1831,6 @@ Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, bool isInstance = CurMethod && CurMethod->isInstance() && DC == CurMethod->getParent() && !isDefaultArgument; - // Give a code modification hint to insert 'this->'. // TODO: fixit for inserting 'Base<T>::' in the other cases. @@ -1829,46 +1840,14 @@ Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, if (isInstance) { Diag(R.getNameLoc(), diagnostic) << Name << FixItHint::CreateInsertion(R.getNameLoc(), "this->"); - UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>( - CallsUndergoingInstantiation.back()->getCallee()); - - CXXMethodDecl *DepMethod; - if (CurMethod->isDependentContext()) - DepMethod = CurMethod; - else if (CurMethod->getTemplatedKind() == - FunctionDecl::TK_FunctionTemplateSpecialization) - DepMethod = cast<CXXMethodDecl>(CurMethod->getPrimaryTemplate()-> - getInstantiatedFromMemberTemplate()->getTemplatedDecl()); - else - DepMethod = cast<CXXMethodDecl>( - CurMethod->getInstantiatedFromMemberFunction()); - assert(DepMethod && "No template pattern found"); - - QualType DepThisType = DepMethod->getThisType(Context); CheckCXXThisCapture(R.getNameLoc()); - CXXThisExpr *DepThis = new (Context) CXXThisExpr( - R.getNameLoc(), DepThisType, false); - TemplateArgumentListInfo TList; - if (ULE->hasExplicitTemplateArgs()) - ULE->copyTemplateArgumentsInto(TList); - - CXXScopeSpec SS; - SS.Adopt(ULE->getQualifierLoc()); - CXXDependentScopeMemberExpr *DepExpr = - CXXDependentScopeMemberExpr::Create( - Context, DepThis, DepThisType, true, SourceLocation(), - SS.getWithLocInContext(Context), - ULE->getTemplateKeywordLoc(), nullptr, - R.getLookupNameInfo(), - ULE->hasExplicitTemplateArgs() ? &TList : nullptr); - CallsUndergoingInstantiation.back()->setCallee(DepExpr); } else { Diag(R.getNameLoc(), diagnostic) << Name; } // Do we really want to note all of these? - for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) - Diag((*I)->getLocation(), diag::note_dependent_var_use); + for (NamedDecl *D : R) + Diag(D->getLocation(), diag::note_dependent_var_use); // Return true if we are inside a default argument instantiation // and the found name refers to an instance member function, otherwise @@ -1923,28 +1902,26 @@ Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, bool AcceptableWithRecovery = false; bool AcceptableWithoutRecovery = false; - NamedDecl *ND = Corrected.getCorrectionDecl(); + NamedDecl *ND = Corrected.getFoundDecl(); if (ND) { if (Corrected.isOverloaded()) { OverloadCandidateSet OCS(R.getNameLoc(), OverloadCandidateSet::CSK_Normal); OverloadCandidateSet::iterator Best; - for (TypoCorrection::decl_iterator CD = Corrected.begin(), - CDEnd = Corrected.end(); - CD != CDEnd; ++CD) { + for (NamedDecl *CD : Corrected) { if (FunctionTemplateDecl *FTD = - dyn_cast<FunctionTemplateDecl>(*CD)) + dyn_cast<FunctionTemplateDecl>(CD)) AddTemplateOverloadCandidate( FTD, DeclAccessPair::make(FTD, AS_none), ExplicitTemplateArgs, Args, OCS); - else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*CD)) + else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) if (!ExplicitTemplateArgs || ExplicitTemplateArgs->size() == 0) AddOverloadCandidate(FD, DeclAccessPair::make(FD, AS_none), Args, OCS); } switch (OCS.BestViableFunction(*this, R.getNameLoc(), Best)) { case OR_Success: - ND = Best->Function; + ND = Best->FoundDecl; Corrected.setCorrectionDecl(ND); break; default: @@ -1966,15 +1943,16 @@ Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, R.setNamingClass(Record); } - AcceptableWithRecovery = - isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND); + auto *UnderlyingND = ND->getUnderlyingDecl(); + AcceptableWithRecovery = isa<ValueDecl>(UnderlyingND) || + isa<FunctionTemplateDecl>(UnderlyingND); // FIXME: If we ended up with a typo for a type name or // Objective-C class name, we're in trouble because the parser // is in the wrong place to recover. Suggest the typo // correction, but don't make it a fix-it since we're not going // to recover well anyway. AcceptableWithoutRecovery = - isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND); + isa<TypeDecl>(UnderlyingND) || isa<ObjCInterfaceDecl>(UnderlyingND); } else { // FIXME: We found a keyword. Suggest it, but don't provide a fix-it // because we aren't able to recover. @@ -1982,8 +1960,7 @@ Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, } if (AcceptableWithRecovery || AcceptableWithoutRecovery) { - unsigned NoteID = (Corrected.getCorrectionDecl() && - isa<ImplicitParamDecl>(Corrected.getCorrectionDecl())) + unsigned NoteID = Corrected.getCorrectionDeclAs<ImplicitParamDecl>() ? diag::note_implicit_param_decl : diag::note_previous_decl; if (SS.isEmpty()) @@ -2278,7 +2255,7 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, if (MightBeImplicitMember) return BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc, - R, TemplateArgs); + R, TemplateArgs, S); } if (TemplateArgs || TemplateKWLoc.isValid()) { @@ -2302,11 +2279,9 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, /// declaration name, generally during template instantiation. /// There's a large number of things which don't need to be done along /// this path. -ExprResult -Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS, - const DeclarationNameInfo &NameInfo, - bool IsAddressOfOperand, - TypeSourceInfo **RecoveryTSI) { +ExprResult Sema::BuildQualifiedDeclarationNameExpr( + CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, + bool IsAddressOfOperand, const Scope *S, TypeSourceInfo **RecoveryTSI) { DeclContext *DC = computeDeclContext(SS, false); if (!DC) return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(), @@ -2373,7 +2348,7 @@ Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS, if (!R.empty() && (*R.begin())->isCXXClassMember() && !IsAddressOfOperand) return BuildPossibleImplicitMemberExpr(SS, /*TemplateKWLoc=*/SourceLocation(), - R, /*TemplateArgs=*/nullptr); + R, /*TemplateArgs=*/nullptr, S); return BuildDeclarationNameExpr(SS, R, /* ADL */ false); } @@ -2615,7 +2590,7 @@ Sema::PerformObjectMemberConversion(Expr *From, // In C++98, the qualifier type doesn't actually have to be a base // type of the object type, in which case we just ignore it. // Otherwise build the appropriate casts. - if (IsDerivedFrom(FromRecordType, QRecordType)) { + if (IsDerivedFrom(FromLoc, FromRecordType, QRecordType)) { CXXCastPath BasePath; if (CheckDerivedToBaseConversion(FromRecordType, QRecordType, FromLoc, FromRange, &BasePath)) @@ -2651,7 +2626,7 @@ Sema::PerformObjectMemberConversion(Expr *From, // We only need to do this if the naming-class to declaring-class // conversion is non-trivial. if (!Context.hasSameUnqualifiedType(FromRecordType, URecordType)) { - assert(IsDerivedFrom(FromRecordType, URecordType)); + assert(IsDerivedFrom(FromLoc, FromRecordType, URecordType)); CXXCastPath BasePath; if (CheckDerivedToBaseConversion(FromRecordType, URecordType, FromLoc, FromRange, &BasePath)) @@ -2698,9 +2673,7 @@ bool Sema::UseArgumentDependentLookup(const CXXScopeSpec &SS, // Turn off ADL when we find certain kinds of declarations during // normal lookup: - for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) { - NamedDecl *D = *I; - + for (NamedDecl *D : R) { // C++0x [basic.lookup.argdep]p3: // -- a declaration of a class member // Since using decls preserve this property, we check this on the @@ -3355,13 +3328,6 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { // Get the value in the widest-possible width. unsigned MaxWidth = Context.getTargetInfo().getIntMaxTWidth(); - // The microsoft literal suffix extensions support 128-bit literals, which - // may be wider than [u]intmax_t. - // FIXME: Actually, they don't. We seem to have accidentally invented the - // i128 suffix. - if (Literal.MicrosoftInteger == 128 && MaxWidth < 128 && - Context.getTargetInfo().hasInt128Type()) - MaxWidth = 128; llvm::APInt ResultVal(MaxWidth, 0); if (Literal.GetIntegerValue(ResultVal)) { @@ -3384,12 +3350,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { // Microsoft specific integer suffixes are explicitly sized. if (Literal.MicrosoftInteger) { - if (Literal.MicrosoftInteger > MaxWidth) { - // If this target doesn't support __int128, error and force to ull. - Diag(Tok.getLocation(), diag::err_int128_unsupported); - Width = MaxWidth; - Ty = Context.getIntMaxType(); - } else if (Literal.MicrosoftInteger == 8 && !Literal.isUnsigned) { + if (Literal.MicrosoftInteger == 8 && !Literal.isUnsigned) { Width = 8; Ty = Context.CharTy; } else { @@ -3726,7 +3687,7 @@ static bool CheckAlignOfExpr(Sema &S, Expr *E) { return false; if (E->getObjectKind() == OK_BitField) { - S.Diag(E->getExprLoc(), diag::err_sizeof_alignof_bitfield) + S.Diag(E->getExprLoc(), diag::err_sizeof_alignof_typeof_bitfield) << 1 << E->getSourceRange(); return true; } @@ -3828,7 +3789,7 @@ Sema::CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc, Diag(E->getExprLoc(), diag::err_openmp_default_simd_align_expr); isInvalid = true; } else if (E->refersToBitField()) { // C99 6.5.3.4p1. - Diag(E->getExprLoc(), diag::err_sizeof_alignof_bitfield) << 0; + Diag(E->getExprLoc(), diag::err_sizeof_alignof_typeof_bitfield) << 0; isInvalid = true; } else { isInvalid = CheckUnaryExprOrTypeTraitOperand(E, UETT_SizeOf); @@ -3854,7 +3815,7 @@ Sema::CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc, ExprResult Sema::ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc, UnaryExprOrTypeTrait ExprKind, bool IsType, - void *TyOrEx, const SourceRange &ArgRange) { + void *TyOrEx, SourceRange ArgRange) { // If error parsing type, ignore. if (!TyOrEx) return ExprError(); @@ -3940,9 +3901,21 @@ static bool checkArithmeticOnObjCPointer(Sema &S, return true; } +static bool isMSPropertySubscriptExpr(Sema &S, Expr *Base) { + auto *BaseNoParens = Base->IgnoreParens(); + if (auto *MSProp = dyn_cast<MSPropertyRefExpr>(BaseNoParens)) + return MSProp->getPropertyDecl()->getType()->isArrayType(); + return isa<MSPropertySubscriptExpr>(BaseNoParens); +} + ExprResult Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc, Expr *idx, SourceLocation rbLoc) { + if (base && !base->getType().isNull() && + base->getType()->isSpecificPlaceholderType(BuiltinType::OMPArraySection)) + return ActOnOMPArraySectionExpr(base, lbLoc, idx, SourceLocation(), + /*Length=*/nullptr, rbLoc); + // Since this might be a postfix expression, get rid of ParenListExprs. if (isa<ParenListExpr>(base)) { ExprResult result = MaybeConvertParenListExprToParenExpr(S, base); @@ -3955,10 +3928,15 @@ Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc, // operand might be an overloadable type, in which case the overload // resolution for the operator overload should get the first crack // at the overload. + bool IsMSPropertySubscript = false; if (base->getType()->isNonOverloadPlaceholderType()) { - ExprResult result = CheckPlaceholderExpr(base); - if (result.isInvalid()) return ExprError(); - base = result.get(); + IsMSPropertySubscript = isMSPropertySubscriptExpr(*this, base); + if (!IsMSPropertySubscript) { + ExprResult result = CheckPlaceholderExpr(base); + if (result.isInvalid()) + return ExprError(); + base = result.get(); + } } if (idx->getType()->isNonOverloadPlaceholderType()) { ExprResult result = CheckPlaceholderExpr(idx); @@ -3973,6 +3951,21 @@ Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc, VK_LValue, OK_Ordinary, rbLoc); } + // MSDN, property (C++) + // https://msdn.microsoft.com/en-us/library/yhfk0thd(v=vs.120).aspx + // This attribute can also be used in the declaration of an empty array in a + // class or structure definition. For example: + // __declspec(property(get=GetX, put=PutX)) int x[]; + // The above statement indicates that x[] can be used with one or more array + // indices. In this case, i=p->x[a][b] will be turned into i=p->GetX(a, b), + // and p->x[a][b] = i will be turned into p->PutX(a, b, i); + if (IsMSPropertySubscript) { + // Build MS property subscript expression if base is MS property reference + // or MS property subscript. + return new (Context) MSPropertySubscriptExpr( + base, idx, Context.PseudoObjectTy, VK_LValue, OK_Ordinary, rbLoc); + } + // Use C++ overloaded-operator rules if either operand has record // type. The spec says to do this if either type is *overloadable*, // but enum types can't declare subscript operators or conversion @@ -3991,6 +3984,139 @@ Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc, return CreateBuiltinArraySubscriptExpr(base, lbLoc, idx, rbLoc); } +ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, + Expr *LowerBound, + SourceLocation ColonLoc, Expr *Length, + SourceLocation RBLoc) { + if (Base->getType()->isPlaceholderType() && + !Base->getType()->isSpecificPlaceholderType( + BuiltinType::OMPArraySection)) { + ExprResult Result = CheckPlaceholderExpr(Base); + if (Result.isInvalid()) + return ExprError(); + Base = Result.get(); + } + if (LowerBound && LowerBound->getType()->isNonOverloadPlaceholderType()) { + ExprResult Result = CheckPlaceholderExpr(LowerBound); + if (Result.isInvalid()) + return ExprError(); + LowerBound = Result.get(); + } + if (Length && Length->getType()->isNonOverloadPlaceholderType()) { + ExprResult Result = CheckPlaceholderExpr(Length); + if (Result.isInvalid()) + return ExprError(); + Length = Result.get(); + } + + // Build an unanalyzed expression if either operand is type-dependent. + if (Base->isTypeDependent() || + (LowerBound && + (LowerBound->isTypeDependent() || LowerBound->isValueDependent())) || + (Length && (Length->isTypeDependent() || Length->isValueDependent()))) { + return new (Context) + OMPArraySectionExpr(Base, LowerBound, Length, Context.DependentTy, + VK_LValue, OK_Ordinary, ColonLoc, RBLoc); + } + + // Perform default conversions. + QualType OriginalTy = OMPArraySectionExpr::getBaseOriginalType(Base); + QualType ResultTy; + if (OriginalTy->isAnyPointerType()) { + ResultTy = OriginalTy->getPointeeType(); + } else if (OriginalTy->isArrayType()) { + ResultTy = OriginalTy->getAsArrayTypeUnsafe()->getElementType(); + } else { + return ExprError( + Diag(Base->getExprLoc(), diag::err_omp_typecheck_section_value) + << Base->getSourceRange()); + } + // C99 6.5.2.1p1 + if (LowerBound) { + auto Res = PerformOpenMPImplicitIntegerConversion(LowerBound->getExprLoc(), + LowerBound); + if (Res.isInvalid()) + return ExprError(Diag(LowerBound->getExprLoc(), + diag::err_omp_typecheck_section_not_integer) + << 0 << LowerBound->getSourceRange()); + LowerBound = Res.get(); + + if (LowerBound->getType()->isSpecificBuiltinType(BuiltinType::Char_S) || + LowerBound->getType()->isSpecificBuiltinType(BuiltinType::Char_U)) + Diag(LowerBound->getExprLoc(), diag::warn_omp_section_is_char) + << 0 << LowerBound->getSourceRange(); + } + if (Length) { + auto Res = + PerformOpenMPImplicitIntegerConversion(Length->getExprLoc(), Length); + if (Res.isInvalid()) + return ExprError(Diag(Length->getExprLoc(), + diag::err_omp_typecheck_section_not_integer) + << 1 << Length->getSourceRange()); + Length = Res.get(); + + if (Length->getType()->isSpecificBuiltinType(BuiltinType::Char_S) || + Length->getType()->isSpecificBuiltinType(BuiltinType::Char_U)) + Diag(Length->getExprLoc(), diag::warn_omp_section_is_char) + << 1 << Length->getSourceRange(); + } + + // C99 6.5.2.1p1: "shall have type "pointer to *object* type". Similarly, + // C++ [expr.sub]p1: The type "T" shall be a completely-defined object + // type. Note that functions are not objects, and that (in C99 parlance) + // incomplete types are not object types. + if (ResultTy->isFunctionType()) { + Diag(Base->getExprLoc(), diag::err_omp_section_function_type) + << ResultTy << Base->getSourceRange(); + return ExprError(); + } + + if (RequireCompleteType(Base->getExprLoc(), ResultTy, + diag::err_omp_section_incomplete_type, Base)) + return ExprError(); + + if (LowerBound) { + llvm::APSInt LowerBoundValue; + if (LowerBound->EvaluateAsInt(LowerBoundValue, Context)) { + // OpenMP 4.0, [2.4 Array Sections] + // The lower-bound and length must evaluate to non-negative integers. + if (LowerBoundValue.isNegative()) { + Diag(LowerBound->getExprLoc(), diag::err_omp_section_negative) + << 0 << LowerBoundValue.toString(/*Radix=*/10, /*Signed=*/true) + << LowerBound->getSourceRange(); + return ExprError(); + } + } + } + + if (Length) { + llvm::APSInt LengthValue; + if (Length->EvaluateAsInt(LengthValue, Context)) { + // OpenMP 4.0, [2.4 Array Sections] + // The lower-bound and length must evaluate to non-negative integers. + if (LengthValue.isNegative()) { + Diag(Length->getExprLoc(), diag::err_omp_section_negative) + << 1 << LengthValue.toString(/*Radix=*/10, /*Signed=*/true) + << Length->getSourceRange(); + return ExprError(); + } + } + } else if (ColonLoc.isValid() && + (OriginalTy.isNull() || (!OriginalTy->isConstantArrayType() && + !OriginalTy->isVariableArrayType()))) { + // OpenMP 4.0, [2.4 Array Sections] + // When the size of the array dimension is not known, the length must be + // specified explicitly. + Diag(ColonLoc, diag::err_omp_section_length_undefined) + << (!OriginalTy.isNull() && OriginalTy->isArrayType()); + return ExprError(); + } + + return new (Context) + OMPArraySectionExpr(Base, LowerBound, Length, Context.OMPArraySectionTy, + VK_LValue, OK_Ordinary, ColonLoc, RBLoc); +} + ExprResult Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, Expr *Idx, SourceLocation RLoc) { @@ -4275,29 +4401,27 @@ static TypoCorrection TryTypoCorrectionForCall(Sema &S, Expr *Fn, llvm::make_unique<FunctionCallCCC>(S, FuncName.getAsIdentifierInfo(), Args.size(), ME), Sema::CTK_ErrorRecovery)) { - if (NamedDecl *ND = Corrected.getCorrectionDecl()) { + if (NamedDecl *ND = Corrected.getFoundDecl()) { if (Corrected.isOverloaded()) { OverloadCandidateSet OCS(NameLoc, OverloadCandidateSet::CSK_Normal); OverloadCandidateSet::iterator Best; - for (TypoCorrection::decl_iterator CD = Corrected.begin(), - CDEnd = Corrected.end(); - CD != CDEnd; ++CD) { - if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*CD)) + for (NamedDecl *CD : Corrected) { + if (FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) S.AddOverloadCandidate(FD, DeclAccessPair::make(FD, AS_none), Args, OCS); } switch (OCS.BestViableFunction(S, NameLoc, Best)) { case OR_Success: - ND = Best->Function; + ND = Best->FoundDecl; Corrected.setCorrectionDecl(ND); break; default: break; } } - if (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)) { + ND = ND->getUnderlyingDecl(); + if (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)) return Corrected; - } } } return TypoCorrection(); @@ -4433,7 +4557,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl, bool IsListInitialization) { unsigned NumParams = Proto->getNumParams(); bool Invalid = false; - unsigned ArgIx = 0; + size_t ArgIx = 0; // Continue to check argument types (even if we have too few/many args). for (unsigned i = FirstParam; i < NumParams; i++) { QualType ProtoArgType = Proto->getParamType(i); @@ -4503,26 +4627,25 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl, // return __unknown_anytype aren't *really* variadic. if (Proto->getReturnType() == Context.UnknownAnyTy && FDecl && FDecl->isExternC()) { - for (unsigned i = ArgIx, e = Args.size(); i != e; ++i) { + for (Expr *A : Args.slice(ArgIx)) { QualType paramType; // ignored - ExprResult arg = checkUnknownAnyArg(CallLoc, Args[i], paramType); + ExprResult arg = checkUnknownAnyArg(CallLoc, A, paramType); Invalid |= arg.isInvalid(); AllArgs.push_back(arg.get()); } // Otherwise do argument promotion, (C99 6.5.2.2p7). } else { - for (unsigned i = ArgIx, e = Args.size(); i != e; ++i) { - ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], CallType, - FDecl); + for (Expr *A : Args.slice(ArgIx)) { + ExprResult Arg = DefaultVariadicArgumentPromotion(A, CallType, FDecl); Invalid |= Arg.isInvalid(); AllArgs.push_back(Arg.get()); } } // Check for array bounds violations. - for (unsigned i = ArgIx, e = Args.size(); i != e; ++i) - CheckArrayAccess(Args[i]); + for (Expr *A : Args.slice(ArgIx)) + CheckArrayAccess(A); } return Invalid; } @@ -4623,7 +4746,9 @@ static bool isPlaceholderToRemoveAsArg(QualType type) { // These are always invalid as call arguments and should be reported. case BuiltinType::BoundMember: case BuiltinType::BuiltinFn: + case BuiltinType::OMPArraySection: return true; + } llvm_unreachable("bad builtin type kind"); } @@ -4647,7 +4772,7 @@ static bool checkArgsForPlaceholders(Sema &S, MultiExprArg args) { } /// If a builtin function has a pointer argument with no explicit address -/// space, than it should be able to accept a pointer to any address +/// space, then it should be able to accept a pointer to any address /// space as input. In order to do this, we need to replace the /// standard builtin declaration with one that uses the same address space /// as the call. @@ -4745,7 +4870,7 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, // Pseudo-destructor calls should not have any arguments. Diag(Fn->getLocStart(), diag::err_pseudo_dtor_call_with_args) << FixItHint::CreateRemoval( - SourceRange(ArgExprs[0]->getLocStart(), + SourceRange(ArgExprs.front()->getLocStart(), ArgExprs.back()->getLocEnd())); } @@ -4802,14 +4927,10 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, // We aren't supposed to apply this logic for if there's an '&' involved. if (!find.HasFormOfMemberPointer) { OverloadExpr *ovl = find.Expression; - if (isa<UnresolvedLookupExpr>(ovl)) { - UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(ovl); + if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(ovl)) return BuildOverloadedCallExpr(S, Fn, ULE, LParenLoc, ArgExprs, RParenLoc, ExecConfig); - } else { - return BuildCallToMemberFunction(S, Fn, LParenLoc, ArgExprs, - RParenLoc); - } + return BuildCallToMemberFunction(S, Fn, LParenLoc, ArgExprs, RParenLoc); } } @@ -4832,7 +4953,7 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, FunctionDecl *FDecl = dyn_cast<FunctionDecl>(NDecl); if (FDecl && FDecl->getBuiltinID()) { - // Rewrite the function decl for this builtin by replacing paramaters + // Rewrite the function decl for this builtin by replacing parameters // with no explicit address space with the address space of the arguments // in ArgExprs. if ((FDecl = rewriteBuiltinFunctionDecl(this, Context, FDecl, ArgExprs))) { @@ -4949,7 +5070,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, if (!Result.isUsable()) return ExprError(); TheCall = dyn_cast<CallExpr>(Result.get()); if (!TheCall) return Result; - Args = ArrayRef<Expr *>(TheCall->getArgs(), TheCall->getNumArgs()); + Args = llvm::makeArrayRef(TheCall->getArgs(), TheCall->getNumArgs()); } // Bail out early if calling a builtin with custom typechecking. @@ -5098,8 +5219,7 @@ ExprResult Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty, SourceLocation RParenLoc, Expr *InitExpr) { assert(Ty && "ActOnCompoundLiteral(): missing type"); - // FIXME: put back this assert when initializers are worked out. - //assert((InitExpr != 0) && "ActOnCompoundLiteral(): missing expression"); + assert(InitExpr && "ActOnCompoundLiteral(): missing expression"); TypeSourceInfo *TInfo; QualType literalType = GetTypeFromParser(Ty, &TInfo); @@ -5280,13 +5400,13 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { return CK_IntegralToFloating; case Type::STK_IntegralComplex: Src = ImpCastExprToType(Src.get(), - DestTy->castAs<ComplexType>()->getElementType(), - CK_IntegralCast); + DestTy->castAs<ComplexType>()->getElementType(), + CK_IntegralCast); return CK_IntegralRealToComplex; case Type::STK_FloatingComplex: Src = ImpCastExprToType(Src.get(), - DestTy->castAs<ComplexType>()->getElementType(), - CK_IntegralToFloating); + DestTy->castAs<ComplexType>()->getElementType(), + CK_IntegralToFloating); return CK_FloatingRealToComplex; case Type::STK_MemberPointer: llvm_unreachable("member pointer type in C"); @@ -5401,36 +5521,54 @@ static bool breakDownVectorType(QualType type, uint64_t &len, return true; } -static bool VectorTypesMatch(Sema &S, QualType srcTy, QualType destTy) { +/// Are the two types lax-compatible vector types? That is, given +/// that one of them is a vector, do they have equal storage sizes, +/// where the storage size is the number of elements times the element +/// size? +/// +/// This will also return false if either of the types is neither a +/// vector nor a real type. +bool Sema::areLaxCompatibleVectorTypes(QualType srcTy, QualType destTy) { + assert(destTy->isVectorType() || srcTy->isVectorType()); + + // Disallow lax conversions between scalars and ExtVectors (these + // conversions are allowed for other vector types because common headers + // depend on them). Most scalar OP ExtVector cases are handled by the + // splat path anyway, which does what we want (convert, not bitcast). + // What this rules out for ExtVectors is crazy things like char4*float. + if (srcTy->isScalarType() && destTy->isExtVectorType()) return false; + if (destTy->isScalarType() && srcTy->isExtVectorType()) return false; + uint64_t srcLen, destLen; - QualType srcElt, destElt; - if (!breakDownVectorType(srcTy, srcLen, srcElt)) return false; - if (!breakDownVectorType(destTy, destLen, destElt)) return false; + QualType srcEltTy, destEltTy; + if (!breakDownVectorType(srcTy, srcLen, srcEltTy)) return false; + if (!breakDownVectorType(destTy, destLen, destEltTy)) return false; // ASTContext::getTypeSize will return the size rounded up to a // power of 2, so instead of using that, we need to use the raw // element size multiplied by the element count. - uint64_t srcEltSize = S.Context.getTypeSize(srcElt); - uint64_t destEltSize = S.Context.getTypeSize(destElt); + uint64_t srcEltSize = Context.getTypeSize(srcEltTy); + uint64_t destEltSize = Context.getTypeSize(destEltTy); return (srcLen * srcEltSize == destLen * destEltSize); } -/// Is this a legal conversion between two known vector types? +/// Is this a legal conversion between two types, one of which is +/// known to be a vector type? bool Sema::isLaxVectorConversion(QualType srcTy, QualType destTy) { assert(destTy->isVectorType() || srcTy->isVectorType()); if (!Context.getLangOpts().LaxVectorConversions) return false; - return VectorTypesMatch(*this, srcTy, destTy); + return areLaxCompatibleVectorTypes(srcTy, destTy); } bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty, CastKind &Kind) { assert(VectorTy->isVectorType() && "Not a vector type!"); - if (Ty->isVectorType() || Ty->isIntegerType()) { - if (!VectorTypesMatch(*this, Ty, VectorTy)) + if (Ty->isVectorType() || Ty->isIntegralType(Context)) { + if (!areLaxCompatibleVectorTypes(Ty, VectorTy)) return Diag(R.getBegin(), Ty->isVectorType() ? diag::err_invalid_conversion_between_vectors : @@ -5456,7 +5594,7 @@ ExprResult Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, // In OpenCL, casts between vectors of different types are not allowed. // (See OpenCL 6.2). if (SrcTy->isVectorType()) { - if (!VectorTypesMatch(*this, SrcTy, DestTy) + if (!areLaxCompatibleVectorTypes(SrcTy, DestTy) || (getLangOpts().OpenCL && (DestTy.getCanonicalType() != SrcTy.getCanonicalType()))) { Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors) @@ -6358,7 +6496,7 @@ QualType Sema::FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS, static void SuggestParentheses(Sema &Self, SourceLocation Loc, const PartialDiagnostic &Note, SourceRange ParenRange) { - SourceLocation EndLoc = Self.PP.getLocForEndOfToken(ParenRange.getEnd()); + SourceLocation EndLoc = Self.getLocForEndOfToken(ParenRange.getEnd()); if (ParenRange.getBegin().isFileID() && ParenRange.getEnd().isFileID() && EndLoc.isValid()) { Self.Diag(Loc, Note) @@ -6371,7 +6509,9 @@ static void SuggestParentheses(Sema &Self, SourceLocation Loc, } static bool IsArithmeticOp(BinaryOperatorKind Opc) { - return Opc >= BO_Mul && Opc <= BO_Shr; + return BinaryOperator::isAdditiveOp(Opc) || + BinaryOperator::isMultiplicativeOp(Opc) || + BinaryOperator::isShiftOp(Opc); } /// IsArithmeticBinaryExpr - Returns true if E is an arithmetic binary @@ -6417,10 +6557,6 @@ static bool IsArithmeticBinaryExpr(Expr *E, BinaryOperatorKind *Opcode, return false; } -static bool IsLogicOp(BinaryOperatorKind Opc) { - return (Opc >= BO_LT && Opc <= BO_NE) || (Opc >= BO_LAnd && Opc <= BO_LOr); -} - /// ExprLooksBoolean - Returns true if E looks boolean, i.e. it has boolean type /// or is a logical expression such as (x==y) which has int type, but is /// commonly interpreted as boolean. @@ -6430,7 +6566,7 @@ static bool ExprLooksBoolean(Expr *E) { if (E->getType()->isBooleanType()) return true; if (BinaryOperator *OP = dyn_cast<BinaryOperator>(E)) - return IsLogicOp(OP->getOpcode()); + return OP->isComparisonOp() || OP->isLogicalOp(); if (UnaryOperator *OP = dyn_cast<UnaryOperator>(E)) return OP->getOpcode() == UO_LNot; if (E->getType()->isPointerType()) @@ -6753,7 +6889,7 @@ Sema::CheckAssignmentConstraints(SourceLocation Loc, ExprResult RHSPtr = &RHSExpr; CastKind K = CK_Invalid; - return CheckAssignmentConstraints(LHSType, RHSPtr, K); + return CheckAssignmentConstraints(LHSType, RHSPtr, K, /*ConvertRHS=*/false); } /// CheckAssignmentConstraints (C99 6.5.16) - This routine currently @@ -6775,7 +6911,7 @@ Sema::CheckAssignmentConstraints(SourceLocation Loc, /// Sets 'Kind' for any result kind except Incompatible. Sema::AssignConvertType Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, - CastKind &Kind) { + CastKind &Kind, bool ConvertRHS) { QualType RHSType = RHS.get()->getType(); QualType OrigLHSType = LHSType; @@ -6797,7 +6933,7 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, CheckAssignmentConstraints(AtomicTy->getValueType(), RHS, Kind); if (result != Compatible) return result; - if (Kind != CK_NoOp) + if (Kind != CK_NoOp && ConvertRHS) RHS = ImpCastExprToType(RHS.get(), AtomicTy->getValueType(), Kind); Kind = CK_NonAtomicToAtomic; return Compatible; @@ -6827,7 +6963,7 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, // CK_VectorSplat does T -> vector T, so first cast to the // element type. QualType elType = cast<ExtVectorType>(LHSType)->getElementType(); - if (elType != RHSType) { + if (elType != RHSType && ConvertRHS) { Kind = PrepareScalarCast(RHS, elType); RHS = ImpCastExprToType(RHS.get(), elType, Kind); } @@ -6860,7 +6996,8 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, // Arithmetic conversions. if (LHSType->isArithmeticType() && RHSType->isArithmeticType() && !(getLangOpts().CPlusPlus && LHSType->isEnumeralType())) { - Kind = PrepareScalarCast(RHS, LHSType); + if (ConvertRHS) + Kind = PrepareScalarCast(RHS, LHSType); return Compatible; } @@ -6985,7 +7122,8 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, // Only under strict condition T^ is compatible with an Objective-C pointer. if (RHSType->isBlockPointerType() && LHSType->isBlockCompatibleObjCPointerType(Context)) { - maybeExtendBlockObject(RHS); + if (ConvertRHS) + maybeExtendBlockObject(RHS); Kind = CK_BlockPointerToObjCPointerCast; return Compatible; } @@ -7111,9 +7249,16 @@ Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType, } Sema::AssignConvertType -Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, +Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS, bool Diagnose, - bool DiagnoseCFAudited) { + bool DiagnoseCFAudited, + bool ConvertRHS) { + // If ConvertRHS is false, we want to leave the caller's RHS untouched. Sadly, + // we can't avoid *all* modifications at the moment, so we need some somewhere + // to put the updated value. + ExprResult LocalRHS = CallerRHS; + ExprResult &RHS = ConvertRHS ? CallerRHS : LocalRHS; + if (getLangOpts().CPlusPlus) { if (!LHSType->isRecordType() && !LHSType->isAtomicType()) { // C++ 5.17p3: If the left operand is not of class type, the @@ -7151,6 +7296,15 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, // structures. // FIXME: We also fall through for atomics; not sure what should // happen there, though. + } else if (RHS.get()->getType() == Context.OverloadTy) { + // As a set of extensions to C, we support overloading on functions. These + // functions need to be resolved here. + DeclAccessPair DAP; + if (FunctionDecl *FD = ResolveAddressOfOverloadedFunction( + RHS.get(), LHSType, /*Complain=*/false, DAP)) + RHS = FixOverloadedFunctionReference(RHS.get(), DAP, FD); + else + return Incompatible; } // C99 6.5.16.1p1: the left operand is a pointer and the right is @@ -7162,7 +7316,8 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, CastKind Kind; CXXCastPath Path; CheckPointerConversion(RHS.get(), LHSType, Kind, Path, false); - RHS = ImpCastExprToType(RHS.get(), LHSType, Kind, VK_RValue, &Path); + if (ConvertRHS) + RHS = ImpCastExprToType(RHS.get(), LHSType, Kind, VK_RValue, &Path); return Compatible; } @@ -7173,7 +7328,8 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, // // Suppress this for references: C++ 8.5.3p5. if (!LHSType->isReferenceType()) { - RHS = DefaultFunctionArrayLvalueConversion(RHS.get()); + // FIXME: We potentially allocate here even if ConvertRHS is false. + RHS = DefaultFunctionArrayLvalueConversion(RHS.get(), Diagnose); if (RHS.isInvalid()) return Incompatible; } @@ -7189,7 +7345,7 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, CastKind Kind = CK_Invalid; Sema::AssignConvertType result = - CheckAssignmentConstraints(LHSType, RHS, Kind); + CheckAssignmentConstraints(LHSType, RHS, Kind, ConvertRHS); // C99 6.5.16.1p2: The value of the right operand is converted to the // type of the assignment expression. @@ -7211,7 +7367,8 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, return Compatible; } - RHS = ImpCastExprToType(E, Ty, Kind); + if (ConvertRHS) + RHS = ImpCastExprToType(E, Ty, Kind); } return result; } @@ -7374,6 +7531,18 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, return QualType(); } + // OpenCL V1.1 6.2.6.p1: + // If the operands are of more than one vector type, then an error shall + // occur. Implicit conversions between vector types are not permitted, per + // section 6.2.1. + if (getLangOpts().OpenCL && + RHSVecType && isa<ExtVectorType>(RHSVecType) && + LHSVecType && isa<ExtVectorType>(LHSVecType)) { + Diag(Loc, diag::err_opencl_implicit_vector_conversion) << LHSType + << RHSType; + return QualType(); + } + // Otherwise, use the generic diagnostic. Diag(Loc, diag::err_typecheck_vector_not_convertable) << LHSType << RHSType @@ -7420,6 +7589,18 @@ static void checkArithmeticNull(Sema &S, ExprResult &LHS, ExprResult &RHS, << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); } +static void DiagnoseBadDivideOrRemainderValues(Sema& S, ExprResult &LHS, + ExprResult &RHS, + SourceLocation Loc, bool IsDiv) { + // Check for division/remainder by zero. + llvm::APSInt RHSValue; + if (!RHS.get()->isValueDependent() && + RHS.get()->EvaluateAsInt(RHSValue, S.Context) && RHSValue == 0) + S.DiagRuntimeBehavior(Loc, RHS.get(), + S.PDiag(diag::warn_remainder_division_by_zero) + << IsDiv << RHS.get()->getSourceRange()); +} + QualType Sema::CheckMultiplyDivideOperands(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsCompAssign, bool IsDiv) { @@ -7438,15 +7619,8 @@ QualType Sema::CheckMultiplyDivideOperands(ExprResult &LHS, ExprResult &RHS, if (compType.isNull() || !compType->isArithmeticType()) return InvalidOperands(Loc, LHS, RHS); - - // Check for division by zero. - llvm::APSInt RHSValue; - if (IsDiv && !RHS.get()->isValueDependent() && - RHS.get()->EvaluateAsInt(RHSValue, Context) && RHSValue == 0) - DiagRuntimeBehavior(Loc, RHS.get(), - PDiag(diag::warn_division_by_zero) - << RHS.get()->getSourceRange()); - + if (IsDiv) + DiagnoseBadDivideOrRemainderValues(*this, LHS, RHS, Loc, IsDiv); return compType; } @@ -7470,15 +7644,7 @@ QualType Sema::CheckRemainderOperands( if (compType.isNull() || !compType->isIntegerType()) return InvalidOperands(Loc, LHS, RHS); - - // Check for remainder by zero. - llvm::APSInt RHSValue; - if (!RHS.get()->isValueDependent() && - RHS.get()->EvaluateAsInt(RHSValue, Context) && RHSValue == 0) - DiagRuntimeBehavior(Loc, RHS.get(), - PDiag(diag::warn_remainder_by_zero) - << RHS.get()->getSourceRange()); - + DiagnoseBadDivideOrRemainderValues(*this, LHS, RHS, Loc, false /* IsDiv */); return compType; } @@ -7596,7 +7762,7 @@ static bool checkArithmeticBinOpPointerOperands(Sema &S, SourceLocation Loc, if (isRHSPointer) RHSPointeeTy = RHSExpr->getType()->getPointeeType(); // if both are pointers check if operation is valid wrt address spaces - if (isLHSPointer && isRHSPointer) { + if (S.getLangOpts().OpenCL && isLHSPointer && isRHSPointer) { const PointerType *lhsPtr = LHSExpr->getType()->getAs<PointerType>(); const PointerType *rhsPtr = RHSExpr->getType()->getAs<PointerType>(); if (!lhsPtr->isAddressSpaceOverlapping(*rhsPtr)) { @@ -7669,7 +7835,7 @@ static void diagnoseStringPlusInt(Sema &Self, SourceLocation OpLoc, // Only print a fixit for "str" + int, not for int + "str". if (IndexExpr == RHSExpr) { - SourceLocation EndLoc = Self.PP.getLocForEndOfToken(RHSExpr->getLocEnd()); + SourceLocation EndLoc = Self.getLocForEndOfToken(RHSExpr->getLocEnd()); Self.Diag(OpLoc, diag::note_string_plus_scalar_silence) << FixItHint::CreateInsertion(LHSExpr->getLocStart(), "&") << FixItHint::CreateReplacement(SourceRange(OpLoc), "[") @@ -7719,7 +7885,7 @@ 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.PP.getLocForEndOfToken(RHSExpr->getLocEnd()); + SourceLocation EndLoc = Self.getLocForEndOfToken(RHSExpr->getLocEnd()); Self.Diag(OpLoc, diag::note_string_plus_scalar_silence) << FixItHint::CreateInsertion(LHSExpr->getLocStart(), "&") << FixItHint::CreateReplacement(SourceRange(OpLoc), "[") @@ -7739,9 +7905,10 @@ static void diagnosePointerIncompatibility(Sema &S, SourceLocation Loc, << RHSExpr->getSourceRange(); } -QualType Sema::CheckAdditionOperands( // C99 6.5.6 - ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned Opc, - QualType* CompLHSTy) { +// C99 6.5.6 +QualType Sema::CheckAdditionOperands(ExprResult &LHS, ExprResult &RHS, + SourceLocation Loc, BinaryOperatorKind Opc, + QualType* CompLHSTy) { checkArithmeticNull(*this, LHS, RHS, Loc, /*isCompare=*/false); if (LHS.get()->getType()->isVectorType() || @@ -7917,7 +8084,7 @@ static bool isScopedEnumerationType(QualType T) { } static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS, - SourceLocation Loc, unsigned Opc, + SourceLocation Loc, BinaryOperatorKind Opc, QualType LHSType) { // OpenCL 6.3j: shift values are effectively % word size of LHS (more defined), // so skip remaining warnings as we don't want to modify values within Sema. @@ -8060,7 +8227,7 @@ static QualType checkOpenCLVectorShift(Sema &S, // C99 6.5.7 QualType Sema::CheckShiftOperands(ExprResult &LHS, ExprResult &RHS, - SourceLocation Loc, unsigned Opc, + SourceLocation Loc, BinaryOperatorKind Opc, bool IsCompAssign) { checkArithmeticNull(*this, LHS, RHS, Loc, /*isCompare=*/false); @@ -8365,9 +8532,9 @@ 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.PP.getLocForEndOfToken(RHS.get()->getLocEnd()); + SourceLocation End = S.getLocForEndOfToken(RHS.get()->getLocEnd()); CharSourceRange OpRange = - CharSourceRange::getCharRange(Loc, S.PP.getLocForEndOfToken(Loc)); + CharSourceRange::getCharRange(Loc, S.getLocForEndOfToken(Loc)); S.Diag(Loc, diag::note_objc_literal_comparison_isequal) << FixItHint::CreateInsertion(Start, Opc == BO_EQ ? "[" : "![") @@ -8379,20 +8546,17 @@ static void diagnoseObjCLiteralComparison(Sema &S, SourceLocation Loc, static void diagnoseLogicalNotOnLHSofComparison(Sema &S, ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, - unsigned OpaqueOpc) { - // This checking requires bools. - if (!S.getLangOpts().Bool) return; - + BinaryOperatorKind Opc) { // Check that left hand side is !something. UnaryOperator *UO = dyn_cast<UnaryOperator>(LHS.get()->IgnoreImpCasts()); if (!UO || UO->getOpcode() != UO_LNot) return; // Only check if the right hand side is non-bool arithmetic type. - if (RHS.get()->getType()->isBooleanType()) return; + if (RHS.get()->isKnownToHaveBooleanValue()) return; // Make sure that the something in !something is not bool. Expr *SubExpr = UO->getSubExpr()->IgnoreImpCasts(); - if (SubExpr->getType()->isBooleanType()) return; + if (SubExpr->isKnownToHaveBooleanValue()) return; // Emit warning. S.Diag(UO->getOperatorLoc(), diag::warn_logical_not_on_lhs_of_comparison) @@ -8401,7 +8565,7 @@ static void diagnoseLogicalNotOnLHSofComparison(Sema &S, ExprResult &LHS, // First note suggest !(x < y) SourceLocation FirstOpen = SubExpr->getLocStart(); SourceLocation FirstClose = RHS.get()->getLocEnd(); - FirstClose = S.getPreprocessor().getLocForEndOfToken(FirstClose); + FirstClose = S.getLocForEndOfToken(FirstClose); if (FirstClose.isInvalid()) FirstOpen = SourceLocation(); S.Diag(UO->getOperatorLoc(), diag::note_logical_not_fix) @@ -8411,7 +8575,7 @@ static void diagnoseLogicalNotOnLHSofComparison(Sema &S, ExprResult &LHS, // Second note suggests (!x) < y SourceLocation SecondOpen = LHS.get()->getLocStart(); SourceLocation SecondClose = LHS.get()->getLocEnd(); - SecondClose = S.getPreprocessor().getLocForEndOfToken(SecondClose); + SecondClose = S.getLocForEndOfToken(SecondClose); if (SecondClose.isInvalid()) SecondOpen = SourceLocation(); S.Diag(UO->getOperatorLoc(), diag::note_logical_not_silence_with_parens) @@ -8437,12 +8601,10 @@ static ValueDecl *getCompareDecl(Expr *E) { // C99 6.5.8, C++ [expr.rel] QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, - SourceLocation Loc, unsigned OpaqueOpc, + SourceLocation Loc, BinaryOperatorKind Opc, bool IsRelational) { checkArithmeticNull(*this, LHS, RHS, Loc, /*isCompare=*/true); - BinaryOperatorKind Opc = (BinaryOperatorKind) OpaqueOpc; - // Handle vector comparisons separately. if (LHS.get()->getType()->isVectorType() || RHS.get()->getType()->isVectorType()) @@ -8455,7 +8617,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, Expr *RHSStripped = RHS.get()->IgnoreParenImpCasts(); checkEnumComparison(*this, Loc, LHS.get(), RHS.get()); - diagnoseLogicalNotOnLHSofComparison(*this, LHS, RHS, Loc, OpaqueOpc); + diagnoseLogicalNotOnLHSofComparison(*this, LHS, RHS, Loc, Opc); if (!LHSType->hasFloatingRepresentation() && !(LHSType->isBlockPointerType() && IsRelational) && @@ -8628,12 +8790,15 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, diagnoseDistinctPointerComparison(*this, Loc, LHS, RHS, /*isError*/false); } if (LCanPointeeTy != RCanPointeeTy) { - const PointerType *lhsPtr = LHSType->getAs<PointerType>(); - if (!lhsPtr->isAddressSpaceOverlapping(*RHSType->getAs<PointerType>())) { - Diag(Loc, - diag::err_typecheck_op_on_nonoverlapping_address_space_pointers) - << LHSType << RHSType << 0 /* comparison */ - << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); + // Treat NULL constant as a special case in OpenCL. + if (getLangOpts().OpenCL && !LHSIsNull && !RHSIsNull) { + const PointerType *LHSPtr = LHSType->getAs<PointerType>(); + if (!LHSPtr->isAddressSpaceOverlapping(*RHSType->getAs<PointerType>())) { + Diag(Loc, + diag::err_typecheck_op_on_nonoverlapping_address_space_pointers) + << LHSType << RHSType << 0 /* comparison */ + << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); + } } unsigned AddrSpaceL = LCanPointeeTy.getAddressSpace(); unsigned AddrSpaceR = RCanPointeeTy.getAddressSpace(); @@ -8941,9 +9106,10 @@ inline QualType Sema::CheckBitwiseOperands( return InvalidOperands(Loc, LHS, RHS); } -inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14] - ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned Opc) { - +// C99 6.5.[13,14] +inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS, + SourceLocation Loc, + BinaryOperatorKind Opc) { // Check vector operands differently. if (LHS.get()->getType()->isVectorType() || RHS.get()->getType()->isVectorType()) return CheckVectorLogicalOperands(LHS, RHS, Loc); @@ -8972,18 +9138,14 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14] Diag(Loc, diag::note_logical_instead_of_bitwise_change_operator) << (Opc == BO_LAnd ? "&" : "|") << FixItHint::CreateReplacement(SourceRange( - Loc, Lexer::getLocForEndOfToken(Loc, 0, getSourceManager(), - getLangOpts())), + Loc, getLocForEndOfToken(Loc)), Opc == BO_LAnd ? "&" : "|"); if (Opc == BO_LAnd) // Suggest replacing "Foo() && kNonZero" with "Foo()" Diag(Loc, diag::note_logical_instead_of_bitwise_remove_constant) << FixItHint::CreateRemoval( - SourceRange( - Lexer::getLocForEndOfToken(LHS.get()->getLocEnd(), - 0, getSourceManager(), - getLangOpts()), - RHS.get()->getLocEnd())); + SourceRange(getLocForEndOfToken(LHS.get()->getLocEnd()), + RHS.get()->getLocEnd())); } } @@ -9161,7 +9323,7 @@ static void DiagnoseConstAssignment(Sema &S, const Expr *E, if (const CallExpr *CE = dyn_cast<CallExpr>(E)) { // Function calls const FunctionDecl *FD = CE->getDirectCallee(); - if (!IsTypeModifiable(FD->getReturnType(), IsDereference)) { + if (FD && !IsTypeModifiable(FD->getReturnType(), IsDereference)) { if (!DiagnosticEmitted) { S.Diag(Loc, diag::err_typecheck_assign_const) << ExprRange << ConstFunction << FD; @@ -9510,7 +9672,9 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op, return QualType(); } // Increment of bool sets it to true, but is deprecated. - S.Diag(OpLoc, diag::warn_increment_bool) << Op->getSourceRange(); + S.Diag(OpLoc, S.getLangOpts().CPlusPlus1z ? diag::ext_increment_bool + : diag::warn_increment_bool) + << Op->getSourceRange(); } else if (S.getLangOpts().CPlusPlus && ResType->isEnumeralType()) { // Error on enum increments and decrements in C++ mode S.Diag(OpLoc, diag::err_increment_decrement_enum) << IsInc << ResType; @@ -9710,6 +9874,12 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) { // expressions here, but the result of one is always an lvalue anyway. } ValueDecl *dcl = getPrimaryDecl(op); + + if (auto *FD = dyn_cast_or_null<FunctionDecl>(dcl)) + if (!checkAddressOfFunctionIsAvailable(FD, /*Complain=*/true, + op->getLocStart())) + return QualType(); + Expr::LValueClassification lval = op->ClassifyLValue(Context); unsigned AddressOfError = AO_No_Error; @@ -9763,8 +9933,9 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) { QualType MPTy = Context.getMemberPointerType( op->getType(), Context.getTypeDeclType(MD->getParent()).getTypePtr()); + // Under the MS ABI, lock down the inheritance model now. if (Context.getTargetInfo().getCXXABI().isMicrosoft()) - RequireCompleteType(OpLoc, MPTy, 0); + (void)isCompleteType(OpLoc, MPTy); return MPTy; } else if (lval != Expr::LV_Valid && lval != Expr::LV_IncompleteVoidType) { // C99 6.5.3.2p1 @@ -9819,8 +9990,9 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) { QualType MPTy = Context.getMemberPointerType( op->getType(), Context.getTypeDeclType(cast<RecordDecl>(Ctx)).getTypePtr()); + // Under the MS ABI, lock down the inheritance model now. if (Context.getTargetInfo().getCXXABI().isMicrosoft()) - RequireCompleteType(OpLoc, MPTy, 0); + (void)isCompleteType(OpLoc, MPTy); return MPTy; } } @@ -10121,6 +10293,20 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, return ExprError(); } + if (getLangOpts().OpenCL) { + // OpenCLC v2.0 s6.13.11.1 allows atomic variables to be initialized by + // the ATOMIC_VAR_INIT macro. + if (LHSExpr->getType()->isAtomicType() || + RHSExpr->getType()->isAtomicType()) { + SourceRange SR(LHSExpr->getLocStart(), RHSExpr->getLocEnd()); + if (BO_Assign == Opc) + Diag(OpLoc, diag::err_atomic_init_constant) << SR; + else + ResultTy = InvalidOperands(OpLoc, LHS, RHS); + return ExprError(); + } + } + switch (Opc) { case BO_Assign: ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, QualType()); @@ -10211,7 +10397,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, break; case BO_AndAssign: case BO_OrAssign: // fallthrough - DiagnoseSelfAssignment(*this, LHS.get(), RHS.get(), OpLoc); + DiagnoseSelfAssignment(*this, LHS.get(), RHS.get(), OpLoc); case BO_XorAssign: CompResultTy = CheckBitwiseOperands(LHS, RHS, OpLoc, true); CompLHSTy = CompResultTy; @@ -10238,7 +10424,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, &Context.Idents.get("object_setClass"), SourceLocation(), LookupOrdinaryName); if (ObjectSetClass && isa<ObjCIsaExpr>(LHS.get())) { - SourceLocation RHSLocEnd = PP.getLocForEndOfToken(RHS.get()->getLocEnd()); + 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), ",") << @@ -10274,17 +10460,17 @@ static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperatorKind Opc, BinaryOperator *LHSBO = dyn_cast<BinaryOperator>(LHSExpr); BinaryOperator *RHSBO = dyn_cast<BinaryOperator>(RHSExpr); - // Check that one of the sides is a comparison operator. + // Check that one of the sides is a comparison operator and the other isn't. bool isLeftComp = LHSBO && LHSBO->isComparisonOp(); bool isRightComp = RHSBO && RHSBO->isComparisonOp(); - if (!isLeftComp && !isRightComp) + if (isLeftComp == isRightComp) return; // Bitwise operations are sometimes used as eager logical ops. // Don't diagnose this. bool isLeftBitwise = LHSBO && LHSBO->isBitwiseOp(); bool isRightBitwise = RHSBO && RHSBO->isBitwiseOp(); - if ((isLeftComp || isLeftBitwise) && (isRightComp || isRightBitwise)) + if (isLeftBitwise || isRightBitwise) return; SourceRange DiagRange = isLeftComp ? SourceRange(LHSExpr->getLocStart(), @@ -10306,21 +10492,6 @@ static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperatorKind Opc, ParensRange); } -/// \brief It accepts a '&' expr that is inside a '|' one. -/// Emit a diagnostic together with a fixit hint that wraps the '&' expression -/// in parentheses. -static void -EmitDiagnosticForBitwiseAndInBitwiseOr(Sema &Self, SourceLocation OpLoc, - BinaryOperator *Bop) { - assert(Bop->getOpcode() == BO_And); - Self.Diag(Bop->getOperatorLoc(), diag::warn_bitwise_and_in_bitwise_or) - << Bop->getSourceRange() << OpLoc; - SuggestParentheses(Self, Bop->getOperatorLoc(), - Self.PDiag(diag::note_precedence_silence) - << Bop->getOpcodeStr(), - Bop->getSourceRange()); -} - /// \brief It accepts a '&&' expr that is inside a '||' one. /// Emit a diagnostic together with a fixit hint that wraps the '&&' expression /// in parentheses. @@ -10389,12 +10560,21 @@ static void DiagnoseLogicalAndInLogicalOrRHS(Sema &S, SourceLocation OpLoc, } } -/// \brief Look for '&' in the left or right hand of a '|' expr. -static void DiagnoseBitwiseAndInBitwiseOr(Sema &S, SourceLocation OpLoc, - Expr *OrArg) { - if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(OrArg)) { - if (Bop->getOpcode() == BO_And) - return EmitDiagnosticForBitwiseAndInBitwiseOr(S, OpLoc, Bop); +/// \brief Look for bitwise op in the left or right hand of a bitwise op with +/// lower precedence and emit a diagnostic together with a fixit hint that wraps +/// the '&' expression in parentheses. +static void DiagnoseBitwiseOpInBitwiseOp(Sema &S, BinaryOperatorKind Opc, + SourceLocation OpLoc, Expr *SubExpr) { + if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(SubExpr)) { + if (Bop->isBitwiseOp() && Bop->getOpcode() < Opc) { + S.Diag(Bop->getOperatorLoc(), diag::warn_bitwise_op_in_bitwise_op) + << Bop->getOpcodeStr() << BinaryOperator::getOpcodeStr(Opc) + << Bop->getSourceRange() << OpLoc; + SuggestParentheses(S, Bop->getOperatorLoc(), + S.PDiag(diag::note_precedence_silence) + << Bop->getOpcodeStr(), + Bop->getSourceRange()); + } } } @@ -10449,9 +10629,10 @@ static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperatorKind Opc, DiagnoseBitwisePrecedence(Self, Opc, OpLoc, LHSExpr, RHSExpr); // Diagnose "arg1 & arg2 | arg3" - if (Opc == BO_Or && !OpLoc.isMacroID()/* Don't warn in macros. */) { - DiagnoseBitwiseAndInBitwiseOr(Self, OpLoc, LHSExpr); - DiagnoseBitwiseAndInBitwiseOr(Self, OpLoc, RHSExpr); + if ((Opc == BO_Or || Opc == BO_Xor) && + !OpLoc.isMacroID()/* Don't warn in macros. */) { + DiagnoseBitwiseOpInBitwiseOp(Self, Opc, OpLoc, LHSExpr); + DiagnoseBitwiseOpInBitwiseOp(Self, Opc, OpLoc, RHSExpr); } // Warn about arg1 || arg2 && arg3, as GCC 4.3+ does. @@ -10593,6 +10774,14 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, ExprValueKind VK = VK_RValue; ExprObjectKind OK = OK_Ordinary; QualType resultType; + if (getLangOpts().OpenCL) { + // The only legal unary operation for atomics is '&'. + if (Opc != UO_AddrOf && InputExpr->getType()->isAtomicType()) { + return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) + << InputExpr->getType() + << Input.get()->getSourceRange()); + } + } switch (Opc) { case UO_PreInc: case UO_PreDec: @@ -10735,6 +10924,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, } break; case UO_Extension: + case UO_Coawait: resultType = Input.get()->getType(); VK = Input.get()->getValueKind(); OK = Input.get()->getObjectKind(); @@ -10778,10 +10968,8 @@ static bool isQualifiedMemberAccess(Expr *E) { if (!ULE->getQualifier()) return false; - for (UnresolvedLookupExpr::decls_iterator D = ULE->decls_begin(), - DEnd = ULE->decls_end(); - D != DEnd; ++D) { - if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*D)) { + for (NamedDecl *D : ULE->decls()) { + if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) { if (Method->isInstance()) return true; } else { @@ -10971,8 +11159,7 @@ Sema::ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, TypeSourceInfo *TInfo, - OffsetOfComponent *CompPtr, - unsigned NumComponents, + ArrayRef<OffsetOfComponent> Components, SourceLocation RParenLoc) { QualType ArgTy = TInfo->getType(); bool Dependent = ArgTy->isDependentType(); @@ -10996,17 +11183,15 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, // GCC extension, diagnose them. // FIXME: This diagnostic isn't actually visible because the location is in // a system header! - if (NumComponents != 1) + if (Components.size() != 1) Diag(BuiltinLoc, diag::ext_offsetof_extended_field_designator) - << SourceRange(CompPtr[1].LocStart, CompPtr[NumComponents-1].LocEnd); + << SourceRange(Components[1].LocStart, Components.back().LocEnd); bool DidWarnAboutNonPOD = false; QualType CurrentType = ArgTy; - typedef OffsetOfExpr::OffsetOfNode OffsetOfNode; SmallVector<OffsetOfNode, 4> Comps; SmallVector<Expr*, 4> Exprs; - for (unsigned i = 0; i != NumComponents; ++i) { - const OffsetOfComponent &OC = CompPtr[i]; + for (const OffsetOfComponent &OC : Components) { if (OC.isBrackets) { // Offset of an array sub-field. TODO: Should we allow vector elements? if (!CurrentType->isDependentType()) { @@ -11074,7 +11259,7 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, if (!IsSafe && !DidWarnAboutNonPOD && DiagRuntimeBehavior(BuiltinLoc, nullptr, PDiag(DiagID) - << SourceRange(CompPtr[0].LocStart, OC.LocEnd) + << SourceRange(Components[0].LocStart, OC.LocEnd) << CurrentType)) DidWarnAboutNonPOD = true; } @@ -11113,7 +11298,8 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, // If the member was found in a base class, introduce OffsetOfNodes for // the base class indirections. CXXBasePaths Paths; - if (IsDerivedFrom(CurrentType, Context.getTypeDeclType(Parent), Paths)) { + if (IsDerivedFrom(OC.LocStart, CurrentType, Context.getTypeDeclType(Parent), + Paths)) { if (Paths.getDetectedVirtual()) { Diag(OC.LocEnd, diag::err_offsetof_field_of_virtual_base) << MemberDecl->getDeclName() @@ -11122,9 +11308,8 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, } CXXBasePath &Path = Paths.front(); - for (CXXBasePath::iterator B = Path.begin(), BEnd = Path.end(); - B != BEnd; ++B) - Comps.push_back(OffsetOfNode(B->Base)); + for (const CXXBasePathElement &B : Path) + Comps.push_back(OffsetOfNode(B.Base)); } if (IndirectMemberDecl) { @@ -11147,8 +11332,7 @@ ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S, SourceLocation BuiltinLoc, SourceLocation TypeLoc, ParsedType ParsedArgTy, - OffsetOfComponent *CompPtr, - unsigned NumComponents, + ArrayRef<OffsetOfComponent> Components, SourceLocation RParenLoc) { TypeSourceInfo *ArgTInfo; @@ -11159,8 +11343,7 @@ ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S, if (!ArgTInfo) ArgTInfo = Context.getTrivialTypeSourceInfo(ArgTy, TypeLoc); - return BuildBuiltinOffsetOf(BuiltinLoc, ArgTInfo, CompPtr, NumComponents, - RParenLoc); + return BuildBuiltinOffsetOf(BuiltinLoc, ArgTInfo, Components, RParenLoc); } @@ -11394,16 +11577,14 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, // Set the captured variables on the block. // FIXME: Share capture structure between BlockDecl and CapturingScopeInfo! SmallVector<BlockDecl::Capture, 4> Captures; - for (unsigned i = 0, e = BSI->Captures.size(); i != e; i++) { - CapturingScopeInfo::Capture &Cap = BSI->Captures[i]; + for (CapturingScopeInfo::Capture &Cap : BSI->Captures) { if (Cap.isThisCapture()) continue; BlockDecl::Capture NewCap(Cap.getVariable(), Cap.isBlockCapture(), Cap.isNested(), Cap.getInitExpr()); Captures.push_back(NewCap); } - BSI->TheDecl->setCaptures(Context, Captures.begin(), Captures.end(), - BSI->CXXThisCaptureIndex != 0); + BSI->TheDecl->setCaptures(Context, Captures, BSI->CXXThisCaptureIndex != 0); // If the user wrote a function type in some form, try to use that. if (!BSI->FunctionType.isNull()) { @@ -11495,43 +11676,57 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc, Expr *E, TypeSourceInfo *TInfo, SourceLocation RPLoc) { Expr *OrigExpr = E; + bool IsMS = false; + + // It might be a __builtin_ms_va_list. (But don't ever mark a va_arg() + // as Microsoft ABI on an actual Microsoft platform, where + // __builtin_ms_va_list and __builtin_va_list are the same.) + if (!E->isTypeDependent() && Context.getTargetInfo().hasBuiltinMSVaList() && + Context.getTargetInfo().getBuiltinVaListKind() != TargetInfo::CharPtrBuiltinVaList) { + QualType MSVaListType = Context.getBuiltinMSVaListType(); + if (Context.hasSameType(MSVaListType, E->getType())) { + if (CheckForModifiableLvalue(E, BuiltinLoc, *this)) + return ExprError(); + IsMS = true; + } + } // Get the va_list type QualType VaListType = Context.getBuiltinVaListType(); - if (VaListType->isArrayType()) { - // Deal with implicit array decay; for example, on x86-64, - // va_list is an array, but it's supposed to decay to - // a pointer for va_arg. - VaListType = Context.getArrayDecayedType(VaListType); - // Make sure the input expression also decays appropriately. - ExprResult Result = UsualUnaryConversions(E); - if (Result.isInvalid()) - return ExprError(); - E = Result.get(); - } else if (VaListType->isRecordType() && getLangOpts().CPlusPlus) { - // If va_list is a record type and we are compiling in C++ mode, - // check the argument using reference binding. - InitializedEntity Entity - = InitializedEntity::InitializeParameter(Context, - Context.getLValueReferenceType(VaListType), false); - ExprResult Init = PerformCopyInitialization(Entity, SourceLocation(), E); - if (Init.isInvalid()) - return ExprError(); - E = Init.getAs<Expr>(); - } else { - // Otherwise, the va_list argument must be an l-value because - // it is modified by va_arg. - if (!E->isTypeDependent() && - CheckForModifiableLvalue(E, BuiltinLoc, *this)) - return ExprError(); + if (!IsMS) { + if (VaListType->isArrayType()) { + // Deal with implicit array decay; for example, on x86-64, + // va_list is an array, but it's supposed to decay to + // a pointer for va_arg. + VaListType = Context.getArrayDecayedType(VaListType); + // Make sure the input expression also decays appropriately. + ExprResult Result = UsualUnaryConversions(E); + if (Result.isInvalid()) + return ExprError(); + E = Result.get(); + } else if (VaListType->isRecordType() && getLangOpts().CPlusPlus) { + // If va_list is a record type and we are compiling in C++ mode, + // check the argument using reference binding. + InitializedEntity Entity = InitializedEntity::InitializeParameter( + Context, Context.getLValueReferenceType(VaListType), false); + ExprResult Init = PerformCopyInitialization(Entity, SourceLocation(), E); + if (Init.isInvalid()) + return ExprError(); + E = Init.getAs<Expr>(); + } else { + // Otherwise, the va_list argument must be an l-value because + // it is modified by va_arg. + if (!E->isTypeDependent() && + CheckForModifiableLvalue(E, BuiltinLoc, *this)) + return ExprError(); + } } - if (!E->isTypeDependent() && - !Context.hasSameType(VaListType, E->getType())) { + 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()); - } if (!TInfo->getType()->isDependentType()) { if (RequireCompleteType(TInfo->getTypeLoc().getBeginLoc(), TInfo->getType(), @@ -11573,7 +11768,7 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc, } QualType T = TInfo->getType().getNonLValueExprType(Context); - return new (Context) VAArgExpr(BuiltinLoc, E, TInfo, RPLoc, T); + return new (Context) VAArgExpr(BuiltinLoc, E, TInfo, RPLoc, T, IsMS); } ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) { @@ -11627,6 +11822,25 @@ Sema::ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&Exp) { return true; } +static bool maybeDiagnoseAssignmentToFunction(Sema &S, QualType DstType, + const Expr *SrcExpr) { + if (!DstType->isFunctionPointerType() || + !SrcExpr->getType()->isFunctionType()) + return false; + + auto *DRE = dyn_cast<DeclRefExpr>(SrcExpr->IgnoreParenImpCasts()); + if (!DRE) + return false; + + auto *FD = dyn_cast<FunctionDecl>(DRE->getDecl()); + if (!FD) + return false; + + return !S.checkAddressOfFunctionIsAvailable(FD, + /*Complain=*/true, + SrcExpr->getLocStart()); +} + bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, SourceLocation Loc, QualType DstType, QualType SrcType, @@ -11759,6 +11973,12 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, DiagKind = diag::err_arc_weak_unavailable_assign; break; case Incompatible: + if (maybeDiagnoseAssignmentToFunction(*this, DstType, SrcExpr)) { + if (Complained) + *Complained = true; + return true; + } + DiagKind = diag::err_typecheck_convert_incompatible; ConvHints.tryToFixConversion(SrcExpr, SrcType, DstType, *this); MayHaveConvFixit = true; @@ -11797,9 +12017,8 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, // If we can fix the conversion, suggest the FixIts. assert(ConvHints.isNull() || Hint.isNull()); if (!ConvHints.isNull()) { - for (std::vector<FixItHint>::iterator HI = ConvHints.Hints.begin(), - HE = ConvHints.Hints.end(); HI != HE; ++HI) - FDiag << *HI; + for (FixItHint &H : ConvHints.Hints) + FDiag << H; } else { FDiag << Hint; } @@ -11816,7 +12035,7 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, if (SecondType == Context.OverloadTy) NoteAllOverloadCandidates(OverloadExpr::find(SrcExpr).Expression, - FirstType); + FirstType, /*TakingAddress=*/true); if (CheckInferredResultType) EmitRelatedResultTypeNote(SrcExpr); @@ -11974,16 +12193,16 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, if (!Folded || !AllowFold) { if (!Diagnoser.Suppress) { Diagnoser.diagnoseNotICE(*this, DiagLoc, E->getSourceRange()); - for (unsigned I = 0, N = Notes.size(); I != N; ++I) - Diag(Notes[I].first, Notes[I].second); + for (const PartialDiagnosticAt &Note : Notes) + Diag(Note.first, Note.second); } return ExprError(); } Diagnoser.diagnoseFold(*this, DiagLoc, E->getSourceRange()); - for (unsigned I = 0, N = Notes.size(); I != N; ++I) - Diag(Notes[I].first, Notes[I].second); + for (const PartialDiagnosticAt &Note : Notes) + Diag(Note.first, Note.second); if (Result) *Result = EvalResult.Val.getInt(); @@ -12417,10 +12636,15 @@ static bool isVariableAlreadyCapturedInScopeInfo(CapturingScopeInfo *CSI, VarDec // Compute the type of an expression that refers to this variable. DeclRefType = CaptureType.getNonReferenceType(); - + + // Similarly to mutable captures in lambda, all the OpenMP captures by copy + // are mutable in the sense that user can change their value - they are + // private instances of the captured declarations. const CapturingScopeInfo::Capture &Cap = CSI->getCapture(Var); if (Cap.isCopyCapture() && - !(isa<LambdaScopeInfo>(CSI) && cast<LambdaScopeInfo>(CSI)->Mutable)) + !(isa<LambdaScopeInfo>(CSI) && cast<LambdaScopeInfo>(CSI)->Mutable) && + !(isa<CapturedRegionScopeInfo>(CSI) && + cast<CapturedRegionScopeInfo>(CSI)->CapRegionKind == CR_OpenMP)) DeclRefType.addConst(); return true; } @@ -12608,9 +12832,17 @@ static bool captureInCapturedRegion(CapturedRegionScopeInfo *RSI, // By default, capture variables by reference. bool ByRef = true; // Using an LValue reference type is consistent with Lambdas (see below). - if (S.getLangOpts().OpenMP && S.IsOpenMPCapturedVar(Var)) - DeclRefType = DeclRefType.getUnqualifiedType(); - CaptureType = S.Context.getLValueReferenceType(DeclRefType); + if (S.getLangOpts().OpenMP) { + ByRef = S.IsOpenMPCapturedByRef(Var, RSI); + if (S.IsOpenMPCapturedVar(Var)) + DeclRefType = DeclRefType.getUnqualifiedType(); + } + + if (ByRef) + CaptureType = S.Context.getLValueReferenceType(DeclRefType); + else + CaptureType = DeclRefType; + Expr *CopyExpr = nullptr; if (BuildAndDiagnose) { // The current implementation assumes that all variables are captured @@ -12836,21 +13068,6 @@ bool Sema::tryCaptureVariable( if (isVariableAlreadyCapturedInScopeInfo(CSI, Var, Nested, CaptureType, DeclRefType)) break; - if (getLangOpts().OpenMP) { - if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(CSI)) { - // OpenMP private variables should not be captured in outer scope, so - // just break here. - if (RSI->CapRegionKind == CR_OpenMP) { - if (isOpenMPPrivateVar(Var, OpenMPLevel)) { - Nested = true; - DeclRefType = DeclRefType.getUnqualifiedType(); - CaptureType = Context.getLValueReferenceType(DeclRefType); - break; - } - ++OpenMPLevel; - } - } - } // If we are instantiating a generic lambda call operator body, // we do not want to capture new variables. What was captured // during either a lambdas transformation or initial parsing @@ -12996,6 +13213,29 @@ bool Sema::tryCaptureVariable( } while (!QTy.isNull() && QTy->isVariablyModifiedType()); } + if (getLangOpts().OpenMP) { + if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(CSI)) { + // OpenMP private variables should not be captured in outer scope, so + // just break here. Similarly, global variables that are captured in a + // target region should not be captured outside the scope of the region. + if (RSI->CapRegionKind == CR_OpenMP) { + auto isTargetCap = isOpenMPTargetCapturedVar(Var, OpenMPLevel); + // When we detect target captures we are looking from inside the + // target region, therefore we need to propagate the capture from the + // enclosing region. Therefore, the capture is not initially nested. + if (isTargetCap) + FunctionScopesIndex--; + + if (isTargetCap || isOpenMPPrivateVar(Var, OpenMPLevel)) { + Nested = !isTargetCap; + DeclRefType = DeclRefType.getUnqualifiedType(); + CaptureType = Context.getLValueReferenceType(DeclRefType); + break; + } + ++OpenMPLevel; + } + } + } if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_None && !Explicit) { // No capture-default, and this is not an explicit capture // so cannot capture this variable. @@ -13152,15 +13392,13 @@ ExprResult Sema::ActOnConstantExpression(ExprResult Res) { } void Sema::CleanupVarDeclMarking() { - for (llvm::SmallPtrSetIterator<Expr*> i = MaybeODRUseExprs.begin(), - e = MaybeODRUseExprs.end(); - i != e; ++i) { + for (Expr *E : MaybeODRUseExprs) { VarDecl *Var; SourceLocation Loc; - if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(*i)) { + if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { Var = cast<VarDecl>(DRE->getDecl()); Loc = DRE->getLocation(); - } else if (MemberExpr *ME = dyn_cast<MemberExpr>(*i)) { + } else if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) { Var = cast<VarDecl>(ME->getMemberDecl()); Loc = ME->getMemberLoc(); } else { @@ -13217,7 +13455,7 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc, } if (!isTemplateInstantiation(TSK)) - return; + return; // Instantiate, but do not mark as odr-used, variable templates. MarkODRUsed = false; @@ -13316,7 +13554,8 @@ static void MarkExprReferenced(Sema &SemaRef, SourceLocation Loc, if (!MD) return; // Only attempt to devirtualize if this is truly a virtual call. - bool IsVirtualCall = MD->isVirtual() && !ME->hasQualifier(); + bool IsVirtualCall = MD->isVirtual() && + ME->performsVirtualDispatch(SemaRef.getLangOpts()); if (!IsVirtualCall) return; const Expr *Base = ME->getBase(); @@ -13350,7 +13589,7 @@ void Sema::MarkMemberReferenced(MemberExpr *E) { // expression, is odr-used, unless it is a pure virtual function and its // name is not explicitly qualified. bool OdrUse = true; - if (!E->hasQualifier()) { + if (E->performsVirtualDispatch(getLangOpts())) { if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(E->getMemberDecl())) if (Method->isPure()) OdrUse = false; @@ -13633,7 +13872,7 @@ void Sema::DiagnoseAssignmentAsCondition(Expr *E) { Diag(Loc, diagnostic) << E->getSourceRange(); SourceLocation Open = E->getLocStart(); - SourceLocation Close = PP.getLocForEndOfToken(E->getSourceRange().getEnd()); + SourceLocation Close = getLocForEndOfToken(E->getSourceRange().getEnd()); Diag(Loc, diag::note_condition_assign_silence) << FixItHint::CreateInsertion(Open, "(") << FixItHint::CreateInsertion(Close, ")"); @@ -14309,6 +14548,11 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) { return ExprError(); } + // Expressions of unknown type. + case BuiltinType::OMPArraySection: + Diag(E->getLocStart(), diag::err_omp_array_section_use); + return ExprError(); + // Everything else should be impossible. #define BUILTIN_TYPE(Id, SingletonId) \ case BuiltinType::Id: |