Author: rsmith Date: Thu Jan 5 17:12:16 2017 New Revision: 291191 URL: http://llvm.org/viewvc/llvm-project?rev=291191&view=rev Log: Fix bug where types other than 'cv auto', 'cv auto &', and 'cv auto &&' could incorrectly be deduced from an initializer list in pathological cases.
Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=291191&r1=291190&r2=291191&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Thu Jan 5 17:12:16 2017 @@ -4127,6 +4127,12 @@ Sema::DeduceAutoType(TypeLoc Type, Expr InitListExpr *InitList = dyn_cast<InitListExpr>(Init); if (InitList) { + // Notionally, we substitute std::initializer_list<T> for 'auto' and deduce + // against that. Such deduction only succeeds if removing cv-qualifiers and + // references results in std::initializer_list<T>. + if (!Type.getType().getNonReferenceType()->getAs<AutoType>()) + return DAR_Failed; + for (unsigned i = 0, e = InitList->getNumInits(); i < e; ++i) { if (DeduceTemplateArgumentsFromCallArgument( *this, TemplateParamsSt.get(), TemplArg, InitList->getInit(i), Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=291191&r1=291190&r2=291191&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp (original) +++ cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp Thu Jan 5 17:12:16 2017 @@ -337,3 +337,13 @@ namespace update_rbrace_loc_crash { Explode<ContainsIncomplete, 4>([](int) {}); } } + +namespace no_conversion_after_auto_list_deduction { + // We used to deduce 'auto' == 'std::initializer_list<X>' here, and then + // incorrectly accept the declaration of 'x'. + struct X { using T = std::initializer_list<X> X::*; operator T(); }; + auto X::*x = { X() }; // expected-error {{from initializer list}} + + struct Y { using T = std::initializer_list<Y>(*)(); operator T(); }; + auto (*y)() = { Y() }; // expected-error {{from initializer list}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits