From d6974c010878cae1df5b27067230ee5dcbc63342 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 31 Jul 2021 15:13:42 -0400 Subject: [PATCH] [Analysis] improve function signature checking for snprintf The check for size_t parameter 1 was already here for snprintf_chk, but it wasn't applied to regular snprintf. This could lead to mismatching and eventually crashing as shown in: https://llvm.org/PR50885 (cherry picked from commit 7f5555776513f174729a686ed01270e23462aaf7) --- llvm/lib/Analysis/TargetLibraryInfo.cpp | 7 ++++--- .../test/Transforms/InstCombine/simplify-libcalls.ll | 12 ++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp index 4a8818f2e2a888..c3a609ee4fe140 100644 --- a/llvm/lib/Analysis/TargetLibraryInfo.cpp +++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp @@ -893,9 +893,10 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy, FTy.getReturnType()->isIntegerTy(32); case LibFunc_snprintf: - return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(2)->isPointerTy() && - FTy.getReturnType()->isIntegerTy(32)); + return NumParams == 3 && FTy.getParamType(0)->isPointerTy() && + IsSizeTTy(FTy.getParamType(1)) && + FTy.getParamType(2)->isPointerTy() && + FTy.getReturnType()->isIntegerTy(32); case LibFunc_snprintf_chk: return NumParams == 5 && FTy.getParamType(0)->isPointerTy() && diff --git a/llvm/test/Transforms/InstCombine/simplify-libcalls.ll b/llvm/test/Transforms/InstCombine/simplify-libcalls.ll index 25b168515cb821..f80286a8cc7e76 100644 --- a/llvm/test/Transforms/InstCombine/simplify-libcalls.ll +++ b/llvm/test/Transforms/InstCombine/simplify-libcalls.ll @@ -217,6 +217,18 @@ define double @fake_ldexp_16(i16 %x) { ret double %z } +; PR50885 - this would crash in ValueTracking. + +declare i32 @snprintf(i8*, double, i32*) + +define i32 @fake_snprintf(i32 %buf, double %len, i32 * %str) { +; CHECK-LABEL: @fake_snprintf( +; CHECK-NEXT: [[CALL:%.*]] = call i32 @snprintf(i8* undef, double [[LEN:%.*]], i32* [[STR:%.*]]) +; CHECK-NEXT: ret i32 [[CALL]] +; + %call = call i32 @snprintf(i8* undef, double %len, i32* %str) + ret i32 %call +} attributes #0 = { nobuiltin } attributes #1 = { builtin }