]> granicus.if.org Git - clang/commitdiff
Fix crash when trying to pretty-print unicode or wide string literals.
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 30 Dec 2011 23:37:31 +0000 (23:37 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 30 Dec 2011 23:37:31 +0000 (23:37 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147385 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/StmtPrinter.cpp
test/SemaCXX/constexpr-printing.cpp

index 6d9139c000af4fc038ddc10cc17bbf907041720a..6408c879fa20fee54941a92413cd8fb95674e6f8 100644 (file)
@@ -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 << '\\'
index cccefca9fa02f1118f6e196b0f4aaa442ec0d61b..a648fab42e368b0318af765852bc10d94a90348d 100644 (file)
@@ -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"}}