diff options
author | Erich Keane <erich.keane@intel.com> | 2017-06-20 17:38:07 +0000 |
---|---|---|
committer | Erich Keane <erich.keane@intel.com> | 2017-06-20 17:38:07 +0000 |
commit | c35b73c765d276f2433f2f89229022e5f08b003c (patch) | |
tree | 9abde6dfde542bb63721d996cc1172c762144795 /lib/Sema/SemaLookup.cpp | |
parent | f5f37badaf42c9f95d12cedd7d097cf7673c8817 (diff) |
Fix for Bug 33471: Preventing operator auto from resolving to a template operator.
As the bug report says,
struct A
{
template<typename T> operator T();
};
void foo()
{
A().operator auto();
}
causes: "undeduced type in IR-generation
UNREACHABLE executed at llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp:208!"
The problem is that in this case, "T" is being deduced as "auto",
which I believe is incorrect.
The 'operator auto' implementation in Clang is standards compliant, however
there is a defect report against core (1670).
Differential Revision: https://reviews.llvm.org/D34370
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@305812 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaLookup.cpp')
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 1fb25f4e0e..9f657a446c 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -862,6 +862,16 @@ static bool LookupDirect(Sema &S, LookupResult &R, const DeclContext *DC) { if (!Record->isCompleteDefinition()) return Found; + // For conversion operators, 'operator auto' should only match + // 'operator auto'. Since 'auto' is not a type, it shouldn't be considered + // as a candidate for template substitution. + auto *ContainedDeducedType = + R.getLookupName().getCXXNameType()->getContainedDeducedType(); + if (R.getLookupName().getNameKind() == + DeclarationName::CXXConversionFunctionName && + ContainedDeducedType && ContainedDeducedType->isUndeducedType()) + return Found; + for (CXXRecordDecl::conversion_iterator U = Record->conversion_begin(), UEnd = Record->conversion_end(); U != UEnd; ++U) { FunctionTemplateDecl *ConvTemplate = dyn_cast<FunctionTemplateDecl>(*U); |