]> granicus.if.org Git - clang/commitdiff
Fix regression in r170489: when instantiating a direct initializer which is a
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 21 Dec 2012 08:13:35 +0000 (08:13 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 21 Dec 2012 08:13:35 +0000 (08:13 +0000)
CXXScalarValueInitExpr (or an ImplicitValueInitExpr), strip it back down to an
empty pair of parentheses so that the initialization code can tell that we're
performing value-initialization.

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

lib/Sema/SemaExpr.cpp
lib/Sema/TreeTransform.h
test/SemaTemplate/instantiate-member-initializers.cpp

index 7656d9ee66745d04731b43ee47e45f6f8d33cd2b..543643434099afcc09ebd7a7346fc3f35289bc98 100644 (file)
@@ -4697,7 +4697,6 @@ Sema::MaybeConvertParenListExprToParenExpr(Scope *S, Expr *OrigExpr) {
 ExprResult Sema::ActOnParenListExpr(SourceLocation L,
                                     SourceLocation R,
                                     MultiExprArg Val) {
-  assert(Val.data() != 0 && "ActOnParenOrParenListExpr() missing expr list");
   Expr *expr = new (Context) ParenListExpr(Context, L, Val, R);
   return Owned(expr);
 }
index c161d8cfcb2b0b06d375cc0aa2cf42c3bc0ae618..baf2308a4586d6b847c0597722a17fe2a881da57 100644 (file)
@@ -2602,12 +2602,28 @@ ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
   if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
     Init = ICE->getSubExprAsWritten();
 
-  // If this is a direct-initializer, we take apart CXXConstructExprs.
-  // Everything else is passed through.
-  CXXConstructExpr *Construct;
-  if (!(Construct = dyn_cast<CXXConstructExpr>(Init)) ||
-      isa<CXXTemporaryObjectExpr>(Construct) ||
-      (!CXXDirectInit && !Construct->isListInitialization()))
+  // If this is not a direct-initializer, we only need to reconstruct
+  // InitListExprs. Other forms of copy-initialization will be a no-op if
+  // the initializer is already the right type.
+  CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init);
+  if (!CXXDirectInit && !(Construct && Construct->isListInitialization()))
+    return getDerived().TransformExpr(Init);
+
+  // Revert value-initialization back to empty parens.
+  if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Init)) {
+    SourceRange Parens = VIE->getSourceRange();
+    return getDerived().RebuildParenListExpr(Parens.getBegin(), MultiExprArg(),
+                                             Parens.getEnd());
+  }
+
+  // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
+  if (isa<ImplicitValueInitExpr>(Init))
+    return getDerived().RebuildParenListExpr(SourceLocation(), MultiExprArg(),
+                                             SourceLocation());
+
+  // Revert initialization by constructor back to a parenthesized or braced list
+  // of expressions. Any other form of initializer can just be reused directly.
+  if (!Construct || isa<CXXTemporaryObjectExpr>(Construct))
     return getDerived().TransformExpr(Init);
 
   SmallVector<Expr*, 8> NewArgs;
index 297ae917bb46369183e82bf09ccd4689f9fe18be..63862063acdfe6ee0b9b5c2722d2464221678f49 100644 (file)
@@ -35,3 +35,9 @@ struct Y {
   X x;
 };
 Y<int> y;
+
+template<typename T> struct Array {
+  int a[3];
+  Array() : a() {}
+};
+Array<int> s;