r289761 - Fix os_log formating with arbitrary precision and field width

Mehdi Amini via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 14 20:02:31 PST 2016


Author: mehdi_amini
Date: Wed Dec 14 22:02:31 2016
New Revision: 289761

URL: http://llvm.org/viewvc/llvm-project?rev=289761&view=rev
Log:
Fix os_log formating with arbitrary precision and field width

Modified:
    cfe/trunk/lib/Analysis/OSLog.cpp
    cfe/trunk/test/CodeGen/builtins.c

Modified: cfe/trunk/lib/Analysis/OSLog.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/OSLog.cpp?rev=289761&r1=289760&r2=289761&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/OSLog.cpp (original)
+++ cfe/trunk/lib/Analysis/OSLog.cpp Wed Dec 14 22:02:31 2016
@@ -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);

Modified: cfe/trunk/test/CodeGen/builtins.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtins.c?rev=289761&r1=289760&r2=289761&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/builtins.c (original)
+++ cfe/trunk/test/CodeGen/builtins.c Wed Dec 14 22:02:31 2016
@@ -489,6 +489,55 @@ void test_builtin_os_log_wide(void *buf,
   __builtin_os_log_format(buf, "%S", str);
 }
 
+// CHECK-LABEL: define void @test_builtin_os_log_precision_width
+// CHECK: (i8* [[BUF:%.*]], i8* [[DATA:%.*]], i32 [[PRECISION:%.*]], i32 [[WIDTH:%.*]])
+void test_builtin_os_log_precision_width(void *buf, const char *data,
+                                         int precision, int width) {
+  volatile int len;
+  // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8
+  // CHECK: store i8* [[DATA]], i8** [[DATA_ADDR:%.*]], align 8
+  // CHECK: store i32 [[PRECISION]], i32* [[PRECISION_ADDR:%.*]], align 4
+  // CHECK: store i32 [[WIDTH]], i32* [[WIDTH_ADDR:%.*]], align 4
+
+  // CHECK: store volatile i32 24,
+  len = __builtin_os_log_format_buffer_size("Hello %*.*s World", precision, width, data);
+
+  // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]]
+  // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0
+  // CHECK: store i8 2, i8* [[SUMMARY]]
+  // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1
+  // CHECK: store i8 3, i8* [[NUM_ARGS]]
+
+  // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2
+  // CHECK: store i8 0, i8* [[ARG1_DESC]]
+  // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3
+  // CHECK: store i8 4, i8* [[ARG1_SIZE]]
+  // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4
+  // CHECK: [[ARG1_INT:%.*]] = bitcast i8* [[ARG1]] to i32*
+  // CHECK: [[ARG1_VAL:%.*]] = load i32, i32* [[PRECISION_ADDR]]
+  // CHECK: store i32 [[ARG1_VAL]], i32* [[ARG1_INT]]
+
+  // CHECK: [[ARG2_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 8
+  // CHECK: store i8 16, i8* [[ARG2_DESC]]
+  // CHECK: [[ARG2_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 9
+  // CHECK: store i8 4, i8* [[ARG2_SIZE]]
+  // CHECK: [[ARG2:%.*]] = getelementptr i8, i8* [[BUF2]], i64 10
+  // CHECK: [[ARG2_INT:%.*]] = bitcast i8* [[ARG2]] to i32*
+  // CHECK: [[ARG2_VAL:%.*]] = load i32, i32* [[WIDTH_ADDR]]
+  // CHECK: store i32 [[ARG2_VAL]], i32* [[ARG2_INT]]
+
+  // CHECK: [[ARG3_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 14
+  // CHECK: store i8 32, i8* [[ARG3_DESC]]
+  // CHECK: [[ARG3_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 15
+  // CHECK: store i8 8, i8* [[ARG3_SIZE]]
+  // CHECK: [[ARG3:%.*]] = getelementptr i8, i8* [[BUF2]], i64 16
+  // CHECK: [[ARG3_PTR:%.*]] = bitcast i8* [[ARG3]] to i8**
+  // CHECK: [[DATA2:%.*]] = load i8*, i8** [[DATA_ADDR]]
+  // CHECK: store i8* [[DATA2]], i8** [[ARG3_PTR]]
+
+  __builtin_os_log_format(buf, "Hello %*.*s World", precision, width, data);
+}
+
 // CHECK-LABEL: define void @test_builtin_os_log_percent
 // CHECK: (i8* [[BUF:%.*]], i8* [[DATA1:%.*]], i8* [[DATA2:%.*]])
 // Check that the %% which does not consume any argument is correctly handled




More information about the cfe-commits mailing list