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/CodeGen/CGExprScalar.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/CodeGen/CGExprScalar.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 1c95ba382dc..a488c80979f 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -2678,6 +2678,30 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF, unsigned width = cast<llvm::IntegerType>(index->getType())->getBitWidth(); auto &DL = CGF.CGM.getDataLayout(); auto PtrTy = cast<llvm::PointerType>(pointer->getType()); + + // Some versions of glibc and gcc use idioms (particularly in their malloc + // routines) that add a pointer-sized integer (known to be a pointer value) + // to a null pointer in order to cast the value back to an integer or as + // part of a pointer alignment algorithm. This is undefined behavior, but + // we'd like to be able to compile programs that use it. + // + // Normally, we'd generate a GEP with a null-pointer base here in response + // to that code, but it's also UB to dereference a pointer created that + // way. Instead (as an acknowledged hack to tolerate the idiom) we will + // generate a direct cast of the integer value to a pointer. + // + // The idiom (p = nullptr + N) is not met if any of the following are true: + // + // The operation is subtraction. + // The index is not pointer-sized. + // The pointer type is not byte-sized. + // + if (BinaryOperator::isNullPointerArithmeticExtension(CGF.getContext(), + op.Opcode, + expr->getLHS(), + expr->getRHS())) + return CGF.Builder.CreateIntToPtr(index, pointer->getType()); + if (width != DL.getTypeSizeInBits(PtrTy)) { // Zero-extend or sign-extend the pointer value according to // whether the index is signed or not. |