DR1213: element access on an array xvalue or prvalue produces an xvalue. In the
latter case, a temporary array object is materialized, and can be
lifetime-extended by binding a reference to the member access. Likewise, in an
array-to-pointer decay, an rvalue array is materialized before being converted
into a pointer.

This caused IR generation to stop treating file-scope array compound literals
as having static storage duration in some cases in C++; that has been rectified
by modeling such a compound literal as an lvalue. This also improves clang's
compatibility with GCC for those cases.

llvm-svn: 288654
diff --git a/clang/test/Analysis/explain-svals.cpp b/clang/test/Analysis/explain-svals.cpp
index ef2ebc2..be2f830 100644
--- a/clang/test/Analysis/explain-svals.cpp
+++ b/clang/test/Analysis/explain-svals.cpp
@@ -76,7 +76,7 @@
   clang_analyzer_explain(&stat); // expected-warning-re{{{{^pointer to static local variable 'stat'$}}}}
   clang_analyzer_explain(stat_glob); // expected-warning-re{{{{^initial value of global variable 'stat_glob'$}}}}
   clang_analyzer_explain(&stat_glob); // expected-warning-re{{{{^pointer to global variable 'stat_glob'$}}}}
-  clang_analyzer_explain((int[]){1, 2, 3}); // expected-warning-re{{{{^pointer to element of type 'int' with index 0 of compound literal \(int \[3\]\)\{1, 2, 3\}$}}}}
+  clang_analyzer_explain((int[]){1, 2, 3}); // expected-warning-re{{{{^pointer to element of type 'int' with index 0 of temporary object constructed at statement '\(int \[3\]\)\{1, 2, 3\}'$}}}}
 }
 
 namespace {
diff --git a/clang/test/CXX/drs/dr12xx.cpp b/clang/test/CXX/drs/dr12xx.cpp
index 048c21a..c4f980a 100644
--- a/clang/test/CXX/drs/dr12xx.cpp
+++ b/clang/test/CXX/drs/dr12xx.cpp
@@ -5,6 +5,17 @@
 
 // expected-no-diagnostics
 
+namespace dr1213 { // dr1213: 4.0
+#if __cplusplus >= 201103L
+  using T = int[3];
+  int &&r = T{}[1];
+
+  using T = decltype((T{}));
+  using U = decltype((T{}[2]));
+  using U = int &&;
+#endif
+}
+
 namespace dr1250 {  // dr1250: 3.9
 struct Incomplete;
 
diff --git a/clang/test/CodeGenCXX/compound-literals.cpp b/clang/test/CodeGenCXX/compound-literals.cpp
index 0169d5b..a9882bc 100644
--- a/clang/test/CodeGenCXX/compound-literals.cpp
+++ b/clang/test/CodeGenCXX/compound-literals.cpp
@@ -12,6 +12,9 @@
   X x;
 };
 
+// CHECK: @.compoundliteral = internal global [5 x i32] [i32 1, i32 2, i32 3, i32 4, i32 5], align 4
+// CHECK: @q = global i32* getelementptr inbounds ([5 x i32], [5 x i32]* @.compoundliteral, i32 0, i32 0), align 4
+
 // CHECK-LABEL: define i32 @_Z1fv()
 int f() {
   // CHECK: [[LVALUE:%[a-z0-9.]+]] = alloca
@@ -51,20 +54,27 @@
 // CHECK: store i32* %{{.*}}, i32** @p
 
 int *q = (int [5]){1, 2, 3, 4, 5};
-// CHECK-LABEL: define {{.*}}__cxx_global_var_init.1()
-// CHECK: store i32* getelementptr inbounds ([5 x i32], [5 x i32]* @.compoundliteral, i32 0, i32 0), i32** @q
+// (constant initialization, checked above)
 
-int *PR21912_1 = (int []){};
-// CHECK-LABEL: define {{.*}}__cxx_global_var_init.2()
-// CHECK: store i32* getelementptr inbounds ([0 x i32], [0 x i32]* @.compoundliteral.3, i32 0, i32 0), i32** @PR21912_1
+extern int n;
+int *r = (int [5]){1, 2, 3, 4, 5} + n;
+// CHECK-LABEL: define {{.*}}__cxx_global_var_init.1()
+// CHECK: %[[PTR:.*]] = getelementptr inbounds i32, i32* getelementptr inbounds ([5 x i32], [5 x i32]* @.compoundliteral.2, i32 0, i32 0), i32 %
+// CHECK: store i32* %[[PTR]], i32** @r
+
+int *PR21912_1 = (int []){} + n;
+// CHECK-LABEL: define {{.*}}__cxx_global_var_init.3()
+// CHECK: %[[PTR:.*]] = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @.compoundliteral.4, i32 0, i32 0), i32 %
+// CHECK: store i32* %[[PTR]], i32** @PR21912_1
 
 union PR21912Ty {
   long long l;
   double d;
 };
-union PR21912Ty *PR21912_2 = (union PR21912Ty[]){{.d = 2.0}, {.l = 3}};
-// CHECK-LABEL: define {{.*}}__cxx_global_var_init.4()
-// CHECK: store %union.PR21912Ty* getelementptr inbounds ([2 x %union.PR21912Ty], [2 x %union.PR21912Ty]* bitcast (<{ { double }, %union.PR21912Ty }>* @.compoundliteral.5 to [2 x %union.PR21912Ty]*), i32 0, i32 0), %union.PR21912Ty** @PR21912_2
+union PR21912Ty *PR21912_2 = (union PR21912Ty[]){{.d = 2.0}, {.l = 3}} + n;
+// CHECK-LABEL: define {{.*}}__cxx_global_var_init.5()
+// CHECK: %[[PTR:.*]] = getelementptr inbounds %union.PR21912Ty, %union.PR21912Ty* getelementptr inbounds ([2 x %union.PR21912Ty], [2 x %union.PR21912Ty]* bitcast (<{ { double }, %union.PR21912Ty }>* @.compoundliteral.6 to [2 x %union.PR21912Ty]*), i32 0, i32 0), i32 %
+// CHECK: store %union.PR21912Ty* %[[PTR]], %union.PR21912Ty** @PR21912_2, align 4
 
 // This compound literal should have local scope.
 int computed_with_lambda = [] {
diff --git a/clang/test/CodeGenCXX/stack-reuse.cpp b/clang/test/CodeGenCXX/stack-reuse.cpp
index d6340ef..8325604 100644
--- a/clang/test/CodeGenCXX/stack-reuse.cpp
+++ b/clang/test/CodeGenCXX/stack-reuse.cpp
@@ -132,8 +132,8 @@
 
 int large_combiner_test(S_large s) {
 // CHECK-LABEL: define i32 @large_combiner_test
-// CHECK: [[T1:%.*]] = alloca %struct.Combiner
 // CHECK: [[T2:%.*]] = alloca %struct.Combiner
+// CHECK: [[T1:%.*]] = alloca %struct.Combiner
 // CHECK: [[T3:%.*]] = call %struct.Combiner* @_ZN8CombinerC1E7S_large(%struct.Combiner* nonnull [[T1]], [9 x i32] %s.coerce)
 // CHECK: call void @_ZN8Combiner1fEv(%struct.Combiner* nonnull sret [[T2]], %struct.Combiner* nonnull [[T1]])
 // CHECK: [[T4:%.*]] = getelementptr inbounds %struct.Combiner, %struct.Combiner* [[T2]], i32 0, i32 0, i32 0, i32 0
diff --git a/clang/test/CodeGenCXX/temporaries.cpp b/clang/test/CodeGenCXX/temporaries.cpp
index c537124..bad51ba 100644
--- a/clang/test/CodeGenCXX/temporaries.cpp
+++ b/clang/test/CodeGenCXX/temporaries.cpp
@@ -779,6 +779,36 @@
   }
 }
 
+namespace ArrayAccess {
+  struct A { A(int); ~A(); };
+  void g();
+  void f() {
+    using T = A[3];
+
+    // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 1
+    // CHECK-NOT: @_ZN11ArrayAccess1AD
+    // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 2
+    // CHECK-NOT: @_ZN11ArrayAccess1AD
+    // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 3
+    // CHECK-NOT: @_ZN11ArrayAccess1AD
+    A &&a = T{1, 2, 3}[1];
+
+    // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 4
+    // CHECK-NOT: @_ZN11ArrayAccess1AD
+    // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 5
+    // CHECK-NOT: @_ZN11ArrayAccess1AD
+    // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 6
+    // CHECK-NOT: @_ZN11ArrayAccess1AD
+    A &&b = 2[T{4, 5, 6}];
+
+    // CHECK: call void @_ZN11ArrayAccess1gEv(
+    g();
+
+    // CHECK: call void @_ZN11ArrayAccess1AD
+    // CHECK: call void @_ZN11ArrayAccess1AD
+  }
+}
+
 namespace PR14130 {
   struct S { S(int); };
   struct U { S &&s; };
diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index 00bf5bd..8ecf4a4 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -1467,13 +1467,26 @@
 }
 
 namespace CompoundLiteral {
-  // FIXME:
-  // We don't model the semantics of this correctly: the compound literal is
-  // represented as a prvalue in the AST, but actually behaves like an lvalue.
-  // We treat the compound literal as a temporary and refuse to produce a
-  // pointer to it. This is OK: we're not required to treat this as a constant
-  // in C++, and in C we model compound literals as lvalues.
-  constexpr int *p = (int*)(int[1]){0}; // expected-warning {{C99}} expected-error {{constant expression}} expected-note 2{{temporary}}
+  // Matching GCC, file-scope array compound literals initialized by constants
+  // are lifetime-extended.
+  constexpr int *p = (int*)(int[1]){3}; // expected-warning {{C99}}
+  static_assert(*p == 3, "");
+  static_assert((int[2]){1, 2}[1] == 2, ""); // expected-warning {{C99}}
+
+  // Other kinds are not.
+  struct X { int a[2]; };
+  constexpr int *n = (X){1, 2}.a; // expected-warning {{C99}} expected-warning {{temporary array}}
+  // expected-error@-1 {{constant expression}}
+  // expected-note@-2 {{pointer to subobject of temporary}}
+  // expected-note@-3 {{temporary created here}}
+
+  void f() {
+    static constexpr int *p = (int*)(int[1]){3}; // expected-warning {{C99}}
+    // expected-error@-1 {{constant expression}}
+    // expected-note@-2 {{pointer to subobject of temporary}}
+    // expected-note@-3 {{temporary created here}}
+    static_assert((int[2]){1, 2}[1] == 2, ""); // expected-warning {{C99}}
+  }
 }
 
 namespace Vector {