summaryrefslogtreecommitdiffstats
path: root/test/FixIt
diff options
context:
space:
mode:
authorAlexander Shaposhnikov <shal1t712@gmail.com>2017-06-08 21:44:45 +0000
committerAlexander Shaposhnikov <shal1t712@gmail.com>2017-06-08 21:44:45 +0000
commit97a93ed9081459ae5590fc787e4163ae435a5028 (patch)
tree4af9185d616bcf72efd91efa670166dcc754ae10 /test/FixIt
parentc792502570b849026b75eff97f8c6040a6db06b2 (diff)
[clang] Fix format specifiers fixits
This diff fixes printf "fixits" in the case when there is a wrapping macro and the format string needs multiple replacements. In the presence of a macro there is an extra logic in EditedSource.cpp to handle multiple uses of the same macro argument (see the old comment inside EditedSource::canInsertInOffset) which was mistriggerred when the argument was used only once but required multiple adjustments), as a result the "fixit" was breaking down the format string by dropping the second format specifier, i.e. Log1("test 4: %s %s", getNSInteger(), getNSInteger()) was getting replaced with Log1("test 4: %ld ", (long)getNSInteger(), (long)getNSInteger()) (if one removed the macro and used printf directly it would work fine). In this diff we track the location where the macro argument is used and (as it was before) the modifications originating from all the locations except the first one are rejected, but multiple changes are allowed. Test plan: make check-all Differential revision: https://reviews.llvm.org/D33976 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@305018 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/FixIt')
-rw-r--r--test/FixIt/fixit-format-darwin.m59
1 files changed, 59 insertions, 0 deletions
diff --git a/test/FixIt/fixit-format-darwin.m b/test/FixIt/fixit-format-darwin.m
new file mode 100644
index 0000000000..bfc71291a5
--- /dev/null
+++ b/test/FixIt/fixit-format-darwin.m
@@ -0,0 +1,59 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fsyntax-only -fblocks -Wformat -fixit %t
+// RUN: grep -v CHECK %t | FileCheck %s
+
+/* This is a test of code modifications created by darwin format fix-its hints
+ that are provided as part of warning */
+
+int printf(const char * restrict, ...);
+
+#if __LP64__
+typedef long NSInteger;
+typedef unsigned long NSUInteger;
+#else
+typedef int NSInteger;
+typedef unsigned int NSUInteger;
+#endif
+NSInteger getNSInteger();
+NSUInteger getNSUInteger();
+
+#define Log1(...) \
+do { \
+ printf(__VA_ARGS__); \
+} while (0)
+
+#define Log2(...) \
+do { \
+ printf(__VA_ARGS__); \
+ printf(__VA_ARGS__); \
+} while (0) \
+
+#define Log3(X, Y, Z) \
+do { \
+ printf(X, Y); \
+ printf(X, Z); \
+} while (0) \
+
+void test() {
+ printf("test 1: %s", getNSInteger());
+ // CHECK: printf("test 1: %ld", (long)getNSInteger());
+ printf("test 2: %s %s", getNSInteger(), getNSInteger());
+ // CHECK: printf("test 2: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
+
+ Log1("test 3: %s", getNSInteger());
+ // CHECK: Log1("test 3: %ld", (long)getNSInteger());
+ Log1("test 4: %s %s", getNSInteger(), getNSInteger());
+ // CHECK: Log1("test 4: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
+
+ Log2("test 5: %s", getNSInteger());
+ // CHECK: Log2("test 5: %ld", (long)getNSInteger());
+ Log2("test 6: %s %s", getNSInteger(), getNSInteger());
+ // CHECK: Log2("test 6: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
+
+ // Artificial test to check that X (in Log3(X, Y, Z))
+ // is modified only according to the diagnostics
+ // for the first printf and the modification caused
+ // by the second printf is dropped.
+ Log3("test 7: %s", getNSInteger(), getNSUInteger());
+ // CHECK: Log3("test 7: %ld", (long)getNSInteger(), (unsigned long)getNSUInteger());
+}