1603c4be006d8c53905d736bf1f19a49f5ce98276Alexey Samsonov//===-- tsan_printf_test.cc -----------------------------------------------===//
2da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//
3da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//                     The LLVM Compiler Infrastructure
4da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//
5da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// This file is distributed under the University of Illinois Open Source
6da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// License. See LICENSE.TXT for details.
7da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//
8da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//===----------------------------------------------------------------------===//
9da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//
10da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// This file is a part of ThreadSanitizer (TSan), a race detector.
11da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//
12da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//===----------------------------------------------------------------------===//
13da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include "tsan_rtl.h"
14da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include "gtest/gtest.h"
15da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
16da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include <string.h>
17da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include <limits.h>
18da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
19da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanynamespace __tsan {
20da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
21da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Printf, Basic) {
22da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char buf[1024];
23de08c02aa3007a590bfb7d43f31d5b1a0e7d337cAlexey Samsonov  uptr len = internal_snprintf(buf, sizeof(buf),
24e954101f6602ac181a2c3accfbbad0ae51b0bf7cAlexey Samsonov      "a%db%zdc%ue%zuf%xh%zxq%pe%sr",
25e954101f6602ac181a2c3accfbbad0ae51b0bf7cAlexey Samsonov      (int)-1, (long)-2, // NOLINT
26e954101f6602ac181a2c3accfbbad0ae51b0bf7cAlexey Samsonov      (unsigned)-4, (unsigned long)5, // NOLINT
27e954101f6602ac181a2c3accfbbad0ae51b0bf7cAlexey Samsonov      (unsigned)10, (unsigned long)11, // NOLINT
28da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany      (void*)0x123, "_string_");
29da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(len, strlen(buf));
30e954101f6602ac181a2c3accfbbad0ae51b0bf7cAlexey Samsonov  EXPECT_EQ(0, strcmp(buf, "a-1b-2c4294967292e5fahbq"
31da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany                           "0x000000000123e_string_r"));
32da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
33da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
34da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Printf, OverflowStr) {
35da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char buf[] = "123456789";
36de08c02aa3007a590bfb7d43f31d5b1a0e7d337cAlexey Samsonov  uptr len = internal_snprintf(buf, 4, "%s", "abcdef");  // NOLINT
37da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(len, (uptr)6);
38da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(0, strcmp(buf, "abc"));
39da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[3], 0);
40da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[4], '5');
41da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[5], '6');
42da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[6], '7');
43da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[7], '8');
44da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[8], '9');
45da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[9], 0);
46da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
47da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
48da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Printf, OverflowInt) {
49da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char buf[] = "123456789";
50de08c02aa3007a590bfb7d43f31d5b1a0e7d337cAlexey Samsonov  internal_snprintf(buf, 4, "%d", -123456789);  // NOLINT
51da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(0, strcmp(buf, "-12"));
52da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[3], 0);
53da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[4], '5');
54da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[5], '6');
55da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[6], '7');
56da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[7], '8');
57da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[8], '9');
58da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[9], 0);
59da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
60da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
61da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Printf, OverflowUint) {
62da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char buf[] = "123456789";
63de08c02aa3007a590bfb7d43f31d5b1a0e7d337cAlexey Samsonov  internal_snprintf(buf, 4, "a%zx", (unsigned long)0x123456789);  // NOLINT
64da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(0, strcmp(buf, "a12"));
65da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[3], 0);
66da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[4], '5');
67da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[5], '6');
68da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[6], '7');
69da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[7], '8');
70da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[8], '9');
71da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[9], 0);
72da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
73da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
74da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Printf, OverflowPtr) {
75da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char buf[] = "123456789";
76de08c02aa3007a590bfb7d43f31d5b1a0e7d337cAlexey Samsonov  internal_snprintf(buf, 4, "%p", (void*)0x123456789);  // NOLINT
77da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(0, strcmp(buf, "0x0"));
78da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[3], 0);
79da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[4], '5');
80da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[5], '6');
81da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[6], '7');
82da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[7], '8');
83da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[8], '9');
84da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[9], 0);
85da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
86da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
87da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanytemplate<typename T>
88da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanystatic void TestMinMax(const char *fmt, T min, T max) {
89da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char buf[1024];
90de08c02aa3007a590bfb7d43f31d5b1a0e7d337cAlexey Samsonov  uptr len = internal_snprintf(buf, sizeof(buf), fmt, min, max);
91da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char buf2[1024];
92da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  snprintf(buf2, sizeof(buf2), fmt, min, max);
93da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(len, strlen(buf));
94da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(0, strcmp(buf, buf2));
95da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
96da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
97da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Printf, MinMax) {
98da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  TestMinMax<int>("%d-%d", INT_MIN, INT_MAX);  // NOLINT
99e954101f6602ac181a2c3accfbbad0ae51b0bf7cAlexey Samsonov  TestMinMax<long>("%zd-%zd", LONG_MIN, LONG_MAX);  // NOLINT
100da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  TestMinMax<unsigned>("%u-%u", 0, UINT_MAX);  // NOLINT
101e954101f6602ac181a2c3accfbbad0ae51b0bf7cAlexey Samsonov  TestMinMax<unsigned long>("%zu-%zu", 0, ULONG_MAX);  // NOLINT
102da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  TestMinMax<unsigned>("%x-%x", 0, UINT_MAX);  // NOLINT
103e954101f6602ac181a2c3accfbbad0ae51b0bf7cAlexey Samsonov  TestMinMax<unsigned long>("%zx-%zx", 0, ULONG_MAX);  // NOLINT
104da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
105da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
106da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}  // namespace __tsan
107