diff options
author | George Burgess IV <george.burgess.iv@gmail.com> | 2015-12-02 21:58:08 +0000 |
---|---|---|
committer | George Burgess IV <george.burgess.iv@gmail.com> | 2015-12-02 21:58:08 +0000 |
commit | 3e3bb95b6951c313dd5dd1c099184c309a3952e2 (patch) | |
tree | 601f182e5509276b9319182864eac0e27a888b68 /clang/lib/Sema/SemaExpr.cpp | |
parent | ba904d4ecf66528be5dadd60665d5a979ce6b1a4 (diff) | |
download | bcm5719-llvm-3e3bb95b6951c313dd5dd1c099184c309a3952e2.tar.gz bcm5719-llvm-3e3bb95b6951c313dd5dd1c099184c309a3952e2.zip |
Add the `pass_object_size` attribute to clang.
`pass_object_size` is our way of enabling `__builtin_object_size` to
produce high quality results without requiring inlining to happen
everywhere.
A link to the design doc for this attribute is available at the
Differential review link below.
Differential Revision: http://reviews.llvm.org/D13263
llvm-svn: 254554
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 6ec5fe2e2fd..67c858ece0b 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -496,7 +496,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); @@ -511,9 +511,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()) { @@ -706,8 +713,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()); @@ -7338,7 +7345,7 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS, // Suppress this for references: C++ 8.5.3p5. if (!LHSType->isReferenceType()) { // FIXME: We potentially allocate here even if ConvertRHS is false. - RHS = DefaultFunctionArrayLvalueConversion(RHS.get()); + RHS = DefaultFunctionArrayLvalueConversion(RHS.get(), Diagnose); if (RHS.isInvalid()) return Incompatible; } @@ -9882,6 +9889,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; @@ -11831,6 +11844,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, @@ -11963,6 +11995,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; |