summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMehdi Amini <mehdi.amini@apple.com>2016-10-25 00:48:48 +0000
committerMehdi Amini <mehdi.amini@apple.com>2016-10-25 00:48:48 +0000
commit9825ab04332a6b1b4692385ca86e715eb3f99190 (patch)
treec09bc7bf193475fc1c514a680d86d625d77dc6ba
parent02be0633517502f75361650966841e008903b5c1 (diff)
downloadbcm5719-llvm-9825ab04332a6b1b4692385ca86e715eb3f99190.tar.gz
bcm5719-llvm-9825ab04332a6b1b4692385ca86e715eb3f99190.zip
Fix handling of %% format specifier in os_log builtins.
Returning `false` was stopping the parsing of further arguments, which wasn't intended. llvm-svn: 285047
-rw-r--r--clang/lib/Analysis/OSLog.cpp2
-rw-r--r--clang/test/CodeGen/builtins.c27
2 files changed, 20 insertions, 9 deletions
diff --git a/clang/lib/Analysis/OSLog.cpp b/clang/lib/Analysis/OSLog.cpp
index b57e0d1d13f..04183883990 100644
--- a/clang/lib/Analysis/OSLog.cpp
+++ b/clang/lib/Analysis/OSLog.cpp
@@ -57,7 +57,7 @@ public:
if (!FS.consumesDataArgument() &&
FS.getConversionSpecifier().getKind() !=
clang::analyze_format_string::ConversionSpecifier::PrintErrno)
- return false;
+ return true;
ArgsData.emplace_back();
unsigned ArgIndex = FS.getArgIndex();
diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c
index 77701984756..c604ee54e29 100644
--- a/clang/test/CodeGen/builtins.c
+++ b/clang/test/CodeGen/builtins.c
@@ -490,19 +490,21 @@ void test_builtin_os_log_wide(void *buf, const char *data, wchar_t *str) {
}
// 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
-void test_builtin_os_log_percent(void *buf, const char *data) {
+void test_builtin_os_log_percent(void *buf, const char *data1, const char *data2) {
volatile int len;
// CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8
- // CHECK: store i8* [[DATA]], i8** [[DATA_ADDR:%.*]], align 8
- // CHECK: store volatile i32 12
- len = __builtin_os_log_format_buffer_size("%s %%", data);
+ // CHECK: store i8* [[DATA1]], i8** [[DATA1_ADDR:%.*]], align 8
+ // CHECK: store i8* [[DATA2]], i8** [[DATA2_ADDR:%.*]], align 8
+ // CHECK: store volatile i32 22
+ len = __builtin_os_log_format_buffer_size("%s %% %s", data1, data2);
// 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 1, i8* [[NUM_ARGS]]
+ // CHECK: store i8 2, i8* [[NUM_ARGS]]
//
// CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2
// CHECK: store i8 32, i8* [[ARG1_DESC]]
@@ -510,9 +512,18 @@ void test_builtin_os_log_percent(void *buf, const char *data) {
// CHECK: store i8 8, i8* [[ARG1_SIZE]]
// CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4
// CHECK: [[ARG1_PTR:%.*]] = bitcast i8* [[ARG1]] to i8**
- // CHECK: [[DATA2:%.*]] = load i8*, i8** [[DATA_ADDR]]
- // CHECK: store i8* [[DATA2]], i8** [[ARG1_PTR]]
- __builtin_os_log_format(buf, "%s %%", data);
+ // CHECK: [[DATA1:%.*]] = load i8*, i8** [[DATA1_ADDR]]
+ // CHECK: store i8* [[DATA1]], i8** [[ARG1_PTR]]
+ //
+ // CHECK: [[ARG2_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 12
+ // CHECK: store i8 32, i8* [[ARG2_DESC]]
+ // CHECK: [[ARG2_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 13
+ // CHECK: store i8 8, i8* [[ARG2_SIZE]]
+ // CHECK: [[ARG2:%.*]] = getelementptr i8, i8* [[BUF2]], i64 14
+ // CHECK: [[ARG2_PTR:%.*]] = bitcast i8* [[ARG2]] to i8**
+ // CHECK: [[DATA2:%.*]] = load i8*, i8** [[DATA2_ADDR]]
+ // CHECK: store i8* [[DATA2]], i8** [[ARG2_PTR]]
+ __builtin_os_log_format(buf, "%s %% %s", data1, data2);
}
#endif \ No newline at end of file
OpenPOWER on IntegriCloud