forked from OSchip/llvm-project
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 llvm-svn: 305812
This commit is contained in:
parent
f5bb738f75
commit
c9cb1c13ba
|
@ -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);
|
||||
|
|
|
@ -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'}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue