diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index 4f677b60e60d..7b873ee9833b 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -1899,11 +1899,17 @@ class TemplateDiff { E = E->IgnoreImpCasts(); - if (isa(E)) return false; + auto CheckIntegerLiteral = [](Expr *E) { + if (auto *TemplateExpr = dyn_cast(E)) + E = TemplateExpr->getReplacement(); + return isa(E); + }; + + if (CheckIntegerLiteral(E)) return false; if (UnaryOperator *UO = dyn_cast(E)) if (UO->getOpcode() == UO_Minus) - if (isa(UO->getSubExpr())) + if (CheckIntegerLiteral(UO->getSubExpr())) return false; if (isa(E)) diff --git a/clang/test/Misc/diag-template-diffing-cxx98.cpp b/clang/test/Misc/diag-template-diffing-cxx98.cpp index 7b1a08c6b869..888b9f8b0e5e 100644 --- a/clang/test/Misc/diag-template-diffing-cxx98.cpp +++ b/clang/test/Misc/diag-template-diffing-cxx98.cpp @@ -47,3 +47,35 @@ namespace qualifiers { // CHECK: candidate template ignored: deduced conflicting types for parameter 'T' ('const vector<...>' vs. 'volatile vector<...>') } + +namespace integers { + template + class wrapper{}; + + template + class foo { + public: + wrapper make(); + }; + + wrapper<1> w1 = foo<2>().make(); + // CHECK: no viable conversion from 'wrapper<2>' to 'wrapper<1>' + + wrapper<1> w2 = foo<-3>().make(); + // CHECK: no viable conversion from 'wrapper<-3>' to 'wrapper<1>' + + template + wrapper make(); + + wrapper<1> w3 = make<4>(); + // CHECK: no viable conversion from 'wrapper<4>' to 'wrapper<1>' + + template + wrapper<-x> makeNegative(); + + wrapper<1> w4 = makeNegative<5>(); + // CHECK: no viable conversion from 'wrapper<-5>' to 'wrapper<1>' + + wrapper<1> w5 = makeNegative<-6>(); + // CHECK: no viable conversion from 'wrapper<6>' to 'wrapper<1>' +}