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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits