Will make the change for if () and *. In the beginning of the function I had 
forgot to remove "return false;"  added for debugging please ignore that line.

------- Original Message -------
Sender : David Majnemer<[email protected]>
Date : Oct 17, 2013 11:07 (GMT+05:30)
Title : Re: [PATCH] Template argument deduction gcc testsuite test case 
sfinae-dr657.C

On Wed, Oct 16, 2013 at 10:10 PM, SENTHIL KUMAR THANGAVELU 
<[email protected]> wrote:

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;



 You seem to have an extra '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



Some quick things: please stick * on the right hand side and spaces between 
'if' and '('


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





Regards
Senthil Kumar




Regards
Senthil Kumar

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

Reply via email to