diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index 3c76c72271..d846b248d4 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -446,7 +446,7 @@ ulpsFromBoundary(const integerPart *parts, unsigned int bits, bool isNearest) if (~parts[count]) return ~(integerPart) 0; /* A lot. */ - return -parts[0]; + return (~parts[0] + 1); } return ~(integerPart) 0; /* A lot. */ diff --git a/lib/Support/StringRef.cpp b/lib/Support/StringRef.cpp index ddece087a9..52b949d826 100644 --- a/lib/Support/StringRef.cpp +++ b/lib/Support/StringRef.cpp @@ -12,6 +12,7 @@ #include "llvm/ADT/Hashing.h" #include "llvm/ADT/edit_distance.h" #include +#include using namespace llvm; @@ -393,13 +394,16 @@ bool llvm::getAsSignedInteger(StringRef Str, unsigned Radix, // Get the positive part of the value. if (getAsUnsignedInteger(Str.substr(1), Radix, ULLVal) || - // Reject values so large they'd overflow as negative signed, but allow - // "-0". This negates the unsigned so that the negative isn't undefined - // on signed overflow. - (long long)-ULLVal > 0) + // Reject values larger than what can be represented as negative signed. + // The most negative long long is LLONG_MIN, which has magnitude + // (LLONG_MAX + 1). Values larger than this magnitude cannot be negated + // without overflow. + ULLVal > static_cast( + std::numeric_limits::max()) + + 1) return true; - Result = -ULLVal; + Result = (~ULLVal + 1); return false; } diff --git a/lib/Support/TimeValue.cpp b/lib/Support/TimeValue.cpp index 136b93ecee..06de27bbda 100644 --- a/lib/Support/TimeValue.cpp +++ b/lib/Support/TimeValue.cpp @@ -19,8 +19,7 @@ using namespace sys; const TimeValue::SecondsType TimeValue::PosixZeroTimeSeconds = -946684800; -const TimeValue::SecondsType - TimeValue::Win32ZeroTimeSeconds = -12591158400ULL; +const TimeValue::SecondsType TimeValue::Win32ZeroTimeSeconds = -12591158400LL; void TimeValue::normalize( void ) { diff --git a/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/lib/Transforms/Scalar/LoopStrengthReduce.cpp index 3ab9367a6b..60962ec69a 100644 --- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -1395,8 +1395,11 @@ static bool isAMCompletelyFolded(const TargetTransformInfo &TTI, // ICmpZero -1*ScaleReg + BaseOffset => ICmp ScaleReg, BaseOffset // Offs is the ICmp immediate. if (Scale == 0) - // The cast does the right thing with INT64_MIN. - BaseOffset = -(uint64_t)BaseOffset; + // Negate BaseOffset using two's complement (~x + 1) to avoid undefined + // behavior. Simple negation (-BaseOffset) would be undefined for + // INT64_MIN since -INT64_MIN cannot fit in int64_t. Two's complement + // gives the expected wraparound behavior: -INT64_MIN becomes INT64_MIN. + BaseOffset = ~BaseOffset + 1ULL; return TTI.isLegalICmpImmediate(BaseOffset); } @@ -3000,7 +3003,7 @@ void LSRInstance::CollectFixupsAndInitialFormulae() { // of -1) are now also interesting. for (size_t i = 0, e = Factors.size(); i != e; ++i) if (Factors[i] != -1) - Factors.insert(-(uint64_t)Factors[i]); + Factors.insert(~Factors[i] + 1ULL); Factors.insert(-1); } @@ -3739,7 +3742,7 @@ void LSRInstance::GenerateCrossUseConstantOffsets() { const SCEV *OrigReg = WI.OrigReg; Type *IntTy = SE.getEffectiveSCEVType(OrigReg->getType()); - const SCEV *NegImmS = SE.getSCEV(ConstantInt::get(IntTy, -(uint64_t)Imm)); + const SCEV *NegImmS = SE.getSCEV(ConstantInt::get(IntTy, ~Imm + 1ULL)); unsigned BitWidth = SE.getTypeSizeInBits(IntTy); // TODO: Use a more targeted data structure. @@ -3754,8 +3757,8 @@ void LSRInstance::GenerateCrossUseConstantOffsets() { if (F.ScaledReg == OrigReg) { int64_t Offset = (uint64_t)F.BaseOffset + Imm * (uint64_t)F.Scale; // Don't create 50 + reg(-50). - if (F.referencesReg(SE.getSCEV( - ConstantInt::get(IntTy, -(uint64_t)Offset)))) + if (F.referencesReg( + SE.getSCEV(ConstantInt::get(IntTy, ~Offset + 1ULL)))) continue; Formula NewF = F; NewF.BaseOffset = Offset; @@ -4556,7 +4559,7 @@ Value *LSRInstance::Expand(const LSRFixup &LF, const Formula &F, // The other interesting way of "folding" with an ICmpZero is to use a // negated immediate. if (!ICmpScaledV) - ICmpScaledV = ConstantInt::get(IntTy, -(uint64_t)Offset); + ICmpScaledV = ConstantInt::get(IntTy, ~Offset + 1ULL); else { Ops.push_back(SE.getUnknown(ICmpScaledV)); ICmpScaledV = ConstantInt::get(IntTy, Offset); @@ -4608,8 +4611,8 @@ Value *LSRInstance::Expand(const LSRFixup &LF, const Formula &F, assert((F.Scale == 0 || F.Scale == 1) && "ICmp does not support folding a global value and " "a scale at the same time!"); - Constant *C = ConstantInt::getSigned(SE.getEffectiveSCEVType(OpTy), - -(uint64_t)Offset); + Constant *C = + ConstantInt::getSigned(SE.getEffectiveSCEVType(OpTy), ~Offset + 1ULL); if (C->getType() != OpTy) C = ConstantExpr::getCast(CastInst::getCastOpcode(C, false, OpTy, false), diff --git a/tools/clang/lib/AST/ExprConstant.cpp b/tools/clang/lib/AST/ExprConstant.cpp index 69e0760bce..9336a80e05 100644 --- a/tools/clang/lib/AST/ExprConstant.cpp +++ b/tools/clang/lib/AST/ExprConstant.cpp @@ -6558,7 +6558,7 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { // handle all cases where the expression has side-effects. if (E->getArg(0)->HasSideEffects(Info.Ctx)) { if (E->getArg(1)->EvaluateKnownConstInt(Info.Ctx).getZExtValue() <= 1) - return Success(-1ULL, E); + return Success(~0ULL, E); return Success(0, E); } @@ -6573,7 +6573,7 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { return Error(E); case EvalInfo::EM_ConstantExpressionUnevaluated: case EvalInfo::EM_PotentialConstantExpressionUnevaluated: - return Success(-1ULL, E); + return Success(~0ULL, E); } llvm_unreachable("Invalid EvalMode!"); } diff --git a/tools/clang/lib/AST/MicrosoftMangle.cpp b/tools/clang/lib/AST/MicrosoftMangle.cpp index 40dca1bb1b..ae9f1cd7f8 100644 --- a/tools/clang/lib/AST/MicrosoftMangle.cpp +++ b/tools/clang/lib/AST/MicrosoftMangle.cpp @@ -633,7 +633,7 @@ void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) { uint64_t Value = static_cast(Number); if (Number < 0) { - Value = -Value; + Value = ~Value + 1ULL; Out << '?'; } @@ -2308,7 +2308,7 @@ static void mangleThunkThisAdjustment(const CXXMethodDecl *MD, Out << AccessSpec; Mangler.mangleNumber( static_cast(Adjustment.Virtual.Microsoft.VtordispOffset)); - Mangler.mangleNumber(-static_cast(Adjustment.NonVirtual)); + Mangler.mangleNumber(~static_cast(Adjustment.NonVirtual) + 1); } } else if (Adjustment.NonVirtual != 0) { switch (MD->getAccess()) { @@ -2323,7 +2323,7 @@ static void mangleThunkThisAdjustment(const CXXMethodDecl *MD, case AS_public: Out << 'W'; } - Mangler.mangleNumber(-static_cast(Adjustment.NonVirtual)); + Mangler.mangleNumber(~static_cast(Adjustment.NonVirtual) + 1); } else { switch (MD->getAccess()) { case AS_none: diff --git a/tools/clang/lib/CodeGen/CoverageMappingGen.cpp b/tools/clang/lib/CodeGen/CoverageMappingGen.cpp index eca91590e6..e16e015a74 100644 --- a/tools/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/tools/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -116,7 +116,7 @@ class CoverageMappingBuilder { /// \brief Return the start location of an included file or expanded macro. SourceLocation getStartOfFileOrMacro(SourceLocation Loc) { if (Loc.isMacroID()) - return Loc.getLocWithOffset(-SM.getFileOffset(Loc)); + return Loc.getLocWithOffset(~SM.getFileOffset(Loc) + 1); return SM.getLocForStartOfFile(SM.getFileID(Loc)); } diff --git a/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp b/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp index 97fe28be7f..698d34c774 100644 --- a/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -639,8 +639,8 @@ llvm::Constant * ItaniumCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) { // Itanium C++ ABI 2.3: // A NULL pointer is represented as -1. - if (MPT->isMemberDataPointer()) - return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL, /*isSigned=*/true); + if (MPT->isMemberDataPointer()) + return llvm::ConstantInt::get(CGM.PtrDiffTy, -1LL, /*isSigned=*/true); llvm::Constant *Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0); llvm::Constant *Values[2] = { Zero, Zero }; @@ -1023,7 +1023,7 @@ static CharUnits computeOffsetHint(ASTContext &Context, // If Dst is not derived from Src we can skip the whole computation below and // return that Src is not a public base of Dst. Record all inheritance paths. if (!Dst->isDerivedFrom(Src, Paths)) - return CharUnits::fromQuantity(-2ULL); + return CharUnits::fromQuantity(-2LL); unsigned NumPublicPaths = 0; CharUnits Offset; @@ -1040,7 +1040,7 @@ static CharUnits computeOffsetHint(ASTContext &Context, // If the path contains a virtual base class we can't give any hint. // -1: no hint. if (J->Base->isVirtual()) - return CharUnits::fromQuantity(-1ULL); + return CharUnits::fromQuantity(-1LL); if (NumPublicPaths > 1) // Won't use offsets, skip computation. continue; @@ -1053,11 +1053,11 @@ static CharUnits computeOffsetHint(ASTContext &Context, // -2: Src is not a public base of Dst. if (NumPublicPaths == 0) - return CharUnits::fromQuantity(-2ULL); + return CharUnits::fromQuantity(-2LL); // -3: Src is a multiple public base type but never a virtual base type. if (NumPublicPaths > 1) - return CharUnits::fromQuantity(-3ULL); + return CharUnits::fromQuantity(-3LL); // Otherwise, the Src type is a unique public nonvirtual base type of Dst. // Return the offset of Src from the origin of Dst. @@ -1154,7 +1154,7 @@ llvm::Value *ItaniumCXXABI::EmitDynamicCastToVoid(CodeGenFunction &CGF, // Get the offset-to-top from the vtable. llvm::Value *OffsetToTop = - CGF.Builder.CreateConstInBoundsGEP1_64(VTable, -2ULL); + CGF.Builder.CreateConstInBoundsGEP1_64(VTable, -2LL); OffsetToTop = CGF.Builder.CreateLoad(OffsetToTop, "offset.to.top"); // Finally, add the offset to the pointer. diff --git a/tools/clang/lib/CodeGen/TargetInfo.cpp b/tools/clang/lib/CodeGen/TargetInfo.cpp index aba43964d9..aaf63355af 100644 --- a/tools/clang/lib/CodeGen/TargetInfo.cpp +++ b/tools/clang/lib/CodeGen/TargetInfo.cpp @@ -1283,7 +1283,7 @@ llvm::Value *X86_32ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, Addr = CGF.Builder.CreateGEP(Addr, Offset); llvm::Value *AsInt = CGF.Builder.CreatePtrToInt(Addr, CGF.Int32Ty); - llvm::Value *Mask = llvm::ConstantInt::get(CGF.Int32Ty, -Align); + llvm::Value *Mask = llvm::ConstantInt::get(CGF.Int32Ty, ~Align + 1); Addr = CGF.Builder.CreateIntToPtr(CGF.Builder.CreateAnd(AsInt, Mask), Addr->getType(), "ap.cur.aligned"); @@ -2849,7 +2849,7 @@ static llvm::Value *EmitVAArgFromMemory(llvm::Value *VAListAddr, overflow_arg_area = CGF.Builder.CreateGEP(overflow_arg_area, Offset); llvm::Value *AsInt = CGF.Builder.CreatePtrToInt(overflow_arg_area, CGF.Int64Ty); - llvm::Value *Mask = llvm::ConstantInt::get(CGF.Int64Ty, -(uint64_t)Align); + llvm::Value *Mask = llvm::ConstantInt::get(CGF.Int64Ty, ~Align + 1); overflow_arg_area = CGF.Builder.CreateIntToPtr(CGF.Builder.CreateAnd(AsInt, Mask), overflow_arg_area->getType(), diff --git a/tools/clang/lib/Format/Format.cpp b/tools/clang/lib/Format/Format.cpp index 7d556c9f0f..b6ca328972 100644 --- a/tools/clang/lib/Format/Format.cpp +++ b/tools/clang/lib/Format/Format.cpp @@ -1049,7 +1049,7 @@ class FormatTokenLexer { FormatTok = new (Allocator.Allocate()) FormatToken; readRawToken(*FormatTok); SourceLocation WhitespaceStart = - FormatTok->Tok.getLocation().getLocWithOffset(-TrailingWhitespace); + FormatTok->Tok.getLocation().getLocWithOffset(~TrailingWhitespace + 1); FormatTok->IsFirst = IsFirstToken; IsFirstToken = false; diff --git a/tools/clang/lib/Lex/Lexer.cpp b/tools/clang/lib/Lex/Lexer.cpp index 089e76b78b..aa72980e2f 100644 --- a/tools/clang/lib/Lex/Lexer.cpp +++ b/tools/clang/lib/Lex/Lexer.cpp @@ -480,7 +480,7 @@ static SourceLocation getBeginningOfFileToken(SourceLocation Loc, } // Create a lexer starting at the beginning of this token. - SourceLocation LexerStartLoc = Loc.getLocWithOffset(-LocInfo.second); + SourceLocation LexerStartLoc = Loc.getLocWithOffset(~LocInfo.second + 1); Lexer TheLexer(LexerStartLoc, LangOpts, BufStart, LexStart, Buffer.end()); TheLexer.SetCommentRetentionState(true); diff --git a/tools/clang/lib/Rewrite/Rewriter.cpp b/tools/clang/lib/Rewrite/Rewriter.cpp index be09a363a6..fa081d65ac 100644 --- a/tools/clang/lib/Rewrite/Rewriter.cpp +++ b/tools/clang/lib/Rewrite/Rewriter.cpp @@ -60,7 +60,7 @@ void RewriteBuffer::RemoveText(unsigned OrigOffset, unsigned Size, Buffer.erase(RealOffset, Size); // Add a delta so that future changes are offset correctly. - AddReplaceDelta(OrigOffset, -Size); + AddReplaceDelta(OrigOffset, ~Size + 1); if (removeLineIfEmpty) { // Find the line that the remove occurred and if it is completely empty @@ -86,7 +86,7 @@ void RewriteBuffer::RemoveText(unsigned OrigOffset, unsigned Size, } if (posI != end() && *posI == '\n') { Buffer.erase(curLineStartOffs, lineSize + 1/* + '\n'*/); - AddReplaceDelta(curLineStartOffs, -(lineSize + 1/* + '\n'*/)); + AddReplaceDelta(curLineStartOffs, ~(lineSize + 1 /* + '\n'*/) + 1); } } }