aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r--clang/lib/Sema/SemaChecking.cpp50
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: