Skip to content

Commit a49030e

Browse files
authored
[clang-tidy] Teach readability-uppercase-literal-suffix about C++23 and C23 suffixes (#148275)
Clang doesn't actually support any of the new floating point types yet (except for `f16`). I've decided to add disabled tests for them, so that when the support comes, we can flip the switch and support them with no delay.
1 parent 5109361 commit a49030e

13 files changed

+414
-252
lines changed

clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ struct IntegerLiteralCheck {
2525
static constexpr llvm::StringLiteral Name = llvm::StringLiteral("integer");
2626
// What should be skipped before looking for the Suffixes? (Nothing here.)
2727
static constexpr llvm::StringLiteral SkipFirst = llvm::StringLiteral("");
28-
// Suffix can only consist of 'u' and 'l' chars, and can be a complex number
29-
// ('i', 'j'). In MS compatibility mode, suffixes like i32 are supported.
28+
// Suffix can only consist of 'u', 'l', and 'z' chars, can be a bit-precise
29+
// integer (wb), and can be a complex number ('i', 'j'). In MS compatibility
30+
// mode, suffixes like i32 are supported.
3031
static constexpr llvm::StringLiteral Suffixes =
31-
llvm::StringLiteral("uUlLiIjJ");
32+
llvm::StringLiteral("uUlLzZwWbBiIjJ");
3233
};
3334

3435
struct FloatingLiteralCheck {
@@ -42,10 +43,10 @@ struct FloatingLiteralCheck {
4243
// Since the exponent ('p'/'P') is mandatory for hexadecimal floating-point
4344
// literals, we first skip everything before the exponent.
4445
static constexpr llvm::StringLiteral SkipFirst = llvm::StringLiteral("pP");
45-
// Suffix can only consist of 'f', 'l', "f16", 'h', 'q' chars,
46-
// and can be a complex number ('i', 'j').
46+
// Suffix can only consist of 'f', 'l', "f16", "bf16", "df", "dd", "dl",
47+
// 'h', 'q' chars, and can be a complex number ('i', 'j').
4748
static constexpr llvm::StringLiteral Suffixes =
48-
llvm::StringLiteral("fFlLhHqQiIjJ");
49+
llvm::StringLiteral("fFlLbBdDhHqQiIjJ");
4950
};
5051

5152
struct NewSuffix {

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,10 @@ Changes in existing checks
245245
<clang-tidy/checks/readability/qualified-auto>` check by adding the option
246246
`IgnoreAliasing`, that allows not looking at underlying types of type aliases.
247247

248+
- Improved :doc:`readability-uppercase-literal-suffix
249+
<clang-tidy/checks/readability/uppercase-literal-suffix>` check to recognize
250+
literal suffixes added in C++23 and C23.
251+
248252
Removed checks
249253
^^^^^^^^^^^^^^
250254

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//===--- stdfloat - Stub header for tests -----------------------*- C++ -*-===//
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+
#ifndef _STDFLOAT_
10+
#define _STDFLOAT_
11+
12+
namespace std {
13+
14+
// TODO: define std::float16_t and friends
15+
16+
}
17+
18+
#endif // _STDFLOAT_

clang-tools-extra/test/clang-tidy/checkers/cert/uppercase-literal-suffix-integer.cpp

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
// RUN: %check_clang_tidy %s cert-dcl16-c %t -- -- -I %clang_tidy_headers
2-
// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
3-
// RUN: clang-tidy %t.cpp -checks='-*,cert-dcl16-c' -fix -- -I %clang_tidy_headers
4-
// RUN: clang-tidy %t.cpp -checks='-*,cert-dcl16-c' -warnings-as-errors='-*,cert-dcl16-c' -- -I %clang_tidy_headers
52

63
#include "integral_constant.h"
74

85
void integer_suffix() {
96
static constexpr auto v0 = __LINE__; // synthetic
10-
static_assert(v0 == 9 || v0 == 5, "");
11-
127
static constexpr auto v1 = __cplusplus; // synthetic, long
138

149
static constexpr auto v2 = 1; // no literal
@@ -29,9 +24,6 @@ void integer_suffix() {
2924

3025
static constexpr auto v5 = 1l;
3126
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'l', which is not uppercase
32-
// CHECK-MESSAGES-NEXT: static constexpr auto v5 = 1l;
33-
// CHECK-MESSAGES-NEXT: ^~
34-
// CHECK-MESSAGES-NEXT: {{^ *| *}}L{{$}}
3527
// CHECK-FIXES: static constexpr auto v5 = 1L;
3628
static_assert(is_same<decltype(v5), const long>::value, "");
3729
static_assert(v5 == 1, "");
@@ -44,9 +36,6 @@ void integer_suffix() {
4436

4537
static constexpr auto v7 = 1ll;
4638
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'll', which is not uppercase
47-
// CHECK-MESSAGES-NEXT: static constexpr auto v7 = 1ll;
48-
// CHECK-MESSAGES-NEXT: ^~~
49-
// CHECK-MESSAGES-NEXT: {{^ *| *}}LL{{$}}
5039
// CHECK-FIXES: static constexpr auto v7 = 1LL;
5140
static_assert(is_same<decltype(v7), const long long>::value, "");
5241
static_assert(v7 == 1, "");
@@ -77,27 +66,18 @@ void integer_suffix() {
7766

7867
static constexpr auto v13 = 1lu;
7968
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'lu', which is not uppercase
80-
// CHECK-MESSAGES-NEXT: static constexpr auto v13 = 1lu;
81-
// CHECK-MESSAGES-NEXT: ^~~
82-
// CHECK-MESSAGES-NEXT: {{^ *| *}}LU{{$}}
8369
// CHECK-FIXES: static constexpr auto v13 = 1LU;
8470
static_assert(is_same<decltype(v13), const unsigned long>::value, "");
8571
static_assert(v13 == 1, "");
8672

8773
static constexpr auto v14 = 1Lu;
8874
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'Lu', which is not uppercase
89-
// CHECK-MESSAGES-NEXT: static constexpr auto v14 = 1Lu;
90-
// CHECK-MESSAGES-NEXT: ^~~
91-
// CHECK-MESSAGES-NEXT: {{^ *| *}}LU{{$}}
9275
// CHECK-FIXES: static constexpr auto v14 = 1LU;
9376
static_assert(is_same<decltype(v14), const unsigned long>::value, "");
9477
static_assert(v14 == 1, "");
9578

9679
static constexpr auto v15 = 1lU;
9780
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'lU', which is not uppercase
98-
// CHECK-MESSAGES-NEXT: static constexpr auto v15 = 1lU;
99-
// CHECK-MESSAGES-NEXT: ^~~
100-
// CHECK-MESSAGES-NEXT: {{^ *| *}}LU{{$}}
10181
// CHECK-FIXES: static constexpr auto v15 = 1LU;
10282
static_assert(is_same<decltype(v15), const unsigned long>::value, "");
10383
static_assert(v15 == 1, "");
@@ -128,27 +108,18 @@ void integer_suffix() {
128108

129109
static constexpr auto v21 = 1llu;
130110
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'llu', which is not uppercase
131-
// CHECK-MESSAGES-NEXT: static constexpr auto v21 = 1llu;
132-
// CHECK-MESSAGES-NEXT: ^~~~
133-
// CHECK-MESSAGES-NEXT: {{^ *| *}}LLU{{$}}
134111
// CHECK-FIXES: static constexpr auto v21 = 1LLU;
135112
static_assert(is_same<decltype(v21), const unsigned long long>::value, "");
136113
static_assert(v21 == 1, "");
137114

138115
static constexpr auto v22 = 1LLu;
139116
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'LLu', which is not uppercase
140-
// CHECK-MESSAGES-NEXT: static constexpr auto v22 = 1LLu;
141-
// CHECK-MESSAGES-NEXT: ^~~~
142-
// CHECK-MESSAGES-NEXT: {{^ *| *}}LLU{{$}}
143117
// CHECK-FIXES: static constexpr auto v22 = 1LLU;
144118
static_assert(is_same<decltype(v22), const unsigned long long>::value, "");
145119
static_assert(v22 == 1, "");
146120

147121
static constexpr auto v23 = 1llU;
148122
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'llU', which is not uppercase
149-
// CHECK-MESSAGES-NEXT: static constexpr auto v23 = 1llU;
150-
// CHECK-MESSAGES-NEXT: ^~~~
151-
// CHECK-MESSAGES-NEXT: {{^ *| *}}LLU{{$}}
152123
// CHECK-FIXES: static constexpr auto v23 = 1LLU;
153124
static_assert(is_same<decltype(v23), const unsigned long long>::value, "");
154125
static_assert(v23 == 1, "");
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
// TODO: When Clang adds support for decimal floating point types, enable these tests by:
2+
// 1. Removing all the #if 0 + #endif guards.
3+
// 2. Removing all occurrences of the string "DISABLED-" in this file.
4+
// 3. Deleting this message.
5+
6+
// RUN: %check_clang_tidy -std=c23-or-later %s readability-uppercase-literal-suffix %t
7+
8+
void bit_precise_literal_suffix() {
9+
// _BitInt()
10+
11+
static constexpr auto v1 = 1wb;
12+
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'wb', which is not uppercase
13+
// CHECK-FIXES: static constexpr auto v1 = 1WB;
14+
static_assert(v1 == 1WB);
15+
16+
static constexpr auto v2 = 1WB; // OK.
17+
static_assert(v2 == 1WB);
18+
19+
// _BitInt() Unsigned
20+
21+
static constexpr auto v3 = 1wbu;
22+
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'wbu', which is not uppercase
23+
// CHECK-FIXES: static constexpr auto v3 = 1WBU;
24+
static_assert(v3 == 1WBU);
25+
26+
static constexpr auto v4 = 1WBu;
27+
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'WBu', which is not uppercase
28+
// CHECK-FIXES: static constexpr auto v4 = 1WBU;
29+
static_assert(v4 == 1WBU);
30+
31+
static constexpr auto v5 = 1wbU;
32+
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'wbU', which is not uppercase
33+
// CHECK-FIXES: static constexpr auto v5 = 1WBU;
34+
static_assert(v5 == 1WBU);
35+
36+
static constexpr auto v6 = 1WBU; // OK.
37+
static_assert(v6 == 1WBU);
38+
39+
// Unsigned _BitInt()
40+
41+
static constexpr auto v7 = 1uwb;
42+
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'uwb', which is not uppercase
43+
// CHECK-FIXES: static constexpr auto v7 = 1UWB;
44+
static_assert(v7 == 1UWB);
45+
46+
static constexpr auto v8 = 1uWB;
47+
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'uWB', which is not uppercase
48+
// CHECK-FIXES: static constexpr auto v8 = 1UWB;
49+
static_assert(v8 == 1UWB);
50+
51+
static constexpr auto v9 = 1Uwb;
52+
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'Uwb', which is not uppercase
53+
// CHECK-FIXES: static constexpr auto v9 = 1UWB;
54+
static_assert(v9 == 1UWB);
55+
56+
static constexpr auto v10 = 1UWB; // OK.
57+
static_assert(v10 == 1UWB);
58+
}
59+
60+
void decimal_floating_point_suffix() {
61+
// _Decimal32
62+
63+
#if 0
64+
static constexpr auto v1 = 1.df;
65+
// DISABLED-CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'df', which is not uppercase
66+
// DISABLED-CHECK-FIXES: static constexpr auto v1 = 1.DF;
67+
static_assert(v1 == 1.DF);
68+
69+
static constexpr auto v2 = 1.e0df;
70+
// DISABLED-CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'df', which is not uppercase
71+
// DISABLED-CHECK-FIXES: static constexpr auto v2 = 1.e0DF;
72+
static_assert(v2 == 1.DF);
73+
74+
static constexpr auto v3 = 1.DF; // OK.
75+
static_assert(v3 == 1.DF);
76+
77+
static constexpr auto v4 = 1.e0DF; // OK.
78+
static_assert(v4 == 1.DF);
79+
#endif
80+
81+
// _Decimal64
82+
83+
#if 0
84+
static constexpr auto v5 = 1.dd;
85+
// DISABLED-CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'dd', which is not uppercase
86+
// DISABLED-CHECK-FIXES: static constexpr auto v5 = 1.DD;
87+
static_assert(v5 == 1.DD);
88+
89+
static constexpr auto v6 = 1.e0dd;
90+
// DISABLED-CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'dd', which is not uppercase
91+
// DISABLED-CHECK-FIXES: static constexpr auto v6 = 1.e0DD;
92+
static_assert(v6 == 1.DD);
93+
94+
static constexpr auto v7 = 1.DD; // OK.
95+
static_assert(v7 == 1.DD);
96+
97+
static constexpr auto v8 = 1.e0DD; // OK.
98+
static_assert(v8 == 1.DD);
99+
#endif
100+
101+
// _Decimal128
102+
103+
#if 0
104+
static constexpr auto v9 = 1.dl;
105+
// DISABLED-CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'dl', which is not uppercase
106+
// DISABLED-CHECK-FIXES: static constexpr auto v9 = 1.DL;
107+
static_assert(v9 == 1.DL);
108+
109+
static constexpr auto v10 = 1.e0dl;
110+
// DISABLED-CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'dl', which is not uppercase
111+
// DISABLED-CHECK-FIXES: static constexpr auto v10 = 1.e0DL;
112+
static_assert(v10 == 1.DL);
113+
114+
static constexpr auto v11 = 1.DL; // OK.
115+
static_assert(v11 == 1.DL);
116+
117+
static constexpr auto v12 = 1.e0DL; // OK.
118+
static_assert(v12 == 1.DL);
119+
#endif
120+
}

0 commit comments

Comments
 (0)