Skip to content

Commit e08c165

Browse files
HighCommander4tru
authored andcommitted
[clangd] Avoid crash when printing call to string literal operator template
Differential Revision: https://reviews.llvm.org/D132830 (cherry picked from commit 898c421)
1 parent 2eba4dd commit e08c165

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

clang/lib/AST/StmtPrinter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1993,7 +1993,7 @@ void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {
19931993
cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs();
19941994
assert(Args);
19951995

1996-
if (Args->size() != 1) {
1996+
if (Args->size() != 1 || Args->get(0).getKind() != TemplateArgument::Pack) {
19971997
const TemplateParameterList *TPL = nullptr;
19981998
if (!DRE->hadMultipleCandidates())
19991999
if (const auto *TD = dyn_cast<TemplateDecl>(DRE->getDecl()))

clang/unittests/AST/StmtPrinterTest.cpp

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ using namespace tooling;
3131

3232
namespace {
3333

34-
enum class StdVer { CXX98, CXX11, CXX14, CXX17, CXX2a };
34+
enum class StdVer { CXX98, CXX11, CXX14, CXX17, CXX20 };
3535

3636
DeclarationMatcher FunctionBodyMatcher(StringRef ContainingFunction) {
3737
return functionDecl(hasName(ContainingFunction),
@@ -67,7 +67,9 @@ PrintedStmtCXXMatches(StdVer Standard, StringRef Code, const T &NodeMatch,
6767
case StdVer::CXX11: StdOpt = "-std=c++11"; break;
6868
case StdVer::CXX14: StdOpt = "-std=c++14"; break;
6969
case StdVer::CXX17: StdOpt = "-std=c++17"; break;
70-
case StdVer::CXX2a: StdOpt = "-std=c++2a"; break;
70+
case StdVer::CXX20:
71+
StdOpt = "-std=c++20";
72+
break;
7173
}
7274

7375
std::vector<std::string> Args = {
@@ -146,6 +148,35 @@ TEST(StmtPrinter, TestFloatingPointLiteral) {
146148
// Should be: with semicolon
147149
}
148150

151+
TEST(StmtPrinter, TestStringLiteralOperatorTemplate_Pack) {
152+
ASSERT_TRUE(PrintedStmtCXXMatches(StdVer::CXX11,
153+
R"cpp(
154+
template <char...> constexpr double operator""_c() { return 42; }
155+
void A() {
156+
constexpr auto waldo = 42_c;
157+
}
158+
)cpp",
159+
FunctionBodyMatcher("A"),
160+
"constexpr auto waldo = 42_c;\n"));
161+
}
162+
163+
TEST(StmtPrinter, TestStringLiteralOperatorTemplate_Class) {
164+
ASSERT_TRUE(
165+
PrintedStmtCXXMatches(StdVer::CXX20,
166+
R"cpp(
167+
struct C {
168+
template <unsigned N> constexpr C(const char (&)[N]) : n(N) {}
169+
unsigned n;
170+
};
171+
template <C c> constexpr auto operator""_c() { return c.n; }
172+
void A() {
173+
constexpr auto waldo = "abc"_c;
174+
}
175+
)cpp",
176+
FunctionBodyMatcher("A"),
177+
"constexpr auto waldo = operator\"\"_c<{4}>();\n"));
178+
}
179+
149180
TEST(StmtPrinter, TestCXXConversionDeclImplicit) {
150181
ASSERT_TRUE(PrintedStmtCXXMatches(
151182
StdVer::CXX98,

0 commit comments

Comments
 (0)