xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/cert/err34-c.c (revision 89a1d03e2b379e325daa5249411e414bbd995b5e)
1*89a1d03eSRichard // RUN: %check_clang_tidy %s cert-err34-c %t -- -- -std=c11
2*89a1d03eSRichard 
3*89a1d03eSRichard typedef __SIZE_TYPE__      size_t;
4*89a1d03eSRichard typedef signed             ptrdiff_t;
5*89a1d03eSRichard typedef long long          intmax_t;
6*89a1d03eSRichard typedef unsigned long long uintmax_t;
7*89a1d03eSRichard typedef void *             FILE;
8*89a1d03eSRichard 
9*89a1d03eSRichard extern FILE *stdin;
10*89a1d03eSRichard 
11*89a1d03eSRichard extern int fscanf(FILE * restrict stream, const char * restrict format, ...);
12*89a1d03eSRichard extern int scanf(const char * restrict format, ...);
13*89a1d03eSRichard extern int sscanf(const char * restrict s, const char * restrict format, ...);
14*89a1d03eSRichard 
15*89a1d03eSRichard extern double atof(const char *nptr);
16*89a1d03eSRichard extern int atoi(const char *nptr);
17*89a1d03eSRichard extern long int atol(const char *nptr);
18*89a1d03eSRichard extern long long int atoll(const char *nptr);
19*89a1d03eSRichard 
f1(const char * in)20*89a1d03eSRichard void f1(const char *in) {
21*89a1d03eSRichard   int i;
22*89a1d03eSRichard   long long ll;
23*89a1d03eSRichard   unsigned int ui;
24*89a1d03eSRichard   unsigned long long ull;
25*89a1d03eSRichard   intmax_t im;
26*89a1d03eSRichard   uintmax_t uim;
27*89a1d03eSRichard   float f;
28*89a1d03eSRichard   double d;
29*89a1d03eSRichard   long double ld;
30*89a1d03eSRichard 
31*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
32*89a1d03eSRichard   sscanf(in, "%d", &i);
33*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead [cert-err34-c]
34*89a1d03eSRichard   fscanf(stdin, "%lld", &ll);
35*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoul' instead [cert-err34-c]
36*89a1d03eSRichard   sscanf(in, "%u", &ui);
37*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoull' instead [cert-err34-c]
38*89a1d03eSRichard   fscanf(stdin, "%llu", &ull);
39*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoimax' instead [cert-err34-c]
40*89a1d03eSRichard   scanf("%jd", &im);
41*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoumax' instead [cert-err34-c]
42*89a1d03eSRichard   fscanf(stdin, "%ju", &uim);
43*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtof' instead [cert-err34-c]
44*89a1d03eSRichard   sscanf(in, "%f", &f); // to float
45*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtod' instead [cert-err34-c]
46*89a1d03eSRichard   fscanf(stdin, "%lg", &d);
47*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtold' instead [cert-err34-c]
48*89a1d03eSRichard   sscanf(in, "%Le", &ld);
49*89a1d03eSRichard 
50*89a1d03eSRichard   // These are conversions with other modifiers
51*89a1d03eSRichard   short s;
52*89a1d03eSRichard   char c;
53*89a1d03eSRichard   size_t st;
54*89a1d03eSRichard   ptrdiff_t pt;
55*89a1d03eSRichard 
56*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
57*89a1d03eSRichard   scanf("%hhd", &c);
58*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
59*89a1d03eSRichard   scanf("%hd", &s);
60*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
61*89a1d03eSRichard   scanf("%zu", &st);
62*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
63*89a1d03eSRichard   scanf("%td", &pt);
64*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
65*89a1d03eSRichard   scanf("%o", ui);
66*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
67*89a1d03eSRichard   scanf("%X", ui);
68*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
69*89a1d03eSRichard   scanf("%x", ui);
70*89a1d03eSRichard }
71*89a1d03eSRichard 
f2(const char * in)72*89a1d03eSRichard void f2(const char *in) {
73*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:11: warning: 'atoi' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
74*89a1d03eSRichard   int i = atoi(in); // to int
75*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:12: warning: 'atol' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
76*89a1d03eSRichard   long l = atol(in); // to long
77*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:18: warning: 'atoll' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead [cert-err34-c]
78*89a1d03eSRichard   long long ll = atoll(in); // to long long
79*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:14: warning: 'atof' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtod' instead [cert-err34-c]
80*89a1d03eSRichard   double d = atof(in); // to double
81*89a1d03eSRichard }
82*89a1d03eSRichard 
f3(void)83*89a1d03eSRichard void f3(void) {
84*89a1d03eSRichard   int i;
85*89a1d03eSRichard   unsigned int u;
86*89a1d03eSRichard   float f;
87*89a1d03eSRichard   char str[32];
88*89a1d03eSRichard 
89*89a1d03eSRichard   // Test that we don't report multiple infractions for a single call.
90*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
91*89a1d03eSRichard   scanf("%d%u%f", &i, &u, &f);
92*89a1d03eSRichard 
93*89a1d03eSRichard   // Test that we still catch infractions that are not the first specifier.
94*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
95*89a1d03eSRichard   scanf("%s%d", str, &i);
96*89a1d03eSRichard }
97*89a1d03eSRichard 
do_not_diagnose(void)98*89a1d03eSRichard void do_not_diagnose(void) {
99*89a1d03eSRichard   char str[32];
100*89a1d03eSRichard 
101*89a1d03eSRichard   scanf("%s", str); // Not a numerical conversion
102*89a1d03eSRichard   scanf("%*d"); // Assignment suppressed
103*89a1d03eSRichard }
104