summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorclaudio <claudio@openbsd.org>2018-12-29 09:11:32 +0000
committerclaudio <claudio@openbsd.org>2018-12-29 09:11:32 +0000
commita2d20eaa3f8ec62a5e571b8687dde7995fcb1014 (patch)
treec820fe77bbb340e3063cf26ff49000bc6677a54e
parentmove kroute_find() call later (diff)
downloadwireguard-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.h6
-rw-r--r--gnu/llvm/tools/clang/lib/Analysis/FormatString.cpp9
-rw-r--r--gnu/llvm/tools/clang/lib/Sema/SemaChecking.cpp36
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);