hazohelet updated this revision to Diff 545582.
hazohelet added a comment.

Address review comments

- Print the character representation only when the type of the expressions is 
`char` or `char8_t`
- Use `pushEscapedString` in the printing so that we can reuse its escaping 
logic
- Use `escapeCStyle` to escape whitespace characters
- `wchar_t` and `charN_t` are not handled yet


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155610/new/

https://reviews.llvm.org/D155610

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/Diagnostic.h
  clang/lib/Basic/Diagnostic.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/Lexer/cxx1z-trigraphs.cpp
  clang/test/SemaCXX/static-assert-cxx26.cpp
  clang/test/SemaCXX/static-assert.cpp

Index: clang/test/SemaCXX/static-assert.cpp
===================================================================
--- clang/test/SemaCXX/static-assert.cpp
+++ clang/test/SemaCXX/static-assert.cpp
@@ -262,7 +262,19 @@
     return 'c';
   }
   static_assert(getChar() == 'a', ""); // expected-error {{failed}} \
-                                       // expected-note {{evaluates to ''c' == 'a''}}
+                                       // expected-note {{evaluates to ''c' (99) == 'a' (97)'}}
+  static_assert((char)9 == '\x61', ""); // expected-error {{failed}} \
+                                        // expected-note {{evaluates to ''\t' (9) == 'a' (97)'}}
+  static_assert((char)10 == '\0', ""); // expected-error {{failed}} \
+                                       // expected-note {{n' (10) == '\u0000' (0)'}}
+  // The note above is intended to match "evaluates to '\n' (10) == '\u0000' (0)'", but if we write it as it is,
+  // the "\n" cannot be consumed by the diagnostic consumer.
+  static_assert((signed char)10 == (char)-123, ""); // expected-error {{failed}} \
+                                                    // expected-note {{evaluates to '10 == '\x85' (-123)'}}
+  static_assert((char)-4 == (unsigned char)-8, ""); // expected-error {{failed}} \
+                                                    // expected-note {{evaluates to ''\xfc' (-4) == 248'}}
+  static_assert((char)-128 == (char)-123, ""); // expected-error {{failed}} \
+                                               // expected-note {{evaluates to ''\x80' (-128) == '\x85' (-123)'}}
 
   /// Bools are printed as bools.
   constexpr bool invert(bool b) {
Index: clang/test/SemaCXX/static-assert-cxx26.cpp
===================================================================
--- clang/test/SemaCXX/static-assert-cxx26.cpp
+++ clang/test/SemaCXX/static-assert-cxx26.cpp
@@ -289,3 +289,10 @@
 Bad<int> b; // expected-note {{in instantiation}}
 
 }
+
+namespace EscapeInDiagnostic {
+static_assert('\u{9}' == (char)1, ""); // expected-error {{failed}} \
+                                       // expected-note {{evaluates to ''\t' (9) == '\u0001' (1)'}}
+static_assert((char8_t)-128 == (char8_t)-123, ""); // expected-error {{failed}} \
+                                                   // expected-note {{evaluates to ''\x80' (128) == '\x85' (133)'}}
+}
Index: clang/test/Lexer/cxx1z-trigraphs.cpp
===================================================================
--- clang/test/Lexer/cxx1z-trigraphs.cpp
+++ clang/test/Lexer/cxx1z-trigraphs.cpp
@@ -21,7 +21,7 @@
 
 #if !ENABLED_TRIGRAPHS
 // expected-error@11 {{}} expected-warning@11 {{trigraph ignored}}
-// expected-error@13 {{failed}} expected-warning@13 {{trigraph ignored}} expected-note@13 {{evaluates to ''?' == '#''}}
+// expected-error@13 {{failed}} expected-warning@13 {{trigraph ignored}} expected-note@13 {{evaluates to ''?' (63) == '#' (35)'}}
 // expected-error@16 {{}}
 // expected-error@20 {{}}
 #else
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -16817,13 +16817,31 @@
              "Bool type, but value is not 0 or 1");
       llvm::raw_svector_ostream OS(Str);
       OS << (BoolValue ? "true" : "false");
