From: Erich Keane Date: Tue, 20 Jun 2017 17:38:07 +0000 (+0000) Subject: Fix for Bug 33471: Preventing operator auto from resolving to a template operator. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c35b73c765d276f2433f2f89229022e5f08b003c;p=clang Fix for Bug 33471: Preventing operator auto from resolving to a template operator. As the bug report says, struct A { template 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 --- 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(*U); diff --git a/test/SemaCXX/cxx1y-deduced-return-type.cpp b/test/SemaCXX/cxx1y-deduced-return-type.cpp index bfe0ab9dcd..13ff751aca 100644 --- a/test/SemaCXX/cxx1y-deduced-return-type.cpp +++ b/test/SemaCXX/cxx1y-deduced-return-type.cpp @@ -55,6 +55,25 @@ auto b(bool k) { return "goodbye"; } +// Allow 'operator auto' to call only the explicit operator auto. +struct BothOps { + template operator T(); + template operator T *(); + operator auto() { return 0; } + operator auto *() { return this; } +}; +struct JustTemplateOp { + template operator T(); + template operator T *(); +}; + +auto c() { + BothOps().operator auto(); // ok + BothOps().operator auto *(); // ok + JustTemplateOp().operator auto(); // expected-error {{no member named 'operator auto' in 'JustTemplateOp'}} + JustTemplateOp().operator auto *(); // expected-error {{no member named 'operator auto *' in 'JustTemplateOp'}} +} + auto *ptr_1() { return 100; // expected-error {{cannot deduce return type 'auto *' from returned value of type 'int'}} }