From d78b21b38eb27e1f0c55bd93a9c49ea3392b2544 Mon Sep 17 00:00:00 2001 From: dim Date: Sun, 17 May 2015 20:38:01 +0000 Subject: For clang 3.4.1, when using -fformat-extensions, and warning about the FreeBSD-specific %D and %b printf format specifiers, avoid possible argument overruns. Also reduce the differences with the version added in r280031 (which has been sent upstream). Direct commit to stable/10, since head already has clang 3.6.0. --- contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp') diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp index 0530a04..edc9016 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp @@ -2980,18 +2980,21 @@ CheckPrintfHandler::HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier CoveredArgs.set(argIndex); } - // FreeBSD extensions + // FreeBSD kernel extensions. if (CS.getKind() == ConversionSpecifier::FreeBSDbArg || CS.getKind() == ConversionSpecifier::FreeBSDDArg) { - // claim the second argument + // We need at least two arguments. + if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1)) + return false; + + // Claim the second argument. CoveredArgs.set(argIndex + 1); - // Now type check the data expression that matches the - // format specifier. + // Type check the first argument (int for %b, pointer for %D) const Expr *Ex = getDataArg(argIndex); - const analyze_printf::ArgType &AT = + const analyze_printf::ArgType &AT = (CS.getKind() == ConversionSpecifier::FreeBSDbArg) ? - ArgType(S.Context.IntTy) : ArgType::CStrTy; + ArgType(S.Context.IntTy) : ArgType::CPointerTy; if (AT.isValid() && !AT.matchesType(S.Context, Ex->getType())) S.Diag(getLocationOfByte(CS.getStart()), diag::warn_printf_conversion_argument_type_mismatch) @@ -2999,8 +3002,7 @@ CheckPrintfHandler::HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier << getSpecifierRange(startSpecifier, specifierLen) << Ex->getSourceRange(); - // Now type check the data expression that matches the - // format specifier. + // Type check the second argument (char * for both %b and %D) Ex = getDataArg(argIndex + 1); const analyze_printf::ArgType &AT2 = ArgType::CStrTy; if (AT2.isValid() && !AT2.matchesType(S.Context, Ex->getType())) -- cgit v1.1