diff options
author | Andrew Kaylor <andrew.kaylor@intel.com> | 2017-09-19 20:26:40 +0000 |
---|---|---|
committer | Andrew Kaylor <andrew.kaylor@intel.com> | 2017-09-19 20:26:40 +0000 |
commit | 3d0a540857edbd510e329f40581f6b2c1968ccca (patch) | |
tree | 89970f6001c5631849102b8d31d368f9df08b17e /clang/lib/AST/Expr.cpp | |
parent | 317782122c8a7d603152b47a2ac2d3f046eb8df7 (diff) | |
download | bcm5719-llvm-3d0a540857edbd510e329f40581f6b2c1968ccca.tar.gz bcm5719-llvm-3d0a540857edbd510e329f40581f6b2c1968ccca.zip |
Teach clang to tolerate the 'p = nullptr + n' idiom used by glibc
Differential Revision: https://reviews.llvm.org/D37042
llvm-svn: 313666
Diffstat (limited to 'clang/lib/AST/Expr.cpp')
-rw-r--r-- | clang/lib/AST/Expr.cpp | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 7c62ccf052c..f04a78f609a 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1829,6 +1829,45 @@ OverloadedOperatorKind BinaryOperator::getOverloadedOperator(Opcode Opc) { return OverOps[Opc]; } +bool BinaryOperator::isNullPointerArithmeticExtension(ASTContext &Ctx, + Opcode Opc, + Expr *LHS, Expr *RHS) { + if (Opc != BO_Add) + return false; + + // Check that we have one pointer and one integer operand. + Expr *PExp; + Expr *IExp; + if (LHS->getType()->isPointerType()) { + if (!RHS->getType()->isIntegerType()) + return false; + PExp = LHS; + IExp = RHS; + } else if (RHS->getType()->isPointerType()) { + if (!LHS->getType()->isIntegerType()) + return false; + PExp = RHS; + IExp = LHS; + } else { + return false; + } + + // Check that the pointer is a nullptr. + if (!PExp->IgnoreParenCasts() + ->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNotNull)) + return false; + + // Check that the pointee type is char-sized. + const PointerType *PTy = PExp->getType()->getAs<PointerType>(); + if (!PTy || !PTy->getPointeeType()->isCharType()) + return false; + + // Check that the integer type is pointer-sized. + if (Ctx.getTypeSize(IExp->getType()) != Ctx.getTypeSize(PExp->getType())) + return false; + + return true; +} InitListExpr::InitListExpr(const ASTContext &C, SourceLocation lbraceloc, ArrayRef<Expr*> initExprs, SourceLocation rbraceloc) : Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false, |