]> granicus.if.org Git - clang/commitdiff
PR20346: fix aggregate initialization / template instantiation bug:
authorRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 17 Jul 2014 23:12:06 +0000 (23:12 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 17 Jul 2014 23:12:06 +0000 (23:12 +0000)
If, during the initial parse of a template, we perform aggregate initialization
and form an implicit value initialization for an array type, then when we come
to instantiate the template and redo the initialization step, we would try to
match the implicit value initialization up against an array *element*, not to
the complete array.

Remarkably, we've had this bug since ~the dawn of time, but only noticed it
recently.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@213332 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaInit.cpp
test/SemaTemplate/instantiate-decl-init.cpp

index 4b756064addb23458946cc0bf0fdc8146334316c..3ed1d7f1f66ccfb64903e2b5d362e0e00ff0c8f2 100644 (file)
@@ -914,6 +914,15 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity,
     assert(SemaRef.getLangOpts().CPlusPlus &&
            "non-aggregate records are only possible in C++");
     // C++ initialization is handled later.
+  } else if (auto *VIE = dyn_cast<ImplicitValueInitExpr>(expr)) {
+    // This happens during template instantiation when we see an InitListExpr
+    // that we've already checked once.
+    assert(SemaRef.Context.hasSameType(VIE->getType(), ElemType) &&
+           "found implicit initialization for the wrong type");
+    if (!VerifyOnly)
+      UpdateStructuredListElement(StructuredList, StructuredIndex, expr);
+    ++Index;
+    return;
   }
 
   // FIXME: Need to handle atomic aggregate types with implicit init lists.
index 9658fc1465cd87f6ed50e21566aa440d70220cb1..f5daa7901fa805546d93985a5212ea67c2a90d1f 100644 (file)
@@ -45,3 +45,23 @@ template<int N> void f1() {
   NonTrivial array[N];
 }
 template<> void f1<2>();
+
+namespace PR20346 {
+  struct S { short inner_s; };
+
+  struct outer_struct {
+    wchar_t arr[32];
+    S outer_s;
+  };
+
+  template <class T>
+  void OpenFileSession() {
+    // Ensure that we don't think the ImplicitValueInitExpr generated here
+    // during the initial parse only initializes the first array element!
+    outer_struct asdfasdf = {};
+  };
+
+  void foo() {
+    OpenFileSession<int>();
+  }
+}