diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-07 03:13:00 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-07 03:13:00 +0000 |
commit | e816c717d4de1de6c67f1fd5ef4a927fe2bf2ea7 (patch) | |
tree | fa77dc0429d47e276b4ca8a66736d521f0deaf16 | |
parent | 946e2726f91c17574d248f9c4b3eeea41e892a22 (diff) |
Add -Wc++11-compat warning for string and character literals followed by
identifiers, in cases where those identifiers would be treated as
user-defined literal suffixes in C++11.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152198 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticLexKinds.td | 3 | ||||
-rw-r--r-- | lib/Lex/Lexer.cpp | 17 | ||||
-rw-r--r-- | test/SemaCXX/cxx0x-compat.cpp | 10 |
3 files changed, 25 insertions, 5 deletions
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td index 776568f076..d31a48b656 100644 --- a/include/clang/Basic/DiagnosticLexKinds.td +++ b/include/clang/Basic/DiagnosticLexKinds.td @@ -131,6 +131,9 @@ def warn_ucn_not_valid_in_c89 : ExtWarn< def warn_cxx98_compat_unicode_literal : Warning< "unicode literals are incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; +def warn_cxx11_compat_user_defined_literal : Warning< + "identifier after literal will be treated as a user-defined literal suffix " + "in C++11">, InGroup<CXX11Compat>, DefaultIgnore; def err_unsupported_string_concat : Error< "unsupported non-standard concatenation of string literals">; def err_string_concat_mixed_suffix : Error< diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp index a7fba8019d..0d388c6d01 100644 --- a/lib/Lex/Lexer.cpp +++ b/lib/Lex/Lexer.cpp @@ -1574,14 +1574,21 @@ void Lexer::LexNumericConstant(Token &Result, const char *CurPtr) { } /// LexUDSuffix - Lex the ud-suffix production for user-defined literal suffixes -/// in C++11. +/// in C++11, or warn on a ud-suffix in C++98. const char *Lexer::LexUDSuffix(Token &Result, const char *CurPtr) { - assert(getFeatures().CPlusPlus0x && "ud-suffix only exists in C++11"); + assert(getFeatures().CPlusPlus); // Maximally munch an identifier. FIXME: UCNs. unsigned Size; char C = getCharAndSize(CurPtr, Size); if (isIdentifierHead(C)) { + if (!getFeatures().CPlusPlus0x) { + if (!isLexingRawMode()) + Diag(CurPtr, diag::warn_cxx11_compat_user_defined_literal) + << FixItHint::CreateInsertion(getSourceLocation(CurPtr), " "); + return CurPtr; + } + Result.setFlag(Token::HasUDSuffix); do { CurPtr = ConsumeChar(CurPtr, Size, Result); @@ -1631,7 +1638,7 @@ void Lexer::LexStringLiteral(Token &Result, const char *CurPtr, } // If we are in C++11, lex the optional ud-suffix. - if (getFeatures().CPlusPlus0x) + if (getFeatures().CPlusPlus) CurPtr = LexUDSuffix(Result, CurPtr); // If a nul character existed in the string, warn about it. @@ -1714,7 +1721,7 @@ void Lexer::LexRawStringLiteral(Token &Result, const char *CurPtr, } // If we are in C++11, lex the optional ud-suffix. - if (getFeatures().CPlusPlus0x) + if (getFeatures().CPlusPlus) CurPtr = LexUDSuffix(Result, CurPtr); // Update the location of token as well as BufferPtr. @@ -1801,7 +1808,7 @@ void Lexer::LexCharConstant(Token &Result, const char *CurPtr, } // If we are in C++11, lex the optional ud-suffix. - if (getFeatures().CPlusPlus0x) + if (getFeatures().CPlusPlus) CurPtr = LexUDSuffix(Result, CurPtr); // If a nul character existed in the character, warn about it. diff --git a/test/SemaCXX/cxx0x-compat.cpp b/test/SemaCXX/cxx0x-compat.cpp index 1ae1c608c1..611dcc755e 100644 --- a/test/SemaCXX/cxx0x-compat.cpp +++ b/test/SemaCXX/cxx0x-compat.cpp @@ -27,3 +27,13 @@ struct S { } s = { n }, // expected-warning {{non-constant-expression cannot be narrowed from type 'int' to 'char' in initializer list in C++11}} expected-note {{explicit cast}} t = { 1234 }; // expected-warning {{constant expression evaluates to 1234 which cannot be narrowed to type 'char' in C++11}} expected-warning {{changes value}} expected-note {{explicit cast}} + +#define PRIuS "uS" +int printf(const char *, ...); +typedef __typeof(sizeof(int)) size_t; +void h(size_t foo, size_t bar) { + printf("foo is %"PRIuS", bar is %"PRIuS, foo, bar); // expected-warning 2{{identifier after literal will be treated as a user-defined literal suffix in C++11}} +} + +#define x + 1 +char c = 'x'x; // expected-warning {{will be treated as a user-defined literal suffix}} |