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