summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2019-01-28 13:47:09 +0000
committerHans Wennborg <hans@hanshq.net>2019-01-28 13:47:09 +0000
commite6bf555407449327770d55daef14b6699c343a0b (patch)
tree029c8f9e006876eb5eaf05bc8246766f5a240664
parent4d37fec6c9b50397feff988fb8cab7749a916454 (diff)
Merging r352323:
Redirecting to URL 'https://llvm.org/svn/llvm-project/cfe/trunk': ------------------------------------------------------------------------ r352323 | rakete1111 | 2019-01-27 20:19:59 +0100 (Sun, 27 Jan 2019) | 31 lines [SemaCXX] Fix ICE with structure bindings to members of template Summary: Trying to use structure binding with a structure that doesn't implement std::tuple_size, should unpack the data members. When the struct is a template though, clang might hit an assertion (if the type has not been completed before), because CXXRecordDecl::DefinitionData is nullptr. This commit fixes the problem by completing the type while trying to decompose the structured binding. The ICE happens in real world code, for example, when trying to iterate a protobuf generated map with a range-based for loop and structure bindings (because google::protobuf::MapPair is a template and doesn't support std::tuple_size). Reported-by: nicholas.sun@nlsun.com Patch by Daniele Di Proietto Reviewers: #clang, rsmith Reviewed By: #clang, rsmith Subscribers: cpplearner, Rakete1111, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D56974 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_80@352356 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaDeclCXX.cpp4
-rw-r--r--test/SemaCXX/cxx1z-decomposition.cpp17
2 files changed, 21 insertions, 0 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 43b289d8d0..e66ee43307 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1301,6 +1301,10 @@ static DeclAccessPair findDecomposableBaseClass(Sema &S, SourceLocation Loc,
static bool checkMemberDecomposition(Sema &S, ArrayRef<BindingDecl*> Bindings,
ValueDecl *Src, QualType DecompType,
const CXXRecordDecl *OrigRD) {
+ if (S.RequireCompleteType(Src->getLocation(), DecompType,
+ diag::err_incomplete_type))
+ return true;
+
CXXCastPath BasePath;
DeclAccessPair BasePair =
findDecomposableBaseClass(S, Src->getLocation(), OrigRD, BasePath);
diff --git a/test/SemaCXX/cxx1z-decomposition.cpp b/test/SemaCXX/cxx1z-decomposition.cpp
index 3c9b181f1c..8b5fd6809b 100644
--- a/test/SemaCXX/cxx1z-decomposition.cpp
+++ b/test/SemaCXX/cxx1z-decomposition.cpp
@@ -81,4 +81,21 @@ struct PR37352 {
void f() { static auto [a] = *this; } // expected-error {{cannot be declared 'static'}}
};
+namespace instantiate_template {
+
+template <typename T1, typename T2>
+struct pair {
+ T1 a;
+ T2 b;
+};
+
+const pair<int, int> &f1();
+
+int f2() {
+ const auto &[a, b] = f1();
+ return a + b;
+}
+
+} // namespace instantiate_template
+
// FIXME: by-value array copies