erichkeane updated this revision to Diff 103224. erichkeane marked an inline comment as done. erichkeane added a comment.
Hi @rsmith Thanks for the quick response! I spent a while going over it, and think I have what you were looking for. I Also added the operator auto * tests. https://reviews.llvm.org/D34370 Files: lib/Sema/SemaLookup.cpp test/SemaCXX/cxx1y-deduced-return-type.cpp Index: test/SemaCXX/cxx1y-deduced-return-type.cpp =================================================================== --- test/SemaCXX/cxx1y-deduced-return-type.cpp +++ test/SemaCXX/cxx1y-deduced-return-type.cpp @@ -55,6 +55,25 @@ return "goodbye"; } +// Allow 'operator auto' to call only the explicit operator auto. +struct BothOps { + template <typename T> operator T(); + template <typename T> operator T *(); + operator auto() { return 0; } + operator auto *() { return this; } +}; +struct JustTemplateOp { + template <typename T> operator T(); + template <typename T> 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'}} } Index: lib/Sema/SemaLookup.cpp =================================================================== --- lib/Sema/SemaLookup.cpp +++ lib/Sema/SemaLookup.cpp @@ -862,6 +862,19 @@ 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. + if (R.getLookupName().getNameKind() == + DeclarationName::CXXConversionFunctionName && + R.getLookupName().getCXXNameType()->getContainedDeducedType() && + R.getLookupName() + .getCXXNameType() + ->getContainedDeducedType() + ->isUndeducedType()) { + return Found; + } + for (CXXRecordDecl::conversion_iterator U = Record->conversion_begin(), UEnd = Record->conversion_end(); U != UEnd; ++U) { FunctionTemplateDecl *ConvTemplate = dyn_cast<FunctionTemplateDecl>(*U);
Index: test/SemaCXX/cxx1y-deduced-return-type.cpp =================================================================== --- test/SemaCXX/cxx1y-deduced-return-type.cpp +++ test/SemaCXX/cxx1y-deduced-return-type.cpp @@ -55,6 +55,25 @@ return "goodbye"; } +// Allow 'operator auto' to call only the explicit operator auto. +struct BothOps { + template <typename T> operator T(); + template <typename T> operator T *(); + operator auto() { return 0; } + operator auto *() { return this; } +}; +struct JustTemplateOp { + template <typename T> operator T(); + template <typename T> 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'}} } Index: lib/Sema/SemaLookup.cpp =================================================================== --- lib/Sema/SemaLookup.cpp +++ lib/Sema/SemaLookup.cpp @@ -862,6 +862,19 @@ 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. + if (R.getLookupName().getNameKind() == + DeclarationName::CXXConversionFunctionName && + R.getLookupName().getCXXNameType()->getContainedDeducedType() && + R.getLookupName() + .getCXXNameType() + ->getContainedDeducedType() + ->isUndeducedType()) { + return Found; + } + for (CXXRecordDecl::conversion_iterator U = Record->conversion_begin(), UEnd = Record->conversion_end(); U != UEnd; ++U) { FunctionTemplateDecl *ConvTemplate = dyn_cast<FunctionTemplateDecl>(*U);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits