diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-12-30 23:37:31 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-12-30 23:37:31 +0000 |
commit | 4debc82d9d967501b8650599cd44003d7026f56c (patch) | |
tree | 85db2abeab374f547792a45e71b80c3c8b68d7c6 | |
parent | 51201882382fb40c9456a06c7f93d6ddd4a57712 (diff) |
Fix crash when trying to pretty-print unicode or wide string literals.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147385 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/AST/StmtPrinter.cpp | 27 | ||||
-rw-r--r-- | test/SemaCXX/constexpr-printing.cpp | 14 |
2 files changed, 33 insertions, 8 deletions
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 6d9139c000..6408c879fa 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -710,16 +710,27 @@ void StmtPrinter::VisitStringLiteral(StringLiteral *Str) { case StringLiteral::UTF32: OS << 'U'; break; } OS << '"'; + static char Hex[] = "0123456789ABCDEF"; - // FIXME: this doesn't print wstrings right. - StringRef StrData = Str->getString(); - for (StringRef::iterator I = StrData.begin(), E = StrData.end(); - I != E; ++I) { - unsigned char Char = *I; - - switch (Char) { + for (unsigned I = 0, N = Str->getLength(); I != N; ++I) { + switch (uint32_t Char = Str->getCodeUnit(I)) { default: - if (isprint(Char)) + // FIXME: Is this the best way to print wchar_t? + if (Char > 0xff) { + // char32_t values are <= 0x10ffff. + if (Char > 0xffff) + OS << "\\U00" + << Hex[(Char >> 20) & 15] + << Hex[(Char >> 16) & 15]; + else + OS << "\\u"; + OS << Hex[(Char >> 12) & 15] + << Hex[(Char >> 8) & 15] + << Hex[(Char >> 4) & 15] + << Hex[(Char >> 0) & 15]; + break; + } + if (Char <= 0xff && isprint(Char)) OS << (char)Char; else // Output anything hard as an octal escape. OS << '\\' diff --git a/test/SemaCXX/constexpr-printing.cpp b/test/SemaCXX/constexpr-printing.cpp index cccefca9fa..a648fab42e 100644 --- a/test/SemaCXX/constexpr-printing.cpp +++ b/test/SemaCXX/constexpr-printing.cpp @@ -73,3 +73,17 @@ constexpr int MemPtr(int (MemPtrTest::*a), void (MemPtrTest::*b)(), int &c) { } static_assert(MemPtr(&MemPtrTest::n, &MemPtrTest::f, mpt.*&MemPtrTest::n), ""); // expected-error {{constant expression}} \ expected-note {{in call to 'MemPtr(&MemPtrTest::n, &MemPtrTest::f, mpt.n)'}} + +template<typename CharT> +constexpr CharT get(const CharT *p) { return p[-1]; } // expected-note 5{{}} + +constexpr char c = get("test\0\\\"\t\a\b\234"); // \ + expected-error {{}} expected-note {{"test\000\\\"\t\a\b\234"}} +constexpr char c8 = get(u8"test\0\\\"\t\a\b\234"); // \ + expected-error {{}} expected-note {{u8"test\000\\\"\t\a\b\234"}} +constexpr char16_t c16 = get(u"test\0\\\"\t\a\b\234\u1234"); // \ + expected-error {{}} expected-note {{u"test\000\\\"\t\a\b\234\u1234"}} +constexpr char32_t c32 = get(U"test\0\\\"\t\a\b\234\u1234\U00101234"); // \ + expected-error {{}} expected-note {{U"test\000\\\"\t\a\b\234\u1234\U00101234"}} +constexpr wchar_t wc = get(L"test\0\\\"\t\a\b\234\u1234"); // \ + expected-error {{}} expected-note {{L"test\000\\\"\t\a\b\234\u1234"}} |