diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -502,6 +502,10 @@ - Implemented `P0849R8: auto(x): decay-copy in the language `_. - Implemented `P2242R3: Non-literal variables (and labels and gotos) in constexpr functions `_. - Implemented `LWG3659: Consider ATOMIC_FLAG_INIT undeprecation `_. +- Implemented `P2290 Delimited escape sequences `_. + This feature is available as an extension in all C and C++ language modes. +- Implemented `P2071 Named universal character escapes `_. + This feature is available as an extension in all C and C++ language modes. CUDA/HIP Language Changes in Clang ---------------------------------- diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -130,8 +130,15 @@ "some environments">, InGroup>; def ext_delimited_escape_sequence : Extension< - "%select{delimited|named}0 escape sequences are a Clang extension">, + "%select{delimited|named}0 escape sequences are a " + "%select{Clang|C++2b}1 extension">, InGroup>; + +def warn_cxx2b_delimited_escape_sequence : Warning< + "%select{delimited|named}0 escape sequences are " + "incompatible with C++ standards before C++2b">, + InGroup, DefaultIgnore; + def err_delimited_escape_empty : Error< "delimited escape sequence cannot be empty">; def err_delimited_escape_missing_brace: Error< diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -3287,7 +3287,10 @@ } if (Delimited && PP) { - Diag(BufferPtr, diag::ext_delimited_escape_sequence) << /*delimited*/ 0; + Diag(BufferPtr, PP->getLangOpts().CPlusPlus2b + ? diag::warn_cxx2b_delimited_escape_sequence + : diag::ext_delimited_escape_sequence) + << /*delimited*/ 0 << (PP->getLangOpts().CPlusPlus ? 1 : 0); } if (Result) { @@ -3371,7 +3374,10 @@ } if (Diagnose && PP && !LooseMatch) - Diag(BufferPtr, diag::ext_delimited_escape_sequence) << /*named*/ 1; + Diag(BufferPtr, PP->getLangOpts().CPlusPlus2b + ? diag::warn_cxx2b_delimited_escape_sequence + : diag::ext_delimited_escape_sequence) + << /*named*/ 1 << (PP->getLangOpts().CPlusPlus ? 1 : 0); if (LooseMatch) Res = LooseMatch->CodePoint; diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -311,8 +311,9 @@ << tok::r_brace; else if (!HadError) { Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf, - diag::ext_delimited_escape_sequence) - << /*delimited*/ 0; + Features.CPlusPlus2b ? diag::warn_cxx2b_delimited_escape_sequence + : diag::ext_delimited_escape_sequence) + << /*delimited*/ 0 << (Features.CPlusPlus ? 1 : 0); } } @@ -641,8 +642,9 @@ if ((IsDelimitedEscapeSequence || IsNamedEscapeSequence) && Diags) Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf, - diag::ext_delimited_escape_sequence) - << (IsNamedEscapeSequence ? 1 : 0); + Features.CPlusPlus2b ? diag::warn_cxx2b_delimited_escape_sequence + : diag::ext_delimited_escape_sequence) + << (IsNamedEscapeSequence ? 1 : 0) << (Features.CPlusPlus ? 1 : 0); return true; } diff --git a/clang/test/Lexer/char-escapes-delimited.c b/clang/test/Lexer/char-escapes-delimited.c --- a/clang/test/Lexer/char-escapes-delimited.c +++ b/clang/test/Lexer/char-escapes-delimited.c @@ -1,8 +1,9 @@ -// RUN: %clang_cc1 -x c++ -std=gnu++11 -fsyntax-only -pedantic -verify %s -// RUN: %clang_cc1 -x c -std=gnu11 -fsyntax-only -pedantic -verify %s -// RUN: %clang_cc1 -x c++ -std=gnu++11 -fwchar-type=short -fno-signed-wchar -fsyntax-only -pedantic -verify %s -// RUN: %clang_cc1 -x c -std=gnu11 -fwchar-type=short -fno-signed-wchar -fsyntax-only -pedantic -verify %s -// RUN: %clang_cc1 -x c++ -std=c++17 -ftrigraphs -fsyntax-only -pedantic -verify -DTRIGRAPHS=1 %s +// RUN: %clang_cc1 -x c++ -std=gnu++11 -fsyntax-only -pedantic -verify=ext,expected %s +// RUN: %clang_cc1 -x c -std=gnu11 -fsyntax-only -pedantic -verify=ext,expected %s +// RUN: %clang_cc1 -x c++ -std=c++2b -fsyntax-only -pedantic -verify=cxx2b,expected -Wpre-c++2b-compat %s +// RUN: %clang_cc1 -x c++ -std=gnu++11 -fwchar-type=short -fno-signed-wchar -fsyntax-only -pedantic -verify=ext,expected %s +// RUN: %clang_cc1 -x c -std=gnu11 -fwchar-type=short -fno-signed-wchar -fsyntax-only -pedantic -verify=ext,expected %s +// RUN: %clang_cc1 -x c++ -std=c++17 -ftrigraphs -fsyntax-only -pedantic -verify=ext,expected -DTRIGRAPHS=1 %s const char *errors = "\u{}" // expected-error {{delimited escape sequence cannot be empty}} @@ -19,46 +20,46 @@ ; void ucn(void) { - char a = '\u{1234}'; // expected-error {{character too large for enclosing character literal type}} - // expected-warning@-1 {{delimited escape sequences are a Clang extension}} + char a = '\u{1234}'; // expected-error {{character too large for enclosing character literal type}} \ + // ext-warning {{extension}} cxx2b-warning {{C++2b}} - unsigned b = U'\u{1234}'; // expected-warning {{extension}} + unsigned b = U'\u{1234}'; // ext-warning {{extension}} cxx2b-warning {{C++2b}} #ifdef __cplusplus - unsigned b2 = U'\u{1}'; // expected-warning {{extension}} + unsigned b2 = U'\u{1}'; // ext-warning {{extension}} cxx2b-warning {{C++2b}} #else unsigned b2 = U'\u{1}'; //expected-error {{universal character name refers to a control character}} #endif - unsigned c = U'\u{000000000001234}'; // expected-warning {{extension}} + unsigned c = U'\u{000000000001234}'; // ext-warning {{extension}} cxx2b-warning {{C++2b}} unsigned d = U'\u{111111111}'; //expected-error {{hex escape sequence out of range}} } void hex(void) { - char a = '\x{1}'; // expected-warning {{extension}} + char a = '\x{1}'; // ext-warning {{extension}} cxx2b-warning {{C++2b}} char b = '\x{abcdegggggabc}'; // expected-error 5{{invalid digit 'g' in escape sequence}} char c = '\x{ff1}'; // expected-error {{hex escape sequence out of range}} #if __WCHAR_MAX__ > 0xFFFF - unsigned d = L'\x{FFFFFFFF}'; // expected-warning {{extension}} + unsigned d = L'\x{FFFFFFFF}'; // ext-warning {{extension}} cxx2b-warning {{C++2b}} unsigned e = L'\x{100000000}'; // expected-error {{hex escape sequence out of range}} #else - unsigned f = L'\x{FFFF}'; // expected-warning {{extension}} + unsigned f = L'\x{FFFF}'; // ext-warning {{extension}} cxx2b-warning {{C++2b}} unsigned g = L'\x{10000}'; // expected-error {{hex escape sequence out of range}} #endif - unsigned h = U'\x{FFFFFFFF}'; // expected-warning {{extension}} + unsigned h = U'\x{FFFFFFFF}'; // ext-warning {{extension}} cxx2b-warning {{C++2b}} unsigned i = U'\x{100000000}'; // expected-error {{hex escape sequence out of range}} } void octal(void) { - char a = '\o{1}'; // expected-warning {{extension}} + char a = '\o{1}'; // ext-warning {{extension}} cxx2b-warning {{C++2b}} char b = '\o{12345678881238}'; // expected-error 4{{invalid digit '8' in escape sequence}} char c = '\o{777}'; // //expected-error {{octal escape sequence out of range}} #if __WCHAR_MAX__ > 0xFFFF - unsigned d = L'\o{37777777777}'; // expected-warning {{extension}} + unsigned d = L'\o{37777777777}'; // ext-warning {{extension}} cxx2b-warning {{C++2b}} unsigned e = L'\o{40000000000}'; // expected-error {{octal escape sequence out of range}} #else - unsigned d = L'\o{177777}'; // expected-warning {{extension}} + unsigned d = L'\o{177777}'; // ext-warning {{extension}} cxx2b-warning {{C++2b}} unsigned e = L'\o{200000}'; // expected-error {{octal escape sequence out of range}} #endif } @@ -75,9 +76,9 @@ void named(void) { char a = '\N{LOTUS}'; // expected-error{{character too large for enclosing character literal type}} \ - // expected-warning {{extension}} + // ext-warning {{extension}} cxx2b-warning {{C++2b}} - char b = '\N{DOLLAR SIGN}'; // expected-warning {{extension}} + char b = '\N{DOLLAR SIGN}'; // ext-warning {{extension}} cxx2b-warning {{C++2b}} char b_ = '\N{ DOL-LAR _SIGN }'; // expected-error {{' DOL-LAR _SIGN ' is not a valid Unicode character name}} \ // expected-note {{characters names in Unicode escape sequences are sensitive to case and whitespaces}} @@ -86,13 +87,13 @@ char d = '\N{}'; // expected-error {{delimited escape sequence cannot be empty}} char e = '\N{'; // expected-error {{incomplete universal character name}} - unsigned f = L'\N{GREEK CAPITAL LETTER DELTA}'; // expected-warning {{extension}} + unsigned f = L'\N{GREEK CAPITAL LETTER DELTA}'; // ext-warning {{extension}} cxx2b-warning {{C++2b}} unsigned g = u'\N{LOTUS}'; // expected-error {{character too large for enclosing character literal type}} \ - // expected-warning {{extension}} + // ext-warning {{extension}} cxx2b-warning {{C++2b}} - unsigned h = U'\N{LOTUS}'; // expected-warning {{extension}} - unsigned i = u'\N{GREEK CAPITAL LETTER DELTA}'; // expected-warning {{extension}} + unsigned h = U'\N{LOTUS}'; // ext-warning {{extension}} cxx2b-warning {{C++2b}} + unsigned i = u'\N{GREEK CAPITAL LETTER DELTA}'; // ext-warning {{extension}} cxx2b-warning {{C++2b}} char j = '\NN'; // expected-error {{expected '{' after '\N' escape sequence}} unsigned k = u'\N{LOTUS'; // expected-error {{incomplete universal character name}} } @@ -107,11 +108,11 @@ // expected-warning@-2 3{{expression result unused}} } -#if L'\N{GREEK CAPITAL LETTER GAMMA}' != L'Γ' // expected-warning {{extension}} +#if L'\N{GREEK CAPITAL LETTER GAMMA}' != L'Γ' // ext-warning {{extension}} cxx2b-warning {{C++2b}} #error "oh no!" #endif #ifdef TRIGRAPHS static_assert('\N??' == '$'); // expected-warning 2{{trigraph converted}} \ - // expected-warning {{named escape sequences are a Clang extension}} + // ext-warning {{extension}} cxx2b-warning {{C++2b}} #endif diff --git a/clang/test/Preprocessor/ucn-pp-identifier.c b/clang/test/Preprocessor/ucn-pp-identifier.c --- a/clang/test/Preprocessor/ucn-pp-identifier.c +++ b/clang/test/Preprocessor/ucn-pp-identifier.c @@ -1,6 +1,7 @@ -// RUN: %clang_cc1 %s -fsyntax-only -std=c99 -pedantic -verify -Wundef -// RUN: %clang_cc1 %s -fsyntax-only -x c++ -pedantic -verify -Wundef -// RUN: %clang_cc1 %s -fsyntax-only -x c++ -pedantic -verify -Wundef -ftrigraphs -DTRIGRAPHS=1 +// RUN: %clang_cc1 %s -fsyntax-only -std=c99 -pedantic -verify=expected,ext -Wundef +// RUN: %clang_cc1 %s -fsyntax-only -x c++ -pedantic -verify=expected,ext -Wundef +// RUN: %clang_cc1 %s -fsyntax-only -x c++ -std=c++2b -pedantic -ftrigraphs -verify=expected,cxx2b -Wundef -Wpre-c++2b-compat +// RUN: %clang_cc1 %s -fsyntax-only -x c++ -pedantic -verify=expected,ext -Wundef -ftrigraphs -DTRIGRAPHS=1 // RUN: not %clang_cc1 %s -fsyntax-only -std=c99 -pedantic -Wundef 2>&1 | FileCheck -strict-whitespace %s #define \u00FC @@ -17,7 +18,7 @@ #error "This should never happen" #endif -#if a\u{FD}() //expected-warning {{Clang extension}} +#if a\u{FD}() // ext-warning {{extension}} cxx2b-warning {{before C++2b}} #error "This should never happen" #endif @@ -30,14 +31,15 @@ // Make sure we reject disallowed UCNs #define \ufffe // expected-error {{macro name must be an identifier}} -#define \U10000000 // expected-error {{macro name must be an identifier}} -#define \u0061 // expected-error {{character 'a' cannot be specified by a universal character name}} expected-error {{macro name must be an identifier}} -#define \u{fffe} // expected-error {{macro name must be an identifier}} expected-warning {{Clang extension}} +#define \U10000000 // expected-error {{macro name must be an identifier}} +#define \u0061 // expected-error {{character 'a' cannot be specified by a universal character name}} expected-error {{macro name must be an identifier}} +#define \u{fffe} // expected-error {{macro name must be an identifier}} \ + // ext-warning {{extension}} cxx2b-warning {{before C++2b}} #define \N{ALERT} // expected-error {{universal character name refers to a control character}} \ // expected-error {{macro name must be an identifier}} \ - // expected-warning {{Clang extension}} + // ext-warning {{extension}} cxx2b-warning {{before C++2b}} #define \N{WASTEBASKET} // expected-error {{macro name must be an identifier}} \ - // expected-warning {{Clang extension}} + // ext-warning {{extension}} cxx2b-warning {{before C++2b}} #define a\u0024 @@ -132,7 +134,7 @@ // expected-warning {{incomplete delimited universal character name}} #ifdef TRIGRAPHS -int \N?? = 0; // expected-warning{{amed escape sequences are a Clang extension}} \ +int \N?? = 0; // expected-warning{{extension}} cxx2b-warning {{before C++2b}} \ // expected-warning 2{{trigraph converted}} #endif diff --git a/clang/test/Sema/ucn-identifiers.c b/clang/test/Sema/ucn-identifiers.c --- a/clang/test/Sema/ucn-identifiers.c +++ b/clang/test/Sema/ucn-identifiers.c @@ -17,8 +17,8 @@ \u00fcber(1); über(2); \U000000FCber(3); - \u{FC}ber(4); // expected-warning {{Clang extension}} - \N{LATIN SMALL LETTER U WITH DIAERESIS}ber(4); // expected-warning {{Clang extension}} + \u{FC}ber(4); // expected-warning {{extension}} + \N{LATIN SMALL LETTER U WITH DIAERESIS}ber(4); // expected-warning {{extension}} } void badCalls(void) {