diff options
author | 2018-12-29 09:11:32 +0000 | |
---|---|---|
committer | 2018-12-29 09:11:32 +0000 | |
commit | a2d20eaa3f8ec62a5e571b8687dde7995fcb1014 (patch) | |
tree | c820fe77bbb340e3063cf26ff49000bc6677a54e | |
parent | move kroute_find() call later (diff) | |
download | wireguard-openbsd-a2d20eaa3f8ec62a5e571b8687dde7995fcb1014.tar.xz wireguard-openbsd-a2d20eaa3f8ec62a5e571b8687dde7995fcb1014.zip |
The %b printf extension in the kernel is not fixed to a int type. On sparc64
there are various %llb formats. Adjust the code to handle the length specifiers
and type check like it is used by the regular case.
OK guenther@
-rw-r--r-- | gnu/llvm/tools/clang/include/clang/Analysis/Analyses/FormatString.h | 6 | ||||
-rw-r--r-- | gnu/llvm/tools/clang/lib/Analysis/FormatString.cpp | 9 | ||||
-rw-r--r-- | gnu/llvm/tools/clang/lib/Sema/SemaChecking.cpp | 36 |
3 files changed, 38 insertions, 13 deletions
diff --git a/gnu/llvm/tools/clang/include/clang/Analysis/Analyses/FormatString.h b/gnu/llvm/tools/clang/include/clang/Analysis/Analyses/FormatString.h index 8c531d638cc..e9f77f5dec6 100644 --- a/gnu/llvm/tools/clang/include/clang/Analysis/Analyses/FormatString.h +++ b/gnu/llvm/tools/clang/include/clang/Analysis/Analyses/FormatString.h @@ -227,8 +227,10 @@ public: bool isIntArg() const { return (kind >= IntArgBeg && kind <= IntArgEnd) || kind == FreeBSDrArg || kind == FreeBSDyArg; } - bool isUIntArg() const { return kind >= UIntArgBeg && kind <= UIntArgEnd; } - bool isAnyIntArg() const { return kind >= IntArgBeg && kind <= UIntArgEnd; } + bool isUIntArg() const { return (kind >= UIntArgBeg && kind <= UIntArgEnd) || + kind == FreeBSDbArg; } + bool isAnyIntArg() const { return (kind >= IntArgBeg && kind <= UIntArgEnd) || + kind == FreeBSDbArg; } bool isDoubleArg() const { return kind >= DoubleArgBeg && kind <= DoubleArgEnd; } diff --git a/gnu/llvm/tools/clang/lib/Analysis/FormatString.cpp b/gnu/llvm/tools/clang/lib/Analysis/FormatString.cpp index c62e537e92d..7e8930c964a 100644 --- a/gnu/llvm/tools/clang/lib/Analysis/FormatString.cpp +++ b/gnu/llvm/tools/clang/lib/Analysis/FormatString.cpp @@ -706,6 +706,10 @@ bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const { case ConversionSpecifier::XArg: case ConversionSpecifier::nArg: return true; + case ConversionSpecifier::FreeBSDbArg: + return Target.getTriple().isOSFreeBSD() || + Target.getTriple().isPS4() || + Target.getTriple().isOSOpenBSD(); case ConversionSpecifier::FreeBSDrArg: case ConversionSpecifier::FreeBSDyArg: return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4(); @@ -739,6 +743,10 @@ bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const { case ConversionSpecifier::ScanListArg: case ConversionSpecifier::ZArg: return true; + case ConversionSpecifier::FreeBSDbArg: + return Target.getTriple().isOSFreeBSD() || + Target.getTriple().isPS4() || + Target.getTriple().isOSOpenBSD(); case ConversionSpecifier::FreeBSDrArg: case ConversionSpecifier::FreeBSDyArg: return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4(); @@ -897,6 +905,7 @@ bool FormatSpecifier::hasStandardLengthConversionCombination() const { case ConversionSpecifier::uArg: case ConversionSpecifier::xArg: case ConversionSpecifier::XArg: + case ConversionSpecifier::FreeBSDbArg: return false; default: return true; diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaChecking.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaChecking.cpp index a6ce70646b9..30e693b558d 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaChecking.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaChecking.cpp @@ -6054,18 +6054,32 @@ CheckPrintfHandler::HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier // Claim the second argument. CoveredArgs.set(argIndex + 1); - // Type check the first argument (int for %b, pointer for %D) const Expr *Ex = getDataArg(argIndex); - const analyze_printf::ArgType &AT = - (CS.getKind() == ConversionSpecifier::FreeBSDbArg) ? - ArgType(S.Context.IntTy) : ArgType::CPointerTy; - if (AT.isValid() && !AT.matchesType(S.Context, Ex->getType())) - EmitFormatDiagnostic( - S.PDiag(diag::warn_format_conversion_argument_type_mismatch) - << AT.getRepresentativeTypeName(S.Context) << Ex->getType() - << false << Ex->getSourceRange(), - Ex->getLocStart(), /*IsStringLocation*/false, - getSpecifierRange(startSpecifier, specifierLen)); + if (CS.getKind() == ConversionSpecifier::FreeBSDDArg) { + // Type check the first argument (pointer for %D) + const analyze_printf::ArgType &AT = ArgType::CPointerTy; + if (AT.isValid() && !AT.matchesType(S.Context, Ex->getType())) + EmitFormatDiagnostic( + S.PDiag(diag::warn_format_conversion_argument_type_mismatch) + << AT.getRepresentativeTypeName(S.Context) << Ex->getType() + << false << Ex->getSourceRange(), + Ex->getLocStart(), /*IsStringLocation*/false, + getSpecifierRange(startSpecifier, specifierLen)); + } else { + // Check the length modifier for %b + if (!FS.hasValidLengthModifier(S.getASTContext().getTargetInfo())) + HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen, + diag::warn_format_nonsensical_length); + else if (!FS.hasStandardLengthModifier()) + HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen); + else if (!FS.hasStandardLengthConversionCombination()) + HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen, + diag::warn_format_non_standard_conversion_spec); + + // Type check the first argument of %b + if (!checkFormatExpr(FS, startSpecifier, specifierLen, Ex)) + return false; + } // Type check the second argument (char * for both %b and %D) Ex = getDataArg(argIndex + 1); |