jix created this revision.
jix added a subscriber: cfe-commits.
jix set the repository for this revision to rL LLVM.
Herald added a subscriber: aemerson.

Parameter default values are expected to be attached to all redeclarations of a 
template. During serialization they are serialized only for the first 
redeclaration (probably to save space, see OwnsDefaultArg in 
ASTDeclWriter::VisitNonTypeTemplateParmDecl in ASTWriterDecl.cpp).

During deserialization the default arguments are recovered for all 
redeclartions by static void inheritDefaultTemplateArguments(... in 
ASTReaderDecl.cpp. This function includes the following optimization: As the 
parameters that have default values have to be at the end of the parameter 
list, it inherits them from back to front, stopping at the first parameter 
without a default. This works fine as long as there are no parameter packs, 
which may follow parameters with defaults.

The fix in this patch simply checks for parameter packs and skips them, 
continuing the default value inheritance for the preceding parameters.

Repository:
  rL LLVM

http://reviews.llvm.org/D16148

Files:
  lib/Serialization/ASTReaderDecl.cpp
  test/PCH/cxx-variadic-templates-with-default-params.cpp
  test/PCH/cxx-variadic-templates-with-default-params.h

Index: test/PCH/cxx-variadic-templates-with-default-params.h
===================================================================
--- test/PCH/cxx-variadic-templates-with-default-params.h
+++ test/PCH/cxx-variadic-templates-with-default-params.h
@@ -0,0 +1,8 @@
+// PR25271: Ensure that variadic template parameter defaults PCH roundtrip
+template<unsigned T=123, unsigned... U>
+class dummy;
+
+template<unsigned T, unsigned... U>
+class dummy {
+    int field[T];
+};
Index: test/PCH/cxx-variadic-templates-with-default-params.cpp
===================================================================
--- test/PCH/cxx-variadic-templates-with-default-params.cpp
+++ test/PCH/cxx-variadic-templates-with-default-params.cpp
@@ -0,0 +1,12 @@
+// Test this without pch.
+// RUN: %clang_cc1 -std=c++11 -include 
%S/cxx-variadic-templates-with-default-params.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -std=c++11 -x c++-header -emit-pch -o %t 
%S/cxx-variadic-templates-with-default-params.h
+// RUN: %clang_cc1 -std=c++11 -include-pch %t -fsyntax-only -verify %s
+
+// expected-no-diagnostics
+void f() {
+    dummy<> x;
+    (void)x;
+}
Index: lib/Serialization/ASTReaderDecl.cpp
===================================================================
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -3000,6 +3000,8 @@
 
   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);
 
     if (auto *FTTP = dyn_cast<TemplateTypeParmDecl>(FromParam)) {


Index: test/PCH/cxx-variadic-templates-with-default-params.h
===================================================================
--- test/PCH/cxx-variadic-templates-with-default-params.h
+++ test/PCH/cxx-variadic-templates-with-default-params.h
@@ -0,0 +1,8 @@
+// PR25271: Ensure that variadic template parameter defaults PCH roundtrip
+template<unsigned T=123, unsigned... U>
+class dummy;
+
+template<unsigned T, unsigned... U>
+class dummy {
+    int field[T];
+};
Index: test/PCH/cxx-variadic-templates-with-default-params.cpp
===================================================================
--- test/PCH/cxx-variadic-templates-with-default-params.cpp
+++ test/PCH/cxx-variadic-templates-with-default-params.cpp
@@ -0,0 +1,12 @@
+// Test this without pch.
+// RUN: %clang_cc1 -std=c++11 -include %S/cxx-variadic-templates-with-default-params.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -std=c++11 -x c++-header -emit-pch -o %t %S/cxx-variadic-templates-with-default-params.h
+// RUN: %clang_cc1 -std=c++11 -include-pch %t -fsyntax-only -verify %s
+
+// expected-no-diagnostics
+void f() {
+    dummy<> x;
+    (void)x;
+}
Index: lib/Serialization/ASTReaderDecl.cpp
===================================================================
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -3000,6 +3000,8 @@
 
   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);
 
     if (auto *FTTP = dyn_cast<TemplateTypeParmDecl>(FromParam)) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to