From 877761c56d850a6cc5f9246bf248c8a4dc2b0554 Mon Sep 17 00:00:00 2001 From: Richard Trieu Date: Wed, 30 Jan 2013 20:04:31 +0000 Subject: [PATCH] Handle passing non-Qualtypes to %diff better. Instead of asserting, fall back to printing the default case. This is a fix for PR15023. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173965 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Basic/Diagnostic.cpp | 28 +++++++++++++++++++++++----- test/Misc/diag-template-diffing.cpp | 15 +++++++++++++++ 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp index f8e2148140..1c8b3728c1 100644 --- a/lib/Basic/Diagnostic.cpp +++ b/lib/Basic/Diagnostic.cpp @@ -726,15 +726,33 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, unsigned ArgNo2 = ArgNo; DiagnosticsEngine::ArgumentKind Kind = getArgKind(ArgNo); - if (Kind == DiagnosticsEngine::ak_qualtype && - ModifierIs(Modifier, ModifierLen, "diff")) { - Kind = DiagnosticsEngine::ak_qualtype_pair; + if (ModifierIs(Modifier, ModifierLen, "diff")) { assert(*DiagStr == ',' && isdigit(*(DiagStr + 1)) && "Invalid format for diff modifier"); ++DiagStr; // Comma. ArgNo2 = *DiagStr++ - '0'; - assert(getArgKind(ArgNo2) == DiagnosticsEngine::ak_qualtype && - "Second value of type diff must be a qualtype"); + DiagnosticsEngine::ArgumentKind Kind2 = getArgKind(ArgNo2); + if (Kind == DiagnosticsEngine::ak_qualtype && + Kind2 == DiagnosticsEngine::ak_qualtype) + Kind = DiagnosticsEngine::ak_qualtype_pair; + else { + // %diff only supports QualTypes. For other kinds of arguments, + // use the default printing. For example, if the modifier is: + // "%diff{compare $ to $|other text}1,2" + // treat it as: + // "compare %1 to %2" + const char *Pipe = ScanFormat(Argument, Argument + ArgumentLen, '|'); + const char *FirstDollar = ScanFormat(Argument, Pipe, '$'); + const char *SecondDollar = ScanFormat(FirstDollar + 1, Pipe, '$'); + const char ArgStr1[] = { '%', '0' + ArgNo }; + const char ArgStr2[] = { '%', '0' + ArgNo2 }; + FormatDiagnostic(Argument, FirstDollar, OutStr); + FormatDiagnostic(ArgStr1, ArgStr1 + 2, OutStr); + FormatDiagnostic(FirstDollar + 1, SecondDollar, OutStr); + FormatDiagnostic(ArgStr2, ArgStr2 + 2, OutStr); + FormatDiagnostic(SecondDollar + 1, Pipe, OutStr); + continue; + } } switch (Kind) { diff --git a/test/Misc/diag-template-diffing.cpp b/test/Misc/diag-template-diffing.cpp index bb85a45d5d..c158255f80 100644 --- a/test/Misc/diag-template-diffing.cpp +++ b/test/Misc/diag-template-diffing.cpp @@ -830,6 +830,21 @@ namespace rdar12456626 { }; } +namespace PR15023 { + // Don't crash when non-QualTypes are passed to a diff modifier. + template + void func(void (*func)(Args...), Args...) { } + + void bar(int, int &) { + } + + void foo(int x) { + func(bar, 1, x) + } + // CHECK-ELIDE-NOTREE: no matching function for call to 'func' + // CHECK-ELIDE-NOTREE: candidate template ignored: deduced conflicting types for parameter 'Args' ( vs. ) +} + // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated. // CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated. // CHECK-ELIDE-TREE: {{[0-9]*}} errors generated. -- 2.40.0