summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis
diff options
context:
space:
mode:
authorMehdi Amini <mehdi.amini@apple.com>2016-12-15 04:02:31 +0000
committerMehdi Amini <mehdi.amini@apple.com>2016-12-15 04:02:31 +0000
commitab11d83048d0467e39bd5ef2b6f43f6f1686c45e (patch)
treeb6387344c9ec148e29d47eb4fe5e05104e51306b /clang/lib/Analysis
parent6ee0b4e9f543fa108b47d3ae7c030d835cacd2c1 (diff)
downloadbcm5719-llvm-ab11d83048d0467e39bd5ef2b6f43f6f1686c45e.tar.gz
bcm5719-llvm-ab11d83048d0467e39bd5ef2b6f43f6f1686c45e.zip
Fix os_log formating with arbitrary precision and field width
llvm-svn: 289761
Diffstat (limited to 'clang/lib/Analysis')
-rw-r--r--clang/lib/Analysis/OSLog.cpp29
1 files changed, 27 insertions, 2 deletions
diff --git a/clang/lib/Analysis/OSLog.cpp b/clang/lib/Analysis/OSLog.cpp
index 04183883990..3e13a153c65 100644
--- a/clang/lib/Analysis/OSLog.cpp
+++ b/clang/lib/Analysis/OSLog.cpp
@@ -22,6 +22,9 @@ private:
const Expr *E = nullptr;
Optional<OSLogBufferItem::Kind> Kind;
Optional<unsigned> Size;
+ Optional<const Expr *> Count;
+ Optional<const Expr *> Precision;
+ Optional<const Expr *> FieldWidth;
unsigned char Flags = 0;
};
SmallVector<ArgData, 4> ArgsData;
@@ -84,7 +87,7 @@ public:
ArgsData.back().Size = precision.getConstantAmount();
break;
case clang::analyze_format_string::OptionalAmount::Arg: // "%.*s"
- ArgsData.back().Kind = OSLogBufferItem::CountKind;
+ ArgsData.back().Count = Args[precision.getArgIndex()];
break;
case clang::analyze_format_string::OptionalAmount::Invalid:
return false;
@@ -100,7 +103,7 @@ public:
ArgsData.back().Size = precision.getConstantAmount();
break;
case clang::analyze_format_string::OptionalAmount::Arg: // "%.*P"
- ArgsData.back().Kind = OSLogBufferItem::CountKind;
+ ArgsData.back().Count = Args[precision.getArgIndex()];
break;
case clang::analyze_format_string::OptionalAmount::Invalid:
return false;
@@ -108,8 +111,14 @@ public:
break;
}
default:
+ if (FS.getPrecision().hasDataArgument()) {
+ ArgsData.back().Precision = Args[FS.getPrecision().getArgIndex()];
+ }
break;
}
+ if (FS.getFieldWidth().hasDataArgument()) {
+ ArgsData.back().FieldWidth = Args[FS.getFieldWidth().getArgIndex()];
+ }
if (FS.isPrivate()) {
ArgsData.back().Flags |= OSLogBufferItem::IsPrivate;
@@ -123,6 +132,22 @@ public:
void computeLayout(ASTContext &Ctx, OSLogBufferLayout &Layout) const {
Layout.Items.clear();
for (auto &Data : ArgsData) {
+ if (Data.FieldWidth) {
+ CharUnits Size = Ctx.getTypeSizeInChars((*Data.FieldWidth)->getType());
+ Layout.Items.emplace_back(OSLogBufferItem::ScalarKind, *Data.FieldWidth,
+ Size, 0);
+ }
+ if (Data.Precision) {
+ CharUnits Size = Ctx.getTypeSizeInChars((*Data.Precision)->getType());
+ Layout.Items.emplace_back(OSLogBufferItem::ScalarKind, *Data.Precision,
+ Size, 0);
+ }
+ if (Data.Count) {
+ // "%.*P" has an extra "count" that we insert before the argument.
+ CharUnits Size = Ctx.getTypeSizeInChars((*Data.Count)->getType());
+ Layout.Items.emplace_back(OSLogBufferItem::CountKind, *Data.Count, Size,
+ 0);
+ }
if (Data.Size)
Layout.Items.emplace_back(Ctx, CharUnits::fromQuantity(*Data.Size),
Data.Flags);
OpenPOWER on IntegriCloud