When substituting into a sizeof parameter pack expression in a context
where we can't expand (i.e., multi-level substitution), be sure to
substitute the pack with its level-reduced pack. Fixes PR10230.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141568 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 33aaf92..2a18afa 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -2140,10 +2140,15 @@
   ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack, 
                                    SourceLocation PackLoc, 
                                    SourceLocation RParenLoc,
-                                   unsigned Length) {
+                                   llvm::Optional<unsigned> Length) {
+    if (Length)
+      return new (SemaRef.Context) SizeOfPackExpr(SemaRef.Context.getSizeType(), 
+                                                  OperatorLoc, Pack, PackLoc, 
+                                                  RParenLoc, *Length);
+    
     return new (SemaRef.Context) SizeOfPackExpr(SemaRef.Context.getSizeType(), 
                                                 OperatorLoc, Pack, PackLoc, 
-                                                RParenLoc, Length);
+                                                RParenLoc);
   }
                                    
   /// \brief Build a new Objective-C @encode expression.
@@ -7709,14 +7714,23 @@
                                            NumExpansions))
     return ExprError();
   
-  if (!ShouldExpand || RetainExpansion)
+  if (RetainExpansion)
     return SemaRef.Owned(E);
+    
+  NamedDecl *Pack = E->getPack();
+  if (!ShouldExpand) {
+    Pack = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getPackLoc(), 
+                                                              Pack));
+    if (!Pack)
+      return ExprError();
+  }
+
   
   // We now know the length of the parameter pack, so build a new expression
   // that stores that length.
-  return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(), 
+  return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), Pack, 
                                             E->getPackLoc(), E->getRParenLoc(), 
-                                            *NumExpansions);
+                                            NumExpansions);
 }
 
 template<typename Derived>
diff --git a/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp b/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp
index cda9ac8..22076fe 100644
--- a/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp
+++ b/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp
@@ -234,3 +234,18 @@
     x1.f(17, 3.14159);
   }
 }
+
+namespace PR10230 {
+  template<typename>
+  struct s
+  {
+    template<typename... Args>
+    auto f() -> int(&)[sizeof...(Args)];
+  };
+
+  void main()
+  {
+    int (&ir1)[1] = s<int>().f<int>();
+    int (&ir3)[3] = s<int>().f<int, float, double>();
+  }
+}