1 //===-- RPC test to check args to printf ----------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "test/IntegrationTest/test.h"
10
11 #include "src/__support/GPU/utils.h"
12 #include "src/gpu/rpc_fprintf.h"
13 #include "src/stdio/fopen.h"
14
15 using namespace LIBC_NAMESPACE;
16
17 FILE *file = LIBC_NAMESPACE::fopen("testdata/test_data.txt", "w");
18
TEST_MAIN(int argc,char ** argv,char ** envp)19 TEST_MAIN(int argc, char **argv, char **envp) {
20 ASSERT_TRUE(file && "failed to open file");
21 // Check basic printing.
22 int written = 0;
23 written = LIBC_NAMESPACE::rpc_fprintf(file, "A simple string\n", nullptr, 0);
24 ASSERT_EQ(written, 16);
25
26 const char *str = "A simple string\n";
27 written = LIBC_NAMESPACE::rpc_fprintf(file, "%s", &str, sizeof(void *));
28 ASSERT_EQ(written, 16);
29
30 // Check printing a different value with each thread.
31 uint64_t thread_id = gpu::get_thread_id();
32 written = LIBC_NAMESPACE::rpc_fprintf(file, "%8ld\n", &thread_id,
33 sizeof(thread_id));
34 ASSERT_EQ(written, 9);
35
36 struct {
37 uint32_t x = 1;
38 char c = 'c';
39 double f = 1.0;
40 } args1;
41 written =
42 LIBC_NAMESPACE::rpc_fprintf(file, "%d%c%.1f\n", &args1, sizeof(args1));
43 ASSERT_EQ(written, 6);
44
45 struct {
46 uint32_t x = 1;
47 const char *str = "A simple string\n";
48 } args2;
49 written =
50 LIBC_NAMESPACE::rpc_fprintf(file, "%032b%s\n", &args2, sizeof(args2));
51 ASSERT_EQ(written, 49);
52
53 // Check that the server correctly handles divergent numbers of arguments.
54 const char *format = gpu::get_thread_id() % 2 ? "%s" : "%20ld\n";
55 written = LIBC_NAMESPACE::rpc_fprintf(file, format, &str, sizeof(void *));
56 ASSERT_EQ(written, gpu::get_thread_id() % 2 ? 16 : 21);
57
58 format = gpu::get_thread_id() % 2 ? "%s" : str;
59 written = LIBC_NAMESPACE::rpc_fprintf(file, format, &str, sizeof(void *));
60 ASSERT_EQ(written, 16);
61
62 // Check that we handle null arguments correctly.
63 struct {
64 void *null = nullptr;
65 } args3;
66 written = LIBC_NAMESPACE::rpc_fprintf(file, "%p", &args3, sizeof(args3));
67 ASSERT_EQ(written, 9);
68
69 #ifndef LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
70 written = LIBC_NAMESPACE::rpc_fprintf(file, "%s", &args3, sizeof(args3));
71 ASSERT_EQ(written, 6);
72 #endif // LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
73
74 // Check for extremely abused variable width arguments
75 struct {
76 uint32_t x = 1;
77 uint32_t y = 2;
78 double f = 1.0;
79 } args4;
80 written = LIBC_NAMESPACE::rpc_fprintf(file, "%**d", &args4, sizeof(args4));
81 ASSERT_EQ(written, 4);
82 written = LIBC_NAMESPACE::rpc_fprintf(file, "%**d%6d", &args4, sizeof(args4));
83 ASSERT_EQ(written, 10);
84 written = LIBC_NAMESPACE::rpc_fprintf(file, "%**.**f", &args4, sizeof(args4));
85 ASSERT_EQ(written, 7);
86
87 return 0;
88 }
89