зеркало из https://github.com/microsoft/clang-1.git
-Wc++98-compat warnings for the lexer.
This also adds a -Wc++98-compat-pedantic for warning on constructs which would be diagnosed by -std=c++98 -pedantic (that is, it warns even on C++11 features which we enable by default, with no warning, in C++98 mode). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142034 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
b75a3451bc
Коммит
661a99690b
|
@ -74,6 +74,9 @@ def note_pragma_entered_here : Note<"#pragma entered here">;
|
|||
def ext_longlong : Extension<
|
||||
"'long long' is an extension when C99 mode is not enabled">,
|
||||
InGroup<LongLong>;
|
||||
def warn_cxx98_compat_longlong : Warning<
|
||||
"'long long' is incompatible with C++98">,
|
||||
InGroup<CXX98CompatPedantic>, DefaultIgnore;
|
||||
def warn_integer_too_large : Warning<
|
||||
"integer constant is too large for its type">;
|
||||
def warn_integer_too_large_for_signed : Warning<
|
||||
|
|
|
@ -55,6 +55,8 @@ def FormatExtraArgs : DiagGroup<"format-extra-args">;
|
|||
def FormatZeroLength : DiagGroup<"format-zero-length">;
|
||||
|
||||
def CXX98Compat : DiagGroup<"c++98-compat">;
|
||||
// Warnings for C++11 features which are Extensions in C++98 mode.
|
||||
def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic", [CXX98Compat]>;
|
||||
|
||||
def CXX11Narrowing : DiagGroup<"c++11-narrowing">;
|
||||
def : DiagGroup<"c++0x-narrowing", [CXX11Narrowing]>;
|
||||
|
|
|
@ -24,6 +24,11 @@ def escaped_newline_block_comment_end : Warning<
|
|||
def backslash_newline_space : Warning<
|
||||
"backslash and newline separated by space">;
|
||||
|
||||
// Digraphs.
|
||||
def warn_cxx98_compat_less_colon_colon : Warning<
|
||||
"'<::' is treated as digraph '<:' (aka '[') followed by ':' in C++98">,
|
||||
InGroup<CXX98Compat>, DefaultIgnore;
|
||||
|
||||
// Trigraphs.
|
||||
def trigraph_ignored : Warning<"trigraph ignored">, InGroup<Trigraphs>;
|
||||
def trigraph_ignored_block_comment : Warning<
|
||||
|
@ -67,6 +72,9 @@ def err_invalid_char_raw_delim : Error<
|
|||
"; use PREFIX( )PREFIX to delimit raw string">;
|
||||
def err_unterminated_raw_string : Error<
|
||||
"raw string missing terminating delimiter )%0\"">;
|
||||
def warn_cxx98_compat_raw_string_literal : Warning<
|
||||
"raw string literals are incompatible with C++98">,
|
||||
InGroup<CXX98Compat>, DefaultIgnore;
|
||||
|
||||
def ext_multichar_character_literal : ExtWarn<
|
||||
"multi-character character constant">, InGroup<MultiChar>;
|
||||
|
@ -112,6 +120,9 @@ def warn_ucn_escape_too_large : ExtWarn<
|
|||
"character unicode escape sequence too long for its type">;
|
||||
def warn_ucn_not_valid_in_c89 : ExtWarn<
|
||||
"unicode escape sequences are only valid in C99 or C++">;
|
||||
def warn_cxx98_compat_unicode_literal : Warning<
|
||||
"unicode literals are incompatible with C++98">,
|
||||
InGroup<CXX98Compat>, DefaultIgnore;
|
||||
def err_unsupported_string_concat : Error<
|
||||
"unsupported non-standard concatenation of string literals">;
|
||||
|
||||
|
@ -179,6 +190,9 @@ def ext_pp_bad_vaargs_use : Extension<
|
|||
def ext_pp_macro_redef : ExtWarn<"%0 macro redefined">;
|
||||
def ext_variadic_macro : Extension<"variadic macros were introduced in C99">,
|
||||
InGroup<VariadicMacros>;
|
||||
def warn_cxx98_compat_variadic_macro : Warning<
|
||||
"variadic macros are incompatible with C++98">,
|
||||
InGroup<CXX98CompatPedantic>, DefaultIgnore;
|
||||
def ext_named_variadic_macro : Extension<
|
||||
"named variadic macros are a GNU extension">, InGroup<VariadicMacros>;
|
||||
def ext_embedded_directive : Extension<
|
||||
|
@ -187,6 +201,9 @@ def ext_missing_varargs_arg : Extension<
|
|||
"varargs argument missing, but tolerated as an extension">;
|
||||
def ext_empty_fnmacro_arg : Extension<
|
||||
"empty macro arguments were standardized in C99">;
|
||||
def warn_cxx98_compat_empty_fnmacro_arg : Warning<
|
||||
"empty macro argument list is incompatible with C++98">,
|
||||
InGroup<CXX98CompatPedantic>, DefaultIgnore;
|
||||
|
||||
def err_pp_invalid_directive : Error<"invalid preprocessing directive">;
|
||||
def err_pp_hash_error : Error<"#error%0">;
|
||||
|
@ -334,6 +351,9 @@ def err_pp_linemarker_invalid_pop : Error<
|
|||
"invalid line marker flag '2': cannot pop empty include stack">;
|
||||
def ext_pp_line_too_big : Extension<
|
||||
"C requires #line number to be less than %0, allowed as extension">;
|
||||
def warn_cxx98_compat_pp_line_too_big : Warning<
|
||||
"#line number greater than 32767 is incompatible with C++98">,
|
||||
InGroup<CXX98CompatPedantic>, DefaultIgnore;
|
||||
|
||||
def err_pp_export_non_macro : Error<"no macro named %0 to export">;
|
||||
|
||||
|
|
|
@ -1373,6 +1373,12 @@ void Lexer::LexStringLiteral(Token &Result, const char *CurPtr,
|
|||
tok::TokenKind Kind) {
|
||||
const char *NulCharacter = 0; // Does this string contain the \0 character?
|
||||
|
||||
if (!isLexingRawMode() &&
|
||||
(Kind == tok::utf8_string_literal ||
|
||||
Kind == tok::utf16_string_literal ||
|
||||
Kind == tok::utf32_string_literal))
|
||||
Diag(BufferPtr, diag::warn_cxx98_compat_unicode_literal);
|
||||
|
||||
char C = getAndAdvanceChar(CurPtr, Result);
|
||||
while (C != '"') {
|
||||
// Skip escaped characters. Escaped newlines will already be processed by
|
||||
|
@ -1419,6 +1425,9 @@ void Lexer::LexRawStringLiteral(Token &Result, const char *CurPtr,
|
|||
// any transformations performed in phases 1 and 2 (trigraphs,
|
||||
// universal-character-names, and line splicing) are reverted.
|
||||
|
||||
if (!isLexingRawMode())
|
||||
Diag(BufferPtr, diag::warn_cxx98_compat_raw_string_literal);
|
||||
|
||||
unsigned PrefixLen = 0;
|
||||
|
||||
while (PrefixLen != 16 && isRawStringDelimBody(CurPtr[PrefixLen]))
|
||||
|
@ -1523,6 +1532,10 @@ void Lexer::LexCharConstant(Token &Result, const char *CurPtr,
|
|||
tok::TokenKind Kind) {
|
||||
const char *NulCharacter = 0; // Does this character contain the \0 character?
|
||||
|
||||
if (!isLexingRawMode() &&
|
||||
(Kind == tok::utf16_char_constant || Kind == tok::utf32_char_constant))
|
||||
Diag(BufferPtr, diag::warn_cxx98_compat_unicode_literal);
|
||||
|
||||
char C = getAndAdvanceChar(CurPtr, Result);
|
||||
if (C == '\'') {
|
||||
if (!isLexingRawMode() && !Features.AsmPreprocessor)
|
||||
|
@ -2799,6 +2812,8 @@ LexNextToken:
|
|||
char After = getCharAndSize(CurPtr + SizeTmp + SizeTmp2, SizeTmp3);
|
||||
if (After != ':' && After != '>') {
|
||||
Kind = tok::less;
|
||||
if (!isLexingRawMode())
|
||||
Diag(BufferPtr, diag::warn_cxx98_compat_less_colon_colon);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -777,6 +777,8 @@ void Preprocessor::HandleLineDirective(Token &Tok) {
|
|||
LineLimit = 2147483648U;
|
||||
if (LineNo >= LineLimit)
|
||||
Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
|
||||
else if (Features.CPlusPlus0x && LineNo >= 32768U)
|
||||
Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
|
||||
|
||||
int FilenameID = -1;
|
||||
Token StrTok;
|
||||
|
@ -1367,8 +1369,10 @@ bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI) {
|
|||
Diag(Tok, diag::err_pp_expected_ident_in_arg_list);
|
||||
return true;
|
||||
case tok::ellipsis: // #define X(... -> C99 varargs
|
||||
if (!Features.C99 && !Features.CPlusPlus0x)
|
||||
Diag(Tok, diag::ext_variadic_macro);
|
||||
if (!Features.C99)
|
||||
Diag(Tok, Features.CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_variadic_macro :
|
||||
diag::ext_variadic_macro);
|
||||
|
||||
// Lex the token after the identifier.
|
||||
LexUnexpandedToken(Tok);
|
||||
|
|
|
@ -216,9 +216,9 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
|
|||
assert(Literal.isIntegerLiteral() && "Unknown ppnumber");
|
||||
|
||||
// long long is a C99 feature.
|
||||
if (!PP.getLangOptions().C99 && !PP.getLangOptions().CPlusPlus0x
|
||||
&& Literal.isLongLong)
|
||||
PP.Diag(PeekTok, diag::ext_longlong);
|
||||
if (!PP.getLangOptions().C99 && Literal.isLongLong)
|
||||
PP.Diag(PeekTok, PP.getLangOptions().CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_longlong : diag::ext_longlong);
|
||||
|
||||
// Parse the integer literal into Result.
|
||||
if (Literal.GetIntegerValue(Result.Val)) {
|
||||
|
@ -778,4 +778,3 @@ EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) {
|
|||
DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
|
||||
return ResVal.Val != 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -421,8 +421,10 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
|
|||
|
||||
// Empty arguments are standard in C99 and C++0x, and are supported as an extension in
|
||||
// other modes.
|
||||
if (ArgTokens.size() == ArgTokenStart && !Features.C99 && !Features.CPlusPlus0x)
|
||||
Diag(Tok, diag::ext_empty_fnmacro_arg);
|
||||
if (ArgTokens.size() == ArgTokenStart && !Features.C99)
|
||||
Diag(Tok, Features.CPlusPlus0x ?
|
||||
diag::warn_cxx98_compat_empty_fnmacro_arg :
|
||||
diag::ext_empty_fnmacro_arg);
|
||||
|
||||
// Add a marker EOF token to the end of the token list for this argument.
|
||||
Token EOFTok;
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat-pedantic -verify %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -std=c++98 -Werror %s
|
||||
|
||||
// -Wc++98-compat-pedantic warns on C++11 features which we accept without a
|
||||
// warning in C++98 mode.
|
||||
|
||||
#line 32767 // ok
|
||||
#line 32768 // expected-warning {{#line number greater than 32767 is incompatible with C++98}}
|
||||
|
||||
#define VA_MACRO(x, ...) x // expected-warning {{variadic macros are incompatible with C++98}}
|
||||
VA_MACRO(,x) // expected-warning {{empty macro argument list is incompatible with C++98}}
|
|
@ -11,3 +11,20 @@ class Variadic3 {};
|
|||
|
||||
int alignas(8) with_alignas; // expected-warning {{'alignas' is incompatible with C++98}}
|
||||
int with_attribute [[ ]]; // expected-warning {{attributes are incompatible with C++98}}
|
||||
|
||||
void Literals() {
|
||||
(void)u8"str"; // expected-warning {{unicode literals are incompatible with C++98}}
|
||||
(void)u"str"; // expected-warning {{unicode literals are incompatible with C++98}}
|
||||
(void)U"str"; // expected-warning {{unicode literals are incompatible with C++98}}
|
||||
(void)u'x'; // expected-warning {{unicode literals are incompatible with C++98}}
|
||||
(void)U'x'; // expected-warning {{unicode literals are incompatible with C++98}}
|
||||
|
||||
(void)u8R"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}}
|
||||
(void)uR"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}}
|
||||
(void)UR"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}}
|
||||
(void)R"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}}
|
||||
(void)LR"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}}
|
||||
}
|
||||
|
||||
template<typename T> struct S {};
|
||||
S<::S<void> > s; // expected-warning {{'<::' is treated as digraph '<:' (aka '[') followed by ':' in C++98}}
|
||||
|
|
Загрузка…
Ссылка в новой задаче