Skip to content

Commit c8554e1

Browse files
erichkeaneEndilll
andauthored
Turn -Wdeprecated-literal-operator on by default (#111027)
It would be nice to see what our users think about this change, as this is something that WG21/EWG quite wants to fix a handful of questionable issues with UB. Depending on the outcome of this after being committed, we might instead suggest EWG undeprecate this, and require a bit of 'magic' from the lexer. Additionally, this patch makes it so we emit this diagnostic ALSO in cases where the literal name is reserved. It doesn't make sense to limit that. --------- Co-authored-by: Vlad Serebrennikov <[email protected]>
1 parent 870d37d commit c8554e1

32 files changed

+236
-197
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,20 @@ C++ Specific Potentially Breaking Changes
9999
// Was error, now evaluates to false.
100100
constexpr bool b = f() == g();
101101
102+
- The warning ``-Wdeprecated-literal-operator`` is now on by default, as this is
103+
something that WG21 has shown interest in removing from the language. The
104+
result is that anyone who is compiling with ``-Werror`` should see this
105+
diagnostic. To fix this diagnostic, simply removing the space character from
106+
between the ``operator""`` and the user defined literal name will make the
107+
source no longer deprecated. This is consistent with `CWG2521 <https://cplusplus.github.io/CWG/issues/2521.html>_`.
108+
109+
.. code-block:: c++
110+
111+
// Now diagnoses by default.
112+
unsigned operator"" _udl_name(unsigned long long);
113+
// Fixed version:
114+
unsigned operator""_udl_name(unsigned long long);
115+
102116
ABI Changes in This Version
103117
---------------------------
104118

@@ -215,6 +229,10 @@ Resolutions to C++ Defect Reports
215229
- Clang now allows trailing requires clause on explicit deduction guides.
216230
(`CWG2707: Deduction guides cannot have a trailing requires-clause <https://cplusplus.github.io/CWG/issues/2707.html>`_).
217231

232+
- Clang now diagnoses a space in the first production of a ``literal-operator-id``
233+
by default.
234+
(`CWG2521: User-defined literals and reserved identifiers <https://cplusplus.github.io/CWG/issues/2521.html>`_).
235+
218236
C Language Changes
219237
------------------
220238

@@ -378,6 +396,10 @@ Improvements to Clang's diagnostics
378396
- The warning for an unsupported type for a named register variable is now phrased ``unsupported type for named register variable``,
379397
instead of ``bad type for named register variable``. This makes it clear that the type is not supported at all, rather than being
380398
suboptimal in some way the error fails to mention (#GH111550).
399+
400+
- Clang now emits a ``-Wdepredcated-literal-operator`` diagnostic, even if the
401+
name was a reserved name, which we improperly allowed to suppress the
402+
diagnostic.
381403

382404
Improvements to Clang's time-trace
383405
----------------------------------

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ def warn_reserved_extern_symbol: Warning<
439439
InGroup<ReservedIdentifier>, DefaultIgnore;
440440
def warn_deprecated_literal_operator_id: Warning<
441441
"identifier %0 preceded by whitespace in a literal operator declaration "
442-
"is deprecated">, InGroup<DeprecatedLiteralOperator>, DefaultIgnore;
442+
"is deprecated">, InGroup<DeprecatedLiteralOperator>;
443443
def warn_reserved_module_name : Warning<
444444
"%0 is a reserved name for a module">, InGroup<ReservedModuleIdentifier>;
445445
def warn_import_implementation_partition_unit_in_interface_unit : Warning<

clang/lib/Basic/IdentifierTable.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,9 @@ ReservedLiteralSuffixIdStatus
406406
IdentifierInfo::isReservedLiteralSuffixId() const {
407407
StringRef Name = getName();
408408

409+
// Note: the diag::warn_deprecated_literal_operator_id diagnostic depends on
410+
// this being the first check we do, so if this order changes, we have to fix
411+
// that as well.
409412
if (Name[0] != '_')
410413
return ReservedLiteralSuffixIdStatus::NotStartsWithUnderscore;
411414

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -503,17 +503,23 @@ bool Sema::checkLiteralOperatorId(const CXXScopeSpec &SS,
503503
const IdentifierInfo *II = Name.Identifier;
504504
ReservedIdentifierStatus Status = II->isReserved(PP.getLangOpts());
505505
SourceLocation Loc = Name.getEndLoc();
506-
if (!PP.getSourceManager().isInSystemHeader(Loc)) {
507-
if (auto Hint = FixItHint::CreateReplacement(
508-
Name.getSourceRange(),
509-
(StringRef("operator\"\"") + II->getName()).str());
510-
isReservedInAllContexts(Status)) {
511-
Diag(Loc, diag::warn_reserved_extern_symbol)
512-
<< II << static_cast<int>(Status) << Hint;
513-
} else {
514-
Diag(Loc, diag::warn_deprecated_literal_operator_id) << II << Hint;
515-
}
516-
}
506+
507+
auto Hint = FixItHint::CreateReplacement(
508+
Name.getSourceRange(),
509+
(StringRef("operator\"\"") + II->getName()).str());
510+
511+
// Only emit this diagnostic if we start with an underscore, else the
512+
// diagnostic for C++11 requiring a space between the quotes and the
513+
// identifier conflicts with this and gets confusing. The diagnostic stating
514+
// this is a reserved name should force the underscore, which gets this
515+
// back.
516+
if (II->isReservedLiteralSuffixId() !=
517+
ReservedLiteralSuffixIdStatus::NotStartsWithUnderscore)
518+
Diag(Loc, diag::warn_deprecated_literal_operator_id) << II << Hint;
519+
520+
if (isReservedInAllContexts(Status))
521+
Diag(Loc, diag::warn_reserved_extern_symbol)
522+
<< II << static_cast<int>(Status) << Hint;
517523
}
518524

519525
if (!SS.isValid())

clang/test/CXX/drs/cwg14xx.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ int i = N::f();
627627

628628
namespace cwg1479 { // cwg1479: 3.1
629629
#if __cplusplus >= 201103L
630-
int operator"" _a(const char*, std::size_t = 0);
630+
int operator""_a(const char*, std::size_t = 0);
631631
// since-cxx11-error@-1 {{literal operator cannot have a default argument}}
632632
#endif
633633
}

clang/test/CXX/drs/cwg25xx.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ operator"" _div();
8888
using ::cwg2521::operator"" _\u03C0___;
8989
using ::cwg2521::operator""_div;
9090
// since-cxx11-warning@-2 {{identifier '_π___' preceded by whitespace in a literal operator declaration is deprecated}}
91+
92+
long double operator"" _RESERVED(long double);
93+
// since-cxx11-warning@-1 {{identifier '_RESERVED' preceded by whitespace in a literal operator declaration is deprecated}}
9194
#pragma clang diagnostic pop
9295
#endif
9396
} // namespace cwg2521

clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
1+
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wno-deprecated-literal-operator -verify %s
22

33
void operator "" p31(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
44
void operator "" _p31(long double);

clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -std=c++11 -verify %s
1+
// RUN: %clang_cc1 -std=c++11 -Wno-deprecated-literal-operator -verify %s
22

33
using size_t = decltype(sizeof(int));
44
void operator "" wibble(const char *); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}

clang/test/CXX/lex/lex.literal/lex.ext/p11.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@ template<typename T, typename U> struct same_type;
66
template<typename T> struct same_type<T, T> {};
77
template<typename T> using X = T;
88
template<typename CharT, X<CharT>...>
9-
int operator "" _x(); // expected-warning {{string literal operator templates are a GNU extension}}
9+
int operator ""_x(); // expected-warning {{string literal operator templates are a GNU extension}}
1010
template<char...>
11-
double operator "" _x();
11+
double operator ""_x();
1212

1313
auto a="string"_x;
1414
auto b=42_x;
1515
same_type<decltype(a), int> test_a;
1616
same_type<decltype(b), double> test_b;
1717

18-
char operator "" _x(const char *begin, size_t size);
18+
char operator ""_x(const char *begin, size_t size);
1919
auto c="string"_x;
2020
auto d=L"string"_x;
2121
same_type<decltype(c), char> test_c;
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
22

3-
int &operator "" _x1 (unsigned long long);
3+
int &operator ""_x1 (unsigned long long);
44
int &i1 = 0x123_x1;
55

6-
double &operator "" _x1 (const char *);
6+
double &operator ""_x1 (const char *);
77
int &i2 = 45_x1;
88

9-
template<char...> char &operator "" _x1 ();
9+
template<char...> char &operator ""_x1 ();
1010
int &i3 = 0377_x1;
1111

1212
int &i4 = 90000000000000000000000000000000000000000000000_x1; // expected-error {{integer literal is too large to be represented in any integer type}}
1313

14-
double &operator "" _x2 (const char *);
14+
double &operator ""_x2 (const char *);
1515
double &i5 = 123123123123123123123123123123123123123123123_x2;
1616

17-
template<char...Cs> constexpr int operator "" _x3() { return sizeof...(Cs); }
17+
template<char...Cs> constexpr int operator ""_x3() { return sizeof...(Cs); }
1818
static_assert(123456789012345678901234567890123456789012345678901234567890_x3 == 60, "");

0 commit comments

Comments
 (0)