diff options
Diffstat (limited to 'lib/Sema')
| -rw-r--r-- | lib/Sema/SemaChecking.cpp | 21 | ||||
| -rw-r--r-- | lib/Sema/SemaDecl.cpp | 25 | ||||
| -rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 38 | ||||
| -rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 49 | ||||
| -rw-r--r-- | lib/Sema/SemaExpr.cpp | 10 | ||||
| -rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 1 | ||||
| -rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 15 | ||||
| -rw-r--r-- | lib/Sema/SemaOverload.cpp | 4 | ||||
| -rw-r--r-- | lib/Sema/SemaType.cpp | 19 |
9 files changed, 139 insertions, 43 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 044ec74679d5..b3ba86e0685b 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -9866,25 +9866,6 @@ void Sema::CheckBoolLikeConversion(Expr *E, SourceLocation CC) { ::CheckBoolLikeConversion(*this, E, CC); } -/// Diagnose when expression is an integer constant expression and its evaluation -/// results in integer overflow -void Sema::CheckForIntOverflow (Expr *E) { - // Use a work list to deal with nested struct initializers. - SmallVector<Expr *, 2> Exprs(1, E); - - do { - Expr *E = Exprs.pop_back_val(); - - if (isa<BinaryOperator>(E->IgnoreParenCasts())) { - E->IgnoreParenCasts()->EvaluateForOverflow(Context); - continue; - } - - if (auto InitList = dyn_cast<InitListExpr>(E)) - Exprs.append(InitList->inits().begin(), InitList->inits().end()); - } while (!Exprs.empty()); -} - namespace { /// \brief Visitor for expressions which looks for unsequenced operations on the /// same object. @@ -10386,7 +10367,7 @@ void Sema::CheckCompletedExpr(Expr *E, SourceLocation CheckLoc, if (!E->isInstantiationDependent()) CheckUnsequencedOperations(E); if (!IsConstexpr && !E->isValueDependent()) - CheckForIntOverflow(E); + E->EvaluateForOverflow(Context); DiagnoseMisalignedMembers(); } diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index f838c9a4877d..054ccb64cbec 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2960,6 +2960,20 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, RequiresAdjustment = true; } + if (OldTypeInfo.getNoCallerSavedRegs() != + NewTypeInfo.getNoCallerSavedRegs()) { + if (NewTypeInfo.getNoCallerSavedRegs()) { + AnyX86NoCallerSavedRegistersAttr *Attr = + New->getAttr<AnyX86NoCallerSavedRegistersAttr>(); + Diag(New->getLocation(), diag::err_function_attribute_mismatch) << Attr; + Diag(OldLocation, diag::note_previous_declaration); + return true; + } + + NewTypeInfo = NewTypeInfo.withNoCallerSavedRegs(true); + RequiresAdjustment = true; + } + if (RequiresAdjustment) { const FunctionType *AdjustedType = New->getType()->getAs<FunctionType>(); AdjustedType = Context.adjustFunctionType(AdjustedType, NewTypeInfo); @@ -7410,6 +7424,10 @@ class DifferentNameValidatorCCC : public CorrectionCandidateCallback { } // end anonymous namespace +void Sema::MarkTypoCorrectedFunctionDefinition(const NamedDecl *F) { + TypoCorrectedFunctionDefinitions.insert(F); +} + /// \brief Generate diagnostics for an invalid function redeclaration. /// /// This routine handles generating the diagnostic messages for an invalid @@ -7507,6 +7525,8 @@ static NamedDecl *DiagnoseInvalidRedeclaration( if ((*I)->getCanonicalDecl() == Canonical) Correction.setCorrectionDecl(*I); + // Let Sema know about the correction. + SemaRef.MarkTypoCorrectedFunctionDefinition(Result); SemaRef.diagnoseTypo( Correction, SemaRef.PDiag(IsLocalFriend @@ -11718,6 +11738,11 @@ Sema::CheckForFunctionRedefinition(FunctionDecl *FD, if (canRedefineFunction(Definition, getLangOpts())) return; + // Don't emit an error when this is redifinition of a typo-corrected + // definition. + if (TypoCorrectedFunctionDefinitions.count(Definition)) + return; + // If we don't have a visible definition of the function, and it's inline or // a template, skip the new definition. if (SkipBody && !hasVisibleDefinition(Definition) && diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 17c6975ca5e9..bb5434a03a10 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -1941,17 +1941,26 @@ static void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) { static void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) { if (hasDeclarator(D)) return; - if (S.CheckNoReturnAttr(attr)) return; + if (S.CheckNoReturnAttr(attr)) + return; if (!isa<ObjCMethodDecl>(D)) { S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) - << attr.getName() << ExpectedFunctionOrMethod; + << attr.getName() << ExpectedFunctionOrMethod; return; } - D->addAttr(::new (S.Context) - NoReturnAttr(attr.getRange(), S.Context, - attr.getAttributeSpellingListIndex())); + D->addAttr(::new (S.Context) NoReturnAttr( + attr.getRange(), S.Context, attr.getAttributeSpellingListIndex())); +} + +static void handleNoCallerSavedRegsAttr(Sema &S, Decl *D, + const AttributeList &Attr) { + if (S.CheckNoCallerSavedRegsAttr(Attr)) + return; + + D->addAttr(::new (S.Context) AnyX86NoCallerSavedRegistersAttr( + Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); } bool Sema::CheckNoReturnAttr(const AttributeList &attr) { @@ -1963,6 +1972,22 @@ bool Sema::CheckNoReturnAttr(const AttributeList &attr) { return false; } +bool Sema::CheckNoCallerSavedRegsAttr(const AttributeList &Attr) { + // Check whether the attribute is valid on the current target. + if (!Attr.existsInTarget(Context.getTargetInfo())) { + Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored) << Attr.getName(); + Attr.setInvalid(); + return true; + } + + if (!checkAttributeNumArgs(*this, Attr, 0)) { + Attr.setInvalid(); + return true; + } + + return false; +} + static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) { @@ -6428,6 +6453,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_TypeTagForDatatype: handleTypeTagForDatatypeAttr(S, D, Attr); break; + case AttributeList::AT_AnyX86NoCallerSavedRegisters: + handleNoCallerSavedRegsAttr(S, D, Attr); + break; case AttributeList::AT_RenderScriptKernel: handleSimpleAttribute<RenderScriptKernelAttr>(S, D, Attr); break; diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 4f51cd399c0c..fe9ba6f1f811 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -4313,6 +4313,51 @@ static void mergeInterfaceMethodToImpl(Sema &S, } } +/// Verify that the method parameters/return value have types that are supported +/// by the x86 target. +static void checkObjCMethodX86VectorTypes(Sema &SemaRef, + const ObjCMethodDecl *Method) { + assert(SemaRef.getASTContext().getTargetInfo().getTriple().getArch() == + llvm::Triple::x86 && + "x86-specific check invoked for a different target"); + SourceLocation Loc; + QualType T; + for (const ParmVarDecl *P : Method->parameters()) { + if (P->getType()->isVectorType()) { + Loc = P->getLocStart(); + T = P->getType(); + break; + } + } + if (Loc.isInvalid()) { + if (Method->getReturnType()->isVectorType()) { + Loc = Method->getReturnTypeSourceRange().getBegin(); + T = Method->getReturnType(); + } else + return; + } + + // Vector parameters/return values are not supported by objc_msgSend on x86 in + // iOS < 9 and macOS < 10.11. + const auto &Triple = SemaRef.getASTContext().getTargetInfo().getTriple(); + VersionTuple AcceptedInVersion; + if (Triple.getOS() == llvm::Triple::IOS) + AcceptedInVersion = VersionTuple(/*Major=*/9); + else if (Triple.isMacOSX()) + AcceptedInVersion = VersionTuple(/*Major=*/10, /*Minor=*/11); + else + return; + VersionTuple MethodVersion = Method->getVersionIntroduced(); + if (SemaRef.getASTContext().getTargetInfo().getPlatformMinVersion() >= + AcceptedInVersion && + (MethodVersion.empty() || MethodVersion >= AcceptedInVersion)) + return; + SemaRef.Diag(Loc, diag::err_objc_method_unsupported_param_ret_type) + << T << (Method->getReturnType()->isVectorType() ? /*return value*/ 1 + : /*parameter*/ 0) + << (Triple.isMacOSX() ? "macOS 10.11" : "iOS 9"); +} + Decl *Sema::ActOnMethodDeclaration( Scope *S, SourceLocation MethodLoc, SourceLocation EndLoc, @@ -4534,6 +4579,10 @@ Decl *Sema::ActOnMethodDeclaration( ObjCMethod->SetRelatedResultType(); } + if (MethodDefinition && + Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86) + checkObjCMethodX86VectorTypes(*this, ObjCMethod); + ActOnDocumentableDecl(ObjCMethod); return ObjCMethod; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 00480f821fc6..f7307f35568d 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -5275,8 +5275,7 @@ ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc, if (Fn->getType() == Context.OverloadTy) { OverloadExpr::FindResult find = OverloadExpr::find(Fn); - // We aren't supposed to apply this logic for if there'Scope an '&' - // involved. + // We aren't supposed to apply this logic if there's an '&' involved. if (!find.HasFormOfMemberPointer) { OverloadExpr *ovl = find.Expression; if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(ovl)) @@ -6432,14 +6431,13 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS, return S.Context .getQualifiedType(CompositeTy.getUnqualifiedType(), CompositeQuals) .withCVRQualifiers(MergedCVRQual); - } else - return CompositeTy.withCVRQualifiers(MergedCVRQual); + } + return CompositeTy.withCVRQualifiers(MergedCVRQual); }(); if (IsBlockPointer) ResultTy = S.Context.getBlockPointerType(ResultTy); - else { + else ResultTy = S.Context.getPointerType(ResultTy); - } LHS = S.ImpCastExprToType(LHS.get(), ResultTy, LHSCastKind); RHS = S.ImpCastExprToType(RHS.get(), ResultTy, RHSCastKind); diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 9cc443ed4fd9..a44e9243e3c5 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -595,7 +595,6 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { break; } } - CheckForIntOverflow(ValueExpr); // FIXME: Do I need to do anything special with BoolTy expressions? // Look for the appropriate method within NSNumber. diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index fb13669407fc..43fd055bbc56 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -824,21 +824,18 @@ DSAStackTy::hasDSA(ValueDecl *D, if (isStackEmpty()) return {}; D = getCanonicalDecl(D); - auto StartI = std::next(Stack.back().first.rbegin()); + auto I = (FromParent && Stack.back().first.size() > 1) + ? std::next(Stack.back().first.rbegin()) + : Stack.back().first.rbegin(); auto EndI = Stack.back().first.rend(); - if (FromParent && StartI != EndI) - StartI = std::next(StartI); - if (StartI == EndI) - return {}; - auto I = std::prev(StartI); - do { - ++I; + while (std::distance(I, EndI) > 1) { + std::advance(I, 1); if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive)) continue; DSAVarData DVar = getDSA(I, D); if (CPred(DVar.CKind)) return DVar; - } while (I != EndI); + } return {}; } diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 29ba34479dab..782c377e3202 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -11426,6 +11426,10 @@ static void AddOverloadedCallCandidate(Sema &S, assert(!KnownValid && "Explicit template arguments?"); return; } + // Prevent ill-formed function decls to be added as overload candidates. + if (!dyn_cast<FunctionProtoType>(Func->getType()->getAs<FunctionType>())) + return; + S.AddOverloadCandidate(Func, FoundDecl, Args, CandidateSet, /*SuppressUsedConversions=*/false, PartialOverloading); diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 279b9ecef94e..bcc66bbd1c0a 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -119,8 +119,9 @@ static void diagnoseBadTypeAttribute(Sema &S, const AttributeList &attr, // Function type attributes. #define FUNCTION_TYPE_ATTRS_CASELIST \ - case AttributeList::AT_NoReturn: \ - case AttributeList::AT_Regparm: \ + case AttributeList::AT_NoReturn: \ + case AttributeList::AT_Regparm: \ + case AttributeList::AT_AnyX86NoCallerSavedRegisters: \ CALLING_CONV_ATTRS_CASELIST // Microsoft-specific type qualifiers. @@ -6371,6 +6372,20 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state, return true; } + if (attr.getKind() == AttributeList::AT_AnyX86NoCallerSavedRegisters) { + if (S.CheckNoCallerSavedRegsAttr(attr)) + return true; + + // Delay if this is not a function type. + if (!unwrapped.isFunctionType()) + return false; + + FunctionType::ExtInfo EI = + unwrapped.get()->getExtInfo().withNoCallerSavedRegs(true); + type = unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI)); + return true; + } + if (attr.getKind() == AttributeList::AT_Regparm) { unsigned value; if (S.CheckRegparmAttr(attr, value)) |
