]> granicus.if.org Git - clang/commitdiff
When substituting into a sizeof parameter pack expression in a context
authorDouglas Gregor <dgregor@apple.com>
Mon, 10 Oct 2011 18:59:29 +0000 (18:59 +0000)
committerDouglas Gregor <dgregor@apple.com>
Mon, 10 Oct 2011 18:59:29 +0000 (18:59 +0000)
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

lib/Sema/TreeTransform.h
test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp

index 33aaf92d813b749af245aeaff6f2a6a25e8d6a61..2a18afafd9bc62abc9b65ea7ba453ad532668ad4 100644 (file)
@@ -2140,10 +2140,15 @@ public:
   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 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
                                            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>
index cda9ac8b045c5c5fe6a52e7cbb481397bcf60b47..22076fee989adebe62ae5700435ea7740bad7558 100644 (file)
@@ -234,3 +234,18 @@ namespace ExpandingFunctionParameters {
     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>();
+  }
+}