aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorJeff Mott <jeffrey.t.mott@intel.com>2020-06-15 06:08:58 -0700
committerErich Keane <erich.keane@intel.com>2020-06-15 06:51:54 -0700
commit8799ebbc1f03a348f732fc14242ad4c395076bcc (patch)
tree27a44cc1859db0d73a458c0c16a4cdda29f949d7 /clang/lib/Sema/SemaChecking.cpp
parent33879aa0bf0079f81223037c8e412411a7d919bc (diff)
downloadllvm-8799ebbc1f03a348f732fc14242ad4c395076bcc.zip
llvm-8799ebbc1f03a348f732fc14242ad4c395076bcc.tar.gz
llvm-8799ebbc1f03a348f732fc14242ad4c395076bcc.tar.bz2
[clang] Fix or emit diagnostic for checked arithmetic builtins with
_ExtInt types - Fix computed size for _ExtInt types passed to checked arithmetic builtins. - Emit diagnostic when signed _ExtInt larger than 128-bits is passed to __builtin_mul_overflow. - Change Sema checks for builtins to accept placeholder types. Differential Revision: https://reviews.llvm.org/D81420
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: