diff options
author | Jeff Mott <jeffrey.t.mott@intel.com> | 2020-06-15 06:08:58 -0700 |
---|---|---|
committer | Erich Keane <erich.keane@intel.com> | 2020-06-15 06:51:54 -0700 |
commit | 8799ebbc1f03a348f732fc14242ad4c395076bcc (patch) | |
tree | 27a44cc1859db0d73a458c0c16a4cdda29f949d7 /clang/lib/Sema/SemaChecking.cpp | |
parent | 33879aa0bf0079f81223037c8e412411a7d919bc (diff) | |
download | llvm-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.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: |