-    } else if (T->isCharType()) {
+    } else {
       // Same is true for chars.
-      Str.push_back('\'');
-      Str.push_back(V.getInt().getExtValue());
-      Str.push_back('\'');
-    } else
-      V.getInt().toString(Str);
+      // We want to print the character representation for `char` type
+      // and need to escape it if it is not printable.
+      const auto *BTy = T->getAs<BuiltinType>();
+      if (BTy && (BTy->getKind() == BuiltinType::Char_S ||
+                  BTy->getKind() == BuiltinType::Char_U ||
+                  BTy->getKind() == BuiltinType::Char8)) {
+        llvm::raw_svector_ostream OS(Str);
+        int64_t CharVal = V.getInt().getExtValue();
+        Str.push_back('\'');
+        StringRef Escaped = escapeCStyle<EscapeChar::Single>(CharVal);
+        if (!Escaped.empty()) {
+          OS << Escaped;
+        } else {
+          const char CharArr[] = {static_cast<char>(CharVal)};
+          pushEscapedString(StringRef(CharArr, sizeof(CharArr)), Str,
+                            /*UseUCN=*/true);
+        }
+        OS << "' (";
+        V.getInt().toString(Str);
+        OS << ")";
+      } else
+        V.getInt().toString(Str);
+    }
 
     break;
 
Index: clang/lib/Basic/Diagnostic.cpp
===================================================================
--- clang/lib/Basic/Diagnostic.cpp
+++ clang/lib/Basic/Diagnostic.cpp
@@ -802,7 +802,8 @@
 
 /// pushEscapedString - Append Str to the diagnostic buffer,
 /// escaping non-printable characters and ill-formed code unit sequences.
-static void pushEscapedString(StringRef Str, SmallVectorImpl<char> &OutStr) {
+void clang::pushEscapedString(StringRef Str, SmallVectorImpl<char> &OutStr,
+                              bool UseUCN) {
   OutStr.reserve(OutStr.size() + Str.size());
   auto *Begin = reinterpret_cast<const unsigned char *>(Str.data());
   llvm::raw_svector_ostream OutStream(OutStr);
@@ -834,12 +835,27 @@
         continue;
       }
       // Unprintable code point.
-      OutStream << "<U+" << llvm::format_hex_no_prefix(CodepointValue, 4, true)
-                << ">";
+      if (UseUCN)
+        OutStream << "\\u"
+                  << llvm::format_hex_no_prefix(CodepointValue, /*Width=*/4,
+                                                /*Upper=*/false);
+      else
+        OutStream << "<U+"
+                  << llvm::format_hex_no_prefix(CodepointValue, /*Width=*/4,
+                                                /*Upper=*/true)
+                  << ">";
       continue;
     }
     // Invalid code unit.
-    OutStream << "<" << llvm::format_hex_no_prefix(*Begin, 2, true) << ">";
+    if (UseUCN)
+      OutStream << "\\x"
+                << llvm::format_hex_no_prefix(*Begin, /*Width=*/2,
+                                              /*Upper=*/false);
+    else
+      OutStream << "<"
+                << llvm::format_hex_no_prefix(*Begin, /*Width=*/2,
+                                              /*Upper=*/true)
+                << ">";
     ++Begin;
   }
 }
Index: clang/include/clang/Basic/Diagnostic.h
===================================================================
--- clang/include/clang/Basic/Diagnostic.h
+++ clang/include/clang/Basic/Diagnostic.h
@@ -1841,6 +1841,10 @@
                            const DiagnosticOptions &Opts,
                            bool ReportDiags = true);
 
+/// pushEscapedString - Append Str to the diagnostic buffer,
+/// escaping non-printable characters and ill-formed code unit sequences.
+void pushEscapedString(StringRef Str, SmallVectorImpl<char> &OutStr,
+                       bool UseUCN = false);
 } // namespace clang
 
 #endif // LLVM_CLANG_BASIC_DIAGNOSTIC_H
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -97,6 +97,9 @@
 -----------------------------------
 - Clang constexpr evaluator now prints template arguments when displaying
   template-specialization function calls.
+- When describing the failure of static assertion, clang prints the integer representation
+  of the value as well as its character representation when the user-provided expression
+  is of character type. Also, clang escapes the character representation if it is non-printable.
 
 Bug Fixes in This Version
 -------------------------
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to