if (S.CheckExceptionSpecCompatibility(CurInit.get(), DestType))
return ExprError();
+ QualType MTETy = Step->Type;
+
+ // When this is an incomplete array type (such as when this is
+ // initializing an array of unknown bounds from an init list), use THAT
+ // type instead so that we propogate the array bounds.
+ if (MTETy->isIncompleteArrayType() &&
+ !CurInit.get()->getType()->isIncompleteArrayType() &&
+ S.Context.hasSameType(
+ MTETy->getPointeeOrArrayElementType(),
+ CurInit.get()->getType()->getPointeeOrArrayElementType()))
+ MTETy = CurInit.get()->getType();
+
// Materialize the temporary into memory.
MaterializeTemporaryExpr *MTE = S.CreateMaterializeTemporaryExpr(
- Step->Type, CurInit.get(), Entity.getType()->isLValueReferenceType());
+ MTETy, CurInit.get(), Entity.getType()->isLValueReferenceType());
CurInit = MTE;
// If we're extending this temporary to automatic storage duration -- we
--- /dev/null
+// RUN: %clang_cc1 -fsyntax-only %s -ast-dump | FileCheck %s
+
+int(&&intu_rvref)[] {1,2,3,4};
+// CHECK: VarDecl 0x[[GLOB_ADDR:[0-9a-f]+]] {{.*}} intu_rvref 'int (&&)[4]' listinit
+// CHECK-NEXT: ExprWithCleanups {{.*}} 'int [4]' xvalue
+// CHECK-NEXT: MaterializeTemporaryExpr {{.*}} 'int [4]' xvalue extended by Var 0x[[GLOB_ADDR]] 'intu_rvref' 'int (&&)[4]'
+// CHECK-NEXT: InitListExpr {{.*}} 'int [4]'
+
+// CHECK: FunctionDecl {{.*}} static_const
+void static_const() {
+ static const int(&&intu_rvref)[] {1,2,3,4};
+ // CHECK: VarDecl 0x[[STATIC_ADDR:[0-9a-f]+]] {{.*}} intu_rvref 'const int (&&)[4]' static listinit
+ // CHECK-NEXT: ExprWithCleanups {{.*}} 'const int [4]' xvalue
+ // CHECK-NEXT: MaterializeTemporaryExpr {{.*}} 'const int [4]' xvalue extended by Var 0x[[STATIC_ADDR]] 'intu_rvref' 'const int (&&)[4]'
+ // CHECK-NEXT: InitListExpr {{.*}} 'const int [4]'
+}
+
+// CHECK: FunctionDecl {{.*}} const_expr
+constexpr int const_expr() {
+ int(&&intu_rvref)[]{1, 2, 3, 4};
+ // CHECK: VarDecl 0x[[CE_ADDR:[0-9a-f]+]] {{.*}} intu_rvref 'int (&&)[4]' listinit
+ // CHECK-NEXT: ExprWithCleanups {{.*}} 'int [4]' xvalue
+ // CHECK-NEXT: MaterializeTemporaryExpr {{.*}} 'int [4]' xvalue extended by Var 0x[[CE_ADDR]] 'intu_rvref' 'int (&&)[4]'
+ // CHECK-NEXT: InitListExpr {{.*}} 'int [4]'
+ return intu_rvref[0];
+}
// CHECK: @_ZZ3foovE10intu_rvref = internal constant [4 x i32]* @_ZGRZ3foovE10intu_rvref_
// CHECK: @_ZGRZ3foovE10intu_rvref_ = internal constant [4 x i32] [i32 1, i32 2, i32 3, i32 4]
}
+
+// Example given on review, ensure this doesn't crash as well.
+constexpr int f() {
+ // CHECK: i32 @_Z1fv()
+ int(&&intu_rvref)[]{1, 2, 3, 4};
+ // CHECK: %{{.*}} = alloca [4 x i32]*
+ return intu_rvref[2];
+}
+
+void use_f() {
+ int i = f();
+}