diff options
author | Adam Magier <adam.a.magier.foss@gmail.com> | 2021-12-17 00:56:43 +0100 |
---|---|---|
committer | Adam Magier <adam.a.magier.foss@gmail.com> | 2022-01-12 01:11:52 +0100 |
commit | b2715660ed0f821619f51158fb92cd8bddd105d8 (patch) | |
tree | c5a6397cfd29adcd54d914327bfd3b98cbb98348 /clang/lib/CodeGen/CodeGenFunction.cpp | |
parent | b7f298f17416dec43269c47e9052ae537071bd92 (diff) | |
download | llvm-b2715660ed0f821619f51158fb92cd8bddd105d8.zip llvm-b2715660ed0f821619f51158fb92cd8bddd105d8.tar.gz llvm-b2715660ed0f821619f51158fb92cd8bddd105d8.tar.bz2 |
[clang][CodeGen][UBSan] VLA size checking for unsigned integer parameter
The code generation for the UBSan VLA size check was qualified by a con-
dition that the parameter must be a signed integer, however the C spec
does not make any distinction that only signed integer parameters can be
used to declare a VLA, only qualifying that it must be greater than zero
if it is not a constant.
Reviewed By: rjmccall
Differential Revision: https://reviews.llvm.org/D116048
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 640c73f..54ddbff 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -2247,32 +2247,36 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) { // Unknown size indication requires no size computation. // Otherwise, evaluate and record it. - if (const Expr *size = vat->getSizeExpr()) { + if (const Expr *sizeExpr = vat->getSizeExpr()) { // It's possible that we might have emitted this already, // e.g. with a typedef and a pointer to it. - llvm::Value *&entry = VLASizeMap[size]; + llvm::Value *&entry = VLASizeMap[sizeExpr]; if (!entry) { - llvm::Value *Size = EmitScalarExpr(size); + llvm::Value *size = EmitScalarExpr(sizeExpr); // C11 6.7.6.2p5: // If the size is an expression that is not an integer constant // expression [...] each time it is evaluated it shall have a value // greater than zero. - if (SanOpts.has(SanitizerKind::VLABound) && - size->getType()->isSignedIntegerType()) { + if (SanOpts.has(SanitizerKind::VLABound)) { SanitizerScope SanScope(this); - llvm::Value *Zero = llvm::Constant::getNullValue(Size->getType()); + llvm::Value *Zero = llvm::Constant::getNullValue(size->getType()); + clang::QualType SEType = sizeExpr->getType(); + llvm::Value *CheckCondition = + SEType->isSignedIntegerType() + ? Builder.CreateICmpSGT(size, Zero) + : Builder.CreateICmpUGT(size, Zero); llvm::Constant *StaticArgs[] = { - EmitCheckSourceLocation(size->getBeginLoc()), - EmitCheckTypeDescriptor(size->getType())}; - EmitCheck(std::make_pair(Builder.CreateICmpSGT(Size, Zero), - SanitizerKind::VLABound), - SanitizerHandler::VLABoundNotPositive, StaticArgs, Size); + EmitCheckSourceLocation(sizeExpr->getBeginLoc()), + EmitCheckTypeDescriptor(SEType)}; + EmitCheck(std::make_pair(CheckCondition, SanitizerKind::VLABound), + SanitizerHandler::VLABoundNotPositive, StaticArgs, size); } // Always zexting here would be wrong if it weren't // undefined behavior to have a negative bound. - entry = Builder.CreateIntCast(Size, SizeTy, /*signed*/ false); + // FIXME: What about when size's type is larger than size_t? + entry = Builder.CreateIntCast(size, SizeTy, /*signed*/ false); } } type = vat->getElementType(); |