diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-01-05 23:12:16 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-01-05 23:12:16 +0000 |
| commit | c8a32e5ed2aaf0ab7478ffbdd20dcea9e86509b3 (patch) | |
| tree | 8070b9f6b25b05c66e13efebd2af79f0a89b563f /clang | |
| parent | c92d206ce441934a28e5886b5d635748f865a808 (diff) | |
| download | bcm5719-llvm-c8a32e5ed2aaf0ab7478ffbdd20dcea9e86509b3.tar.gz bcm5719-llvm-c8a32e5ed2aaf0ab7478ffbdd20dcea9e86509b3.zip | |
Fix bug where types other than 'cv auto', 'cv auto &', and 'cv auto &&' could
incorrectly be deduced from an initializer list in pathological cases.
llvm-svn: 291191
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 6 | ||||
| -rw-r--r-- | clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp | 10 |
2 files changed, 16 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 043e5c37160..b79904c0a70 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -4127,6 +4127,12 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, 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), diff --git a/clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp b/clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp index 01d498a5e95..9b8fadd2f52 100644 --- a/clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp +++ b/clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -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}} +} |

