From: Richard Smith Date: Thu, 5 Jan 2017 23:12:16 +0000 (+0000) Subject: Fix bug where types other than 'cv auto', 'cv auto &', and 'cv auto &&' could X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=41fdaf8af10cd6116b96535b201b28c63345ef37;p=clang Fix bug where types other than 'cv auto', 'cv auto &', and 'cv auto &&' could incorrectly be deduced from an initializer list in pathological cases. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@291191 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 043e5c3716..b79904c0a7 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -4127,6 +4127,12 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, InitListExpr *InitList = dyn_cast(Init); if (InitList) { + // Notionally, we substitute std::initializer_list for 'auto' and deduce + // against that. Such deduction only succeeds if removing cv-qualifiers and + // references results in std::initializer_list. + if (!Type.getType().getNonReferenceType()->getAs()) + return DAR_Failed; + for (unsigned i = 0, e = InitList->getNumInits(); i < e; ++i) { if (DeduceTemplateArgumentsFromCallArgument( *this, TemplateParamsSt.get(), TemplArg, InitList->getInit(i), diff --git a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp index 01d498a5e9..9b8fadd2f5 100644 --- a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp +++ b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -337,3 +337,13 @@ namespace update_rbrace_loc_crash { Explode([](int) {}); } } + +namespace no_conversion_after_auto_list_deduction { + // We used to deduce 'auto' == 'std::initializer_list' here, and then + // incorrectly accept the declaration of 'x'. + struct X { using T = std::initializer_list X::*; operator T(); }; + auto X::*x = { X() }; // expected-error {{from initializer list}} + + struct Y { using T = std::initializer_list(*)(); operator T(); }; + auto (*y)() = { Y() }; // expected-error {{from initializer list}} +}