r305812 - Fix for Bug 33471: Preventing operator auto from resolving to a template operator.
Erich Keane via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 20 10:38:08 PDT 2017
Author: erichkeane
Date: Tue Jun 20 12:38:07 2017
New Revision: 305812
URL: http://llvm.org/viewvc/llvm-project?rev=305812&view=rev
Log:
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
Modified:
cfe/trunk/lib/Sema/SemaLookup.cpp
cfe/trunk/test/SemaCXX/cxx1y-deduced-return-type.cpp
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=305812&r1=305811&r2=305812&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Tue Jun 20 12:38:07 2017
@@ -862,6 +862,16 @@ static bool LookupDirect(Sema &S, Lookup
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);
Modified: cfe/trunk/test/SemaCXX/cxx1y-deduced-return-type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-deduced-return-type.cpp?rev=305812&r1=305811&r2=305812&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1y-deduced-return-type.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1y-deduced-return-type.cpp Tue Jun 20 12:38:07 2017
@@ -55,6 +55,25 @@ auto b(bool k) {
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'}}
}
More information about the cfe-commits
mailing list