]> granicus.if.org Git - clang/commitdiff
When performing template argument deduction given a function argument
authorDouglas Gregor <dgregor@apple.com>
Fri, 3 Jun 2011 03:35:07 +0000 (03:35 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 3 Jun 2011 03:35:07 +0000 (03:35 +0000)
of incomplete array type, attempt to complete the array type. This was
made much easier by Chandler's addition of RequireCompleteExprType(),
which I've tweaked (slightly) to improve the consistency of the
DeclRefExpr. Fixes PR7985.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@132530 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplateDeduction.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
lib/Sema/SemaType.cpp
test/SemaTemplate/instantiate-init.cpp

index ed1b671bf4a32410e5dac967e17f4bcd1540172a..7d0ce8b2e71d0d97c24d2a466f13d1a754593f74 100644 (file)
@@ -2500,6 +2500,12 @@ static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S,
   if (ParamRefType) {
     QualType PointeeType = ParamRefType->getPointeeType();
 
+    // If the argument has incomplete array type, try to complete it's type.
+    if (ArgType->isIncompleteArrayType() &&
+        !S.RequireCompleteExprType(Arg, S.PDiag(), 
+                                   std::make_pair(SourceLocation(), S.PDiag())))
+      ArgType = Arg->getType();
+
     //   [C++0x] If P is an rvalue reference to a cv-unqualified
     //   template parameter and the argument is an lvalue, the type
     //   "lvalue reference to A" is used in place of A for type
index cd08b1e3df047bd7b171a7069ccfec7f263af50d..22db4c8f61d4740976f058d10b698a9f08d908df 100644 (file)
@@ -2555,6 +2555,10 @@ void Sema::InstantiateStaticDataMemberDefinition(
         == TSK_ExplicitInstantiationDeclaration)
     return;
 
+  // If we already have a definition, we're done.
+  if (Var->getDefinition())
+    return;
+
   InstantiatingTemplate Inst(*this, PointOfInstantiation, Var);
   if (Inst)
     return;
index 9fccdb11c589a908111445c27bdf8723311beda8..02bcb2b89e1583e1b7a07377480dc8643f782477 100644 (file)
@@ -3280,9 +3280,13 @@ bool Sema::RequireCompleteExprType(Expr *E, const PartialDiagnostic &PD,
           InstantiateStaticDataMemberDefinition(E->getExprLoc(), Var);
           // Update the type to the newly instantiated definition's type both
           // here and within the expression.
-          T = Var->getDefinition()->getType();
-          E->setType(T);
-
+          if (VarDecl *Def = Var->getDefinition()) {
+            DRE->setDecl(Def);
+            T = Def->getType();
+            DRE->setType(T);
+            E->setType(T);
+          }
+          
           // We still go on to try to complete the type independently, as it
           // may also require instantiations or diagnostics if it remains
           // incomplete.
index d5711ddf5a2f01b9c704e7886c76a3b0b22e2454..ce2c1633b141f24c514b07ed15437385e299cfec 100644 (file)
@@ -73,3 +73,26 @@ namespace PR10001 {
 
   int x = S<int>::f();
 }
+
+namespace PR7985 {
+  template<int N> struct integral_c { };
+
+  template <typename T, int N>
+  integral_c<N> array_lengthof(T (&x)[N]) { return integral_c<N>(); }
+
+  struct Data {
+    int x;
+  };
+
+  template<typename T>
+  struct Description {
+    static const Data data[];
+  };
+
+  template<typename T>
+  const Data Description<T>::data[] = {{ 0 }};
+
+  void test() {
+    integral_c<1> ic1 = array_lengthof(Description<int>::data);
+  }
+}