r338438 - [serialization] PR34728: Don't assume that only a suffix of template
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 31 14:01:53 PDT 2018
Author: rsmith
Date: Tue Jul 31 14:01:53 2018
New Revision: 338438
URL: http://llvm.org/viewvc/llvm-project?rev=338438&view=rev
Log:
[serialization] PR34728: Don't assume that only a suffix of template
parameters can have default arguments.
At least for function templates and class template partial
specializations, it's possible for a template parameter with a default
argument to be followed by a non-pack template parameter with no default
argument, and this case was not properly handled here.
Testcase by Steve O'Brien!
Modified:
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
cfe/trunk/test/PCH/cxx-templates.cpp
cfe/trunk/test/PCH/cxx-templates.h
Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=338438&r1=338437&r2=338438&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Tue Jul 31 14:01:53 2018
@@ -3439,22 +3439,16 @@ static void inheritDefaultTemplateArgume
assert(FromTP->size() == ToTP->size() && "merged mismatched templates?");
for (unsigned I = 0, N = FromTP->size(); I != N; ++I) {
- NamedDecl *FromParam = FromTP->getParam(N - I - 1);
- if (FromParam->isParameterPack())
- continue;
- NamedDecl *ToParam = ToTP->getParam(N - I - 1);
+ NamedDecl *FromParam = FromTP->getParam(I);
+ NamedDecl *ToParam = ToTP->getParam(I);
- if (auto *FTTP = dyn_cast<TemplateTypeParmDecl>(FromParam)) {
- if (!inheritDefaultTemplateArgument(Context, FTTP, ToParam))
- break;
- } else if (auto *FNTTP = dyn_cast<NonTypeTemplateParmDecl>(FromParam)) {
- if (!inheritDefaultTemplateArgument(Context, FNTTP, ToParam))
- break;
- } else {
- if (!inheritDefaultTemplateArgument(
- Context, cast<TemplateTemplateParmDecl>(FromParam), ToParam))
- break;
- }
+ if (auto *FTTP = dyn_cast<TemplateTypeParmDecl>(FromParam))
+ inheritDefaultTemplateArgument(Context, FTTP, ToParam);
+ else if (auto *FNTTP = dyn_cast<NonTypeTemplateParmDecl>(FromParam))
+ inheritDefaultTemplateArgument(Context, FNTTP, ToParam);
+ else
+ inheritDefaultTemplateArgument(
+ Context, cast<TemplateTemplateParmDecl>(FromParam), ToParam);
}
}
Modified: cfe/trunk/test/PCH/cxx-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-templates.cpp?rev=338438&r1=338437&r2=338438&view=diff
==============================================================================
--- cfe/trunk/test/PCH/cxx-templates.cpp (original)
+++ cfe/trunk/test/PCH/cxx-templates.cpp Tue Jul 31 14:01:53 2018
@@ -116,3 +116,19 @@ namespace MemberSpecializationLocation {
#endif
int k = A<int>::n;
}
+
+// https://bugs.llvm.org/show_bug.cgi?id=34728
+namespace PR34728 {
+int test() {
+ // Verify with several TemplateParmDecl kinds, using PCH (incl. modules).
+ int z1 = func1(/*ignored*/2.718);
+ int z2 = func2(/*ignored*/3.142);
+ int tmp3 = 30;
+ Container<int> c = func3(tmp3);
+ int z3 = c.item;
+
+ // Return value is meaningless. Just "use" all these values to avoid
+ // warning about unused vars / values.
+ return z1 + z2 + z3;
+}
+} // end namespace PR34728
Modified: cfe/trunk/test/PCH/cxx-templates.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-templates.h?rev=338438&r1=338437&r2=338438&view=diff
==============================================================================
--- cfe/trunk/test/PCH/cxx-templates.h (original)
+++ cfe/trunk/test/PCH/cxx-templates.h Tue Jul 31 14:01:53 2018
@@ -361,3 +361,38 @@ namespace rdar15468709c {
namespace MemberSpecializationLocation {
template<typename T> struct A { static int n; };
}
+
+// https://bugs.llvm.org/show_bug.cgi?id=34728
+namespace PR34728 {
+
+// case 1: defaulted `NonTypeTemplateParmDecl`, non-defaulted 2nd tpl param
+template <int foo = 10, class T>
+int func1(T const &);
+
+template <int foo, class T>
+int func1(T const &) {
+ return foo;
+}
+
+// case 2: defaulted `TemplateTypeParmDecl`, non-defaulted 2nd tpl param
+template <class A = int, class B>
+A func2(B const &);
+
+template <class A, class B>
+A func2(B const &) {
+ return A(20.0f);
+}
+
+// case 3: defaulted `TemplateTemplateParmDecl`, non-defaulted 2nd tpl param
+template <class T>
+struct Container { T const &item; };
+
+template <template <class> class C = Container, class D>
+C<D> func3(D const &);
+
+template <template <class> class C, class D>
+C<D> func3(D const &d) {
+ return Container<D>{d};
+}
+
+} // end namespace PR34728
More information about the cfe-commits
mailing list