]> granicus.if.org Git - clang/commitdiff
Fix a couple of places where we assumed that non-type template parameters are always...
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 14 Feb 2018 02:07:53 +0000 (02:07 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 14 Feb 2018 02:07:53 +0000 (02:07 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@325095 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ExprCXX.h
lib/AST/ExprCXX.cpp
lib/Sema/SemaTemplateInstantiate.cpp
lib/Sema/TreeTransform.h
test/SemaTemplate/nested-template.cpp
test/SemaTemplate/sizeof-pack.cpp [new file with mode: 0644]

index 3fb2c6130f86bff200747cd8df6bf7d477176ce6..e51ffb6d5beea0d800f51f551d447ccebdbf7c47 100644 (file)
@@ -3916,6 +3916,7 @@ class SubstNonTypeTemplateParmPackExpr : public Expr {
 
 public:
   SubstNonTypeTemplateParmPackExpr(QualType T,
+                                   ExprValueKind ValueKind,
                                    NonTypeTemplateParmDecl *Param,
                                    SourceLocation NameLoc,
                                    const TemplateArgument &ArgPack);
index a0d6113811232e0b662a421c210a1d77823858bb..b8a837fe47b409f742b1167debf1a5c393a1fc73 100644 (file)
@@ -1330,10 +1330,11 @@ SizeOfPackExpr *SizeOfPackExpr::CreateDeserialized(ASTContext &Context,
 
 SubstNonTypeTemplateParmPackExpr::
 SubstNonTypeTemplateParmPackExpr(QualType T, 
+                                 ExprValueKind ValueKind,
                                  NonTypeTemplateParmDecl *Param,
                                  SourceLocation NameLoc,
                                  const TemplateArgument &ArgPack)
-    : Expr(SubstNonTypeTemplateParmPackExprClass, T, VK_RValue, OK_Ordinary,
+    : Expr(SubstNonTypeTemplateParmPackExprClass, T, ValueKind, OK_Ordinary,
            true, true, true, true),
       Param(Param), Arguments(ArgPack.pack_begin()),
       NumArguments(ArgPack.pack_size()), NameLoc(NameLoc) {}
index 489d026027de195020b56d1293fd5df08ff4ce9c..2c4f6490789e52e2afaf6620bfc61047fdcbd922 100644 (file)
@@ -1212,11 +1212,11 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
                                               NTTP->getDeclName());
       if (TargetType.isNull())
         return ExprError();
-      
-      return new (SemaRef.Context) SubstNonTypeTemplateParmPackExpr(TargetType,
-                                                                    NTTP, 
-                                                              E->getLocation(),
-                                                                    Arg);
+
+      return new (SemaRef.Context) SubstNonTypeTemplateParmPackExpr(
+          TargetType.getNonLValueExprType(SemaRef.Context),
+          TargetType->isReferenceType() ? VK_LValue : VK_RValue, NTTP,
+          E->getLocation(), Arg);
     }
     
     Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
index c33a1fc2ecfa514e6bc09acb2a8aed7baa1169ff..7d52394bd7ab4de0be729f83ff2a0664e195a059 100644 (file)
@@ -11392,8 +11392,10 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
         ArgStorage = TemplateArgument(TemplateName(TTPD), None);
       } else {
         auto *VD = cast<ValueDecl>(Pack);
-        ExprResult DRE = getSema().BuildDeclRefExpr(VD, VD->getType(),
-                                                    VK_RValue, E->getPackLoc());
+        ExprResult DRE = getSema().BuildDeclRefExpr(
+            VD, VD->getType().getNonLValueExprType(getSema().Context),
+            VD->getType()->isReferenceType() ? VK_LValue : VK_RValue,
+            E->getPackLoc());
         if (DRE.isInvalid())
           return ExprError();
         ArgStorage = new (getSema().Context) PackExpansionExpr(
index 44cb82e95bbfaa8d00c321ce7fdc2bf623075c8a..efbde2076b9fa1a3135eae09412ab54f51b866be 100644 (file)
@@ -161,3 +161,10 @@ class Outer1 {
     template <typename T> struct X;
     template <typename T> int X<T>::func() {} //  expected-error{{out-of-line definition of 'func' from class 'X<T>' without definition}}
 };
+
+namespace RefPack {
+  template<const int &...N> struct A { template<typename ...T> void f(T (&...t)[N]); };
+  constexpr int k = 10;
+  int arr[10];
+  void g() { A<k>().f(arr); }
+}
diff --git a/test/SemaTemplate/sizeof-pack.cpp b/test/SemaTemplate/sizeof-pack.cpp
new file mode 100644 (file)
index 0000000..4b0c883
--- /dev/null
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+// expected-no-diagnostics
+
+template<int &...Ns> int f() {
+  return sizeof...(Ns);
+}
+template int f<>();