<div dir="auto"><div dir="auto">Hi Hans,</div><div dir="auto"><br></div><div dir="auto">This is a safe change that fixes a crash; it'd be good to get this into clang 8.</div><div dir="auto"><br></div><div dir="auto">Thanks!</div><div dir="auto"></div><br><div class="gmail_quote"><div dir="ltr" class="m_-1543674657201319911gmail_attr">On Sun, 27 Jan 2019, 11:19 Nicolas Lesser via cfe-commits, <<a href="mailto:cfe-commits@lists.llvm.org" target="_blank" rel="noreferrer">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rakete1111<br>
Date: Sun Jan 27 11:19:59 2019<br>
New Revision: 352323<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=352323&view=rev" rel="noreferrer noreferrer noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=352323&view=rev</a><br>
Log:<br>
[SemaCXX] Fix ICE with structure bindings to members of template<br>
<br>
Summary:<br>
Trying to use structure binding with a structure that doesn't implement<br>
std::tuple_size, should unpack the data members. When the struct is a<br>
template though, clang might hit an assertion (if the type has not been<br>
completed before), because CXXRecordDecl::DefinitionData is nullptr.<br>
<br>
This commit fixes the problem by completing the type while trying to<br>
decompose the structured binding.<br>
<br>
The ICE happens in real world code, for example, when trying to iterate<br>
a protobuf generated map with a range-based for loop and structure<br>
bindings (because google::protobuf::MapPair is a template and doesn't<br>
support std::tuple_size).<br>
<br>
Reported-by: <a href="mailto:nicholas.sun@nlsun.com" rel="noreferrer noreferrer" target="_blank">nicholas.sun@nlsun.com</a><br>
<br>
Patch by Daniele Di Proietto<br>
<br>
Reviewers: #clang, rsmith<br>
<br>
Reviewed By: #clang, rsmith<br>
<br>
Subscribers: cpplearner, Rakete1111, cfe-commits<br>
<br>
Tags: #clang<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D56974" rel="noreferrer noreferrer noreferrer" target="_blank">https://reviews.llvm.org/D56974</a><br>
<br>
<br>
Modified:<br>
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
    cfe/trunk/test/SemaCXX/cxx1z-decomposition.cpp<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=352323&r1=352322&r2=352323&view=diff" rel="noreferrer noreferrer noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=352323&r1=352322&r2=352323&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Sun Jan 27 11:19:59 2019<br>
@@ -1300,6 +1300,10 @@ static DeclAccessPair findDecomposableBa<br>
 static bool checkMemberDecomposition(Sema &S, ArrayRef<BindingDecl*> Bindings,<br>
                                      ValueDecl *Src, QualType DecompType,<br>
                                      const CXXRecordDecl *OrigRD) {<br>
+  if (S.RequireCompleteType(Src->getLocation(), DecompType,<br>
+                            diag::err_incomplete_type))<br>
+    return true;<br>
+<br>
   CXXCastPath BasePath;<br>
   DeclAccessPair BasePair =<br>
       findDecomposableBaseClass(S, Src->getLocation(), OrigRD, BasePath);<br>
<br>
Modified: cfe/trunk/test/SemaCXX/cxx1z-decomposition.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-decomposition.cpp?rev=352323&r1=352322&r2=352323&view=diff" rel="noreferrer noreferrer noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-decomposition.cpp?rev=352323&r1=352322&r2=352323&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/cxx1z-decomposition.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/cxx1z-decomposition.cpp Sun Jan 27 11:19:59 2019<br>
@@ -81,4 +81,21 @@ struct PR37352 {<br>
   void f() { static auto [a] = *this; } // expected-error {{cannot be declared 'static'}}<br>
 };<br>
<br>
+namespace instantiate_template {<br>
+<br>
+template <typename T1, typename T2><br>
+struct pair {<br>
+  T1 a;<br>
+  T2 b;<br>
+};<br>
+<br>
+const pair<int, int> &f1();<br>
+<br>
+int f2() {<br>
+  const auto &[a, b] = f1();<br>
+  return a + b;<br>
+}<br>
+<br>
+} // namespace instantiate_template<br>
+<br>
 // FIXME: by-value array copies<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" rel="noreferrer noreferrer" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer noreferrer noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div></div>