Resending mail in txt format.

------- Original Message -------
Sender : SENTHIL KUMAR THANGAVELU<[email protected]> ./Senior Technical 
Manager/SRI-Bangalore-Native Framework/Samsung Electronics
Date : Oct 16, 2013 19:38 (GMT+05:30)
Title : [PATCH] Template argument deduction gcc testsuite test case 
sfinae-dr657.C

Hello all,
    Found a test case sfinae-dr657.C in gcc 4.8.1 testsuite. This is related to 
c++ standard section "14.8.2 Template argument deduction" which states type 
deduction may fail for "Attempting to create a function type in which a 
parameter type or the return type is an abstract class type". This is a DR in 
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3027.html section 
"657. Abstract class parameter in synthesized declaration"

Following test case should compile with -c option as per test case. With gcc 
4.8.1 and intel  x64 compiler 13.1.3 this test case is accepted for compilation 
whereas clang throws "call to 'declval' is ambiguous" error during compilation. 
Problem seems to be call candidate which ends up returning abstract type is 
considered instead of being rejected. As per test case abstract type returning 
call should result in deduction failure and only elipsis version should be 
considered for call candidate list.

test case sfinae-dr657.C
// DR 657
// Test that a return or parameter type with abstract class type causes a
// deduction failure.
struct A
{
  A();
  virtual void f() = 0;
};
template<class T> T declval();
template<class T> int declval(...);
int main()
{
  int i = declval<A>();
}

I have added a patch for the issue as follows based on 3.3 base code. This 
patch works and passed LLVM regression. I am looking for comments on the patch. 
Based on comments I will rework the patch and send it.

--- /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) { return false;
+  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;



Regards
Senthil Kumar

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to