diff options
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 85126e0..22f25f9 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -283,48 +283,60 @@ static bool SemaBuiltinAlignment(Sema &S, CallExpr *TheCall, unsigned ID) { return false; } -static bool SemaBuiltinOverflow(Sema &S, CallExpr *TheCall) { +static bool SemaBuiltinOverflow(Sema &S, CallExpr *TheCall, + unsigned BuiltinID) { if (checkArgCount(S, TheCall, 3)) return true; // First two arguments should be integers. for (unsigned I = 0; I < 2; ++I) { - ExprResult Arg = TheCall->getArg(I); + ExprResult Arg = S.DefaultFunctionArrayLvalueConversion(TheCall->getArg(I)); + if (Arg.isInvalid()) return true; + TheCall->setArg(I, Arg.get()); + QualType Ty = Arg.get()->getType(); if (!Ty->isIntegerType()) { S.Diag(Arg.get()->getBeginLoc(), diag::err_overflow_builtin_must_be_int) << Ty << Arg.get()->getSourceRange(); return true; } - InitializedEntity Entity = InitializedEntity::InitializeParameter( - S.getASTContext(), Ty, /*consume*/ false); - Arg = S.PerformCopyInitialization(Entity, SourceLocation(), Arg); - if (Arg.isInvalid()) - return true; - TheCall->setArg(I, Arg.get()); } // Third argument should be a pointer to a non-const integer. // IRGen correctly handles volatile, restrict, and address spaces, and // the other qualifiers aren't possible. { - ExprResult Arg = TheCall->getArg(2); + ExprResult Arg = S.DefaultFunctionArrayLvalueConversion(TheCall->getArg(2)); + if (Arg.isInvalid()) return true; + TheCall->setArg(2, Arg.get()); + QualType Ty = Arg.get()->getType(); const auto *PtrTy = Ty->getAs<PointerType>(); - if (!(PtrTy && PtrTy->getPointeeType()->isIntegerType() && - !PtrTy->getPointeeType().isConstQualified())) { + if (!PtrTy || + !PtrTy->getPointeeType()->isIntegerType() || + PtrTy->getPointeeType().isConstQualified()) { S.Diag(Arg.get()->getBeginLoc(), diag::err_overflow_builtin_must_be_ptr_int) - << Ty << Arg.get()->getSourceRange(); + << Ty << Arg.get()->getSourceRange(); return true; } - InitializedEntity Entity = InitializedEntity::InitializeParameter( - S.getASTContext(), Ty, /*consume*/ false); - Arg = S.PerformCopyInitialization(Entity, SourceLocation(), Arg); - if (Arg.isInvalid()) - return true; - TheCall->setArg(2, Arg.get()); } + + // Disallow signed ExtIntType args larger than 128 bits to mul function until + // we improve backend support. + if (BuiltinID == Builtin::BI__builtin_mul_overflow) { + for (unsigned I = 0; I < 3; ++I) { + const auto Arg = TheCall->getArg(I); + // Third argument will be a pointer. + auto Ty = I < 2 ? Arg->getType() : Arg->getType()->getPointeeType(); + if (Ty->isExtIntType() && Ty->isSignedIntegerType() && + S.getASTContext().getIntWidth(Ty) > 128) + return S.Diag(Arg->getBeginLoc(), + diag::err_overflow_builtin_ext_int_max_size) + << 128; + } + } + return false; } @@ -1728,7 +1740,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, case Builtin::BI__builtin_add_overflow: case Builtin::BI__builtin_sub_overflow: case Builtin::BI__builtin_mul_overflow: - if (SemaBuiltinOverflow(*this, TheCall)) + if (SemaBuiltinOverflow(*this, TheCall, BuiltinID)) return ExprError(); break; case Builtin::BI__builtin_operator_new: |