[PATCH] Template argument deduction gcc testsuite test case sfinae-dr657.C

SENTHIL KUMAR THANGAVELU senthil.t at samsung.com
Thu Oct 17 02:12:34 PDT 2013


Made changes as per comment "stick * on the right hand side and spaces between 'if' and '(' "

--- /home/camel/orig/llvm_3.3_src/tools/clang/lib/Sema/SemaOverload.cpp
+++ /home/camel/llvm_3.3_src/tools/clang/lib/Sema/SemaOverload.cpp
@@ -9534,6 +9534,51 @@
   return true;
 }
 
+/// \brief Reject a call candidate if abstract type is returned
+static bool IsRejectAbstractReturningCallCandidate(
+               FunctionTemplateDecl *FuncTemplate,
+               TemplateArgumentListInfo *ExplicitTemplateArgs) {
+  if (!FuncTemplate || !ExplicitTemplateArgs)
+    return false;
+
+  TemplateParameterList *TemplateParams = FuncTemplate->getTemplateParameters();
+  FunctionDecl *FD = FuncTemplate->getTemplatedDecl();
+  if (!FD || !TemplateParams)
+    return false;
+
+  // Check if atleast one of the template param is used as return type
+  const Type *RetType = (FD) ? FD->getResultType().getTypePtr() : 0;
+  unsigned MatchedIdx = 0;
+  bool RetDependsOnTemplateArg = false;
+  for (TemplateParameterList::iterator I = TemplateParams->begin(),
+         E = TemplateParams->end(); I != E ; ++I) {
+    NamedDecl *ND = *I;
+    TemplateTypeParmDecl  *TmpParamDecl = dyn_cast<TemplateTypeParmDecl>(ND);
+    if (TmpParamDecl) {
+      const Type *TemplateParamType = TmpParamDecl->getTypeForDecl();
+      if (TemplateParamType == RetType) {
+        RetDependsOnTemplateArg = true;
+        break;
+      }
+    }
+    MatchedIdx++;
+  }
+
+  if (RetDependsOnTemplateArg) {
+    TemplateArgumentListInfo ArgList = *ExplicitTemplateArgs;
+    if (MatchedIdx >= ArgList.size())
+      return false;
+
+    TemplateArgumentLoc TAL = ArgList[MatchedIdx];
+    CXXRecordDecl *RD =
+      (TAL.getArgument().getKind() == TemplateArgument::Type) ?
+      TAL.getArgument().getAsType().getTypePtr()->getAsCXXRecordDecl() : 0;
+
+    return (RD) ? (RD->getDefinition() && RD->isAbstract()) : false;
+  }
+  return false;
+}
+
 /// \brief Add a single candidate to the overload set.
 static void AddOverloadedCallCandidate(Sema &S,
                                        DeclAccessPair FoundDecl,
@@ -9558,6 +9603,11 @@
 
   if (FunctionTemplateDecl *FuncTemplate
       = dyn_cast<FunctionTemplateDecl>(Callee)) {
+
+    if (IsRejectAbstractReturningCallCandidate(FuncTemplate,
+                                              ExplicitTemplateArgs))
+      return;
+
     S.AddTemplateOverloadCandidate(FuncTemplate, FoundDecl,
                                    ExplicitTemplateArgs, Args, CandidateSet);
     return;




More information about the cfe-commits mailing list