r203741 - PR18275: If a member function of a class template is declared with a

Richard Smith richard-llvm at metafoo.co.uk
Wed Mar 12 17:28:45 PDT 2014


Author: rsmith
Date: Wed Mar 12 19:28:45 2014
New Revision: 203741

URL: http://llvm.org/viewvc/llvm-project?rev=203741&view=rev
Log:
PR18275: If a member function of a class template is declared with a
const-qualified parameter type and the defined with a non-const-qualified
parameter type, the parameter is not const inside its body. Ensure that
the type we use when instantiating the body is the right one. Patch by
suyog sarda!

This is still rather unsatisfactory; it seems like it might be better to
instantiate at least the function parameters, and maybe the complete function
declaration, when we instantiate the definition for such a member function
(instead of reusing the declaration from inside the instantiated class
definition).

Modified:
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=203741&r1=203740&r2=203741&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Mar 12 19:28:45 2014
@@ -2991,6 +2991,14 @@ static void addInstantiatedParametersToS
       // Simple case: not a parameter pack.
       assert(FParamIdx < Function->getNumParams());
       ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx);
+      // If the parameter's type is not dependent, update it to match the type
+      // in the pattern. They can differ in top-level cv-qualifiers, and we want
+      // the pattern's type here. If the type is dependent, they can't differ,
+      // per core issue 1668.
+      // FIXME: Updating the type to work around this is at best fragile.
+      if (!PatternDecl->getType()->isDependentType())
+        FunctionParam->setType(PatternParam->getType());
+
       FunctionParam->setDeclName(PatternParam->getDeclName());
       Scope.InstantiatedLocal(PatternParam, FunctionParam);
       ++FParamIdx;
@@ -3005,6 +3013,9 @@ static void addInstantiatedParametersToS
            "should only be called when all template arguments are known");
     for (unsigned Arg = 0; Arg < *NumArgumentsInExpansion; ++Arg) {
       ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx);
+      if (!PatternDecl->getType()->isDependentType())
+        FunctionParam->setType(PatternParam->getType());
+
       FunctionParam->setDeclName(PatternParam->getDeclName());
       Scope.InstantiatedLocalPackArg(PatternParam, FunctionParam);
       ++FParamIdx;

Modified: cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp?rev=203741&r1=203740&r2=203741&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp (original)
+++ cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp Wed Mar 12 19:28:45 2014
@@ -98,3 +98,27 @@ namespace PR7460 {
   template <typename T>
   T TemplateClass2<T>::member[TemplateClass2<T>::SIZE];
 }
+
+namespace PR18275 {
+  template<typename T> struct A {
+    void f(const int);
+    void g(int);
+    void h(const T);
+    void i(T);
+  };
+
+  template<typename T>
+  void A<T>::f(int x) { x = 0; }
+
+  template<typename T>
+  void A<T>::g(const int x) { x = 0; } // expected-error {{not assignable}}
+
+  template<typename T>
+  void A<T>::h(T) {} // FIXME: Should reject this. Type is different from prior decl if T is an array type.
+
+  template<typename T>
+  void A<T>::i(const T) {} // FIXME: Should reject this. Type is different from prior decl if T is an array type.
+
+  template struct A<int>;
+  template struct A<int[1]>;
+}





More information about the cfe-commits mailing list