[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-05-01 Thread Alan Zhao via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG9b4faa11c68b: [clang] Fix overly aggressive lifetime checks 
for parenthesized aggregate… (authored by ayzhao).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/Sema/SemaAccess.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/test/CodeGen/paren-list-agg-init.cpp
  clang/test/SemaCXX/paren-list-agg-init.cpp

Index: clang/test/SemaCXX/paren-list-agg-init.cpp
===
--- clang/test/SemaCXX/paren-list-agg-init.cpp
+++ clang/test/SemaCXX/paren-list-agg-init.cpp
@@ -9,7 +9,7 @@
 struct B {
   A a;
   int b[20];
-  int & // expected-note {{reference member declared here}}
+  int &
 };
 
 struct C { // expected-note 5{{candidate constructor}}
@@ -21,9 +21,9 @@
   int a;
 };
 
-struct E { // expected-note 3{{candidate constructor}}
-  struct F {
-F(int, int);
+struct E {
+  struct F { // expected-note 2{{candidate constructor}}
+F(int, int); // expected-note {{candidate constructor}}
   };
   int a;
   F f;
@@ -56,6 +56,22 @@
   int b[]; // expected-note {{initialized flexible array member 'b' is here}}
 };
 
+enum K { K0, K1, K2 };
+
+struct L {
+  K k : 1;
+};
+
+struct M {
+  struct N {
+private:
+N(int);
+// expected-note@-1 {{declared private here}}
+  };
+  int i;
+  N n;
+};
+
 union U {
   int a;
   char* b;
@@ -74,7 +90,7 @@
   // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
 }
 
-void foo() {
+void foo(int n) {
   A a1(1954, 9, 21);
   // expected-error@-1 {{excess elements in struct initializer}}
   A a2(2.1);
@@ -96,9 +112,8 @@
   B b1(2022, {7, 8});
   // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
   B b2(A(1), {}, 1);
-  // expected-error@-1 {{reference member 'c' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
-  // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
-  // beforecxx20-warning@-3 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
 
   C c(A(1), 1, 2, 3, 4);
   // expected-error@-1 {{array initializer must be an initializer list}}
@@ -130,7 +145,7 @@
   // expected-error@-1 {{excess elements in union initializer}}
 
   E e1(1);
-  // expected-error@-1 {{no matching constructor for initialization of 'E'}}
+  // expected-error@-1 {{no matching constructor for initialization of 'F'}}
 
   constexpr F f1(1);
   // expected-error@-1 {{constexpr variable 'f1' must be initialized by a constant expression}}
@@ -148,18 +163,29 @@
   A a7 = Construct('i', 2.2);
   // beforecxx20-note@-1 {{in instantiation of function template specialization 'Construct' requested here}}
 
+  L l(K::K2);
+  // expected-warning@-1 {{implicit truncation}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'L' from a parenthesized list of values is a C++20 extension}}
+
   int arr4[](1, 2);
   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
 
   int arr5[2](1, 2);
   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
 
+  int arr6[n](1, 2, 3);
+  // expected-error@-1 {{variable-sized object may not be initialized}}
+
   I i(1, 2);
   // expected-error@-1 {{no matching constructor for initialization of 'I'}}
 
   J j(1, {2, 3});
   // expected-error@-1 {{initialization of flexible array member is not allowed}}
 
+  M m(1, 1);
+  // expected-error@-1 {{field of type 'N' has private constructor}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'M' from a parenthesized list of values is a C++20 extension}}
+
   static_assert(__is_trivially_constructible(A, char, double));
   static_assert(__is_trivially_constructible(A, char, int));
   static_assert(__is_trivially_constructible(A, char));
@@ -221,5 +247,22 @@
 N n(43);
 // expected-error@-1 {{field of type 'L' has protected constructor}}
 // beforecxx20-warning@-2 {{aggregate initialization of type 'N' from a parenthesized list of values is a C++20 extension}}
+}
+
+namespace gh61567 {
+struct O {
+  int i;
+  int &
+  // expected-note@-1 {{uninitialized reference member is here}}
+  int & = 1;
+};
+
+O o1(0, 0, 0); // 

[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-05-01 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 518479.
ayzhao added a comment.

rebase + fix merge conflicts


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/Sema/SemaAccess.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/test/CodeGen/paren-list-agg-init.cpp
  clang/test/SemaCXX/paren-list-agg-init.cpp

Index: clang/test/SemaCXX/paren-list-agg-init.cpp
===
--- clang/test/SemaCXX/paren-list-agg-init.cpp
+++ clang/test/SemaCXX/paren-list-agg-init.cpp
@@ -9,7 +9,7 @@
 struct B {
   A a;
   int b[20];
-  int & // expected-note {{reference member declared here}}
+  int &
 };
 
 struct C { // expected-note 5{{candidate constructor}}
@@ -21,9 +21,9 @@
   int a;
 };
 
-struct E { // expected-note 3{{candidate constructor}}
-  struct F {
-F(int, int);
+struct E {
+  struct F { // expected-note 2{{candidate constructor}}
+F(int, int); // expected-note {{candidate constructor}}
   };
   int a;
   F f;
@@ -56,6 +56,22 @@
   int b[]; // expected-note {{initialized flexible array member 'b' is here}}
 };
 
+enum K { K0, K1, K2 };
+
+struct L {
+  K k : 1;
+};
+
+struct M {
+  struct N {
+private:
+N(int);
+// expected-note@-1 {{declared private here}}
+  };
+  int i;
+  N n;
+};
+
 union U {
   int a;
   char* b;
@@ -74,7 +90,7 @@
   // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
 }
 
-void foo() {
+void foo(int n) {
   A a1(1954, 9, 21);
   // expected-error@-1 {{excess elements in struct initializer}}
   A a2(2.1);
@@ -96,9 +112,8 @@
   B b1(2022, {7, 8});
   // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
   B b2(A(1), {}, 1);
-  // expected-error@-1 {{reference member 'c' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
-  // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
-  // beforecxx20-warning@-3 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
 
   C c(A(1), 1, 2, 3, 4);
   // expected-error@-1 {{array initializer must be an initializer list}}
@@ -130,7 +145,7 @@
   // expected-error@-1 {{excess elements in union initializer}}
 
   E e1(1);
-  // expected-error@-1 {{no matching constructor for initialization of 'E'}}
+  // expected-error@-1 {{no matching constructor for initialization of 'F'}}
 
   constexpr F f1(1);
   // expected-error@-1 {{constexpr variable 'f1' must be initialized by a constant expression}}
@@ -148,18 +163,29 @@
   A a7 = Construct('i', 2.2);
   // beforecxx20-note@-1 {{in instantiation of function template specialization 'Construct' requested here}}
 
+  L l(K::K2);
+  // expected-warning@-1 {{implicit truncation}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'L' from a parenthesized list of values is a C++20 extension}}
+
   int arr4[](1, 2);
   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
 
   int arr5[2](1, 2);
   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
 
+  int arr6[n](1, 2, 3);
+  // expected-error@-1 {{variable-sized object may not be initialized}}
+
   I i(1, 2);
   // expected-error@-1 {{no matching constructor for initialization of 'I'}}
 
   J j(1, {2, 3});
   // expected-error@-1 {{initialization of flexible array member is not allowed}}
 
+  M m(1, 1);
+  // expected-error@-1 {{field of type 'N' has private constructor}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'M' from a parenthesized list of values is a C++20 extension}}
+
   static_assert(__is_trivially_constructible(A, char, double));
   static_assert(__is_trivially_constructible(A, char, int));
   static_assert(__is_trivially_constructible(A, char));
@@ -221,5 +247,22 @@
 N n(43);
 // expected-error@-1 {{field of type 'L' has protected constructor}}
 // beforecxx20-warning@-2 {{aggregate initialization of type 'N' from a parenthesized list of values is a C++20 extension}}
+}
+
+namespace gh61567 {
+struct O {
+  int i;
+  int &
+  // expected-note@-1 {{uninitialized reference member is here}}
+  int & = 1;
+};
+
+O o1(0, 0, 0); // no-error
+// beforecxx20-warning@-1 {{aggregate initialization of type 'O' from a parenthesized list of values is a C++20 extension}}
+
+O o2(0, 0); // no-error
+// 

[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-28 Thread Shafik Yaghmour via Phabricator via cfe-commits
shafik accepted this revision.
shafik added a comment.
This revision is now accepted and ready to land.

LGTM


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-28 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 518044.
ayzhao added a comment.

add release note


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/Sema/SemaAccess.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/test/CodeGen/paren-list-agg-init.cpp
  clang/test/SemaCXX/paren-list-agg-init.cpp

Index: clang/test/SemaCXX/paren-list-agg-init.cpp
===
--- clang/test/SemaCXX/paren-list-agg-init.cpp
+++ clang/test/SemaCXX/paren-list-agg-init.cpp
@@ -9,7 +9,7 @@
 struct B {
   A a;
   int b[20];
-  int & // expected-note {{reference member declared here}}
+  int &
 };
 
 struct C { // expected-note 5{{candidate constructor}}
@@ -21,9 +21,9 @@
   int a;
 };
 
-struct E { // expected-note 3{{candidate constructor}}
-  struct F {
-F(int, int);
+struct E {
+  struct F { // expected-note 2{{candidate constructor}}
+F(int, int); // expected-note {{candidate constructor}}
   };
   int a;
   F f;
@@ -56,6 +56,22 @@
   int b[]; // expected-note {{initialized flexible array member 'b' is here}}
 };
 
+enum K { K0, K1, K2 };
+
+struct L {
+  K k : 1;
+};
+
+struct M {
+  struct N {
+private:
+N(int);
+// expected-note@-1 {{declared private here}}
+  };
+  int i;
+  N n;
+};
+
 union U {
   int a;
   char* b;
@@ -74,7 +90,7 @@
   // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
 }
 
-void foo() {
+void foo(int n) {
   A a1(1954, 9, 21);
   // expected-error@-1 {{excess elements in struct initializer}}
   A a2(2.1);
@@ -96,9 +112,8 @@
   B b1(2022, {7, 8});
   // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
   B b2(A(1), {}, 1);
-  // expected-error@-1 {{reference member 'c' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
-  // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
-  // beforecxx20-warning@-3 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
 
   C c(A(1), 1, 2, 3, 4);
   // expected-error@-1 {{array initializer must be an initializer list}}
@@ -130,7 +145,7 @@
   // expected-error@-1 {{excess elements in union initializer}}
 
   E e1(1);
-  // expected-error@-1 {{no matching constructor for initialization of 'E'}}
+  // expected-error@-1 {{no matching constructor for initialization of 'F'}}
 
   constexpr F f1(1);
   // expected-error@-1 {{constexpr variable 'f1' must be initialized by a constant expression}}
@@ -148,18 +163,29 @@
   A a7 = Construct('i', 2.2);
   // beforecxx20-note@-1 {{in instantiation of function template specialization 'Construct' requested here}}
 
+  L l(K::K2);
+  // expected-warning@-1 {{implicit truncation}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'L' from a parenthesized list of values is a C++20 extension}}
+
   int arr4[](1, 2);
   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
 
   int arr5[2](1, 2);
   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
 
+  int arr6[n](1, 2, 3);
+  // expected-error@-1 {{variable-sized object may not be initialized}}
+
   I i(1, 2);
   // expected-error@-1 {{no matching constructor for initialization of 'I'}}
 
   J j(1, {2, 3});
   // expected-error@-1 {{initialization of flexible array member is not allowed}}
 
+  M m(1, 1);
+  // expected-error@-1 {{field of type 'N' has private constructor}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'M' from a parenthesized list of values is a C++20 extension}}
+
   static_assert(__is_trivially_constructible(A, char, double));
   static_assert(__is_trivially_constructible(A, char, int));
   static_assert(__is_trivially_constructible(A, char));
@@ -221,5 +247,22 @@
 N n(43);
 // expected-error@-1 {{field of type 'L' has protected constructor}}
 // beforecxx20-warning@-2 {{aggregate initialization of type 'N' from a parenthesized list of values is a C++20 extension}}
+}
+
+namespace gh61567 {
+struct O {
+  int i;
+  int &
+  // expected-note@-1 {{uninitialized reference member is here}}
+  int & = 1;
+};
+
+O o1(0, 0, 0); // no-error
+// beforecxx20-warning@-1 {{aggregate initialization of type 'O' from a parenthesized list of values is a C++20 extension}}
+
+O o2(0, 0); // no-error
+// 

[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-27 Thread Shafik Yaghmour via Phabricator via cfe-commits
shafik added a comment.

I need to look at this more carefully but can we add a release note in the 
meantime


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-27 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 517699.
ayzhao marked an inline comment as done.
ayzhao added a comment.

code review comments + pull in D149301 


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/Sema/SemaAccess.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/test/CodeGen/paren-list-agg-init.cpp
  clang/test/SemaCXX/paren-list-agg-init.cpp

Index: clang/test/SemaCXX/paren-list-agg-init.cpp
===
--- clang/test/SemaCXX/paren-list-agg-init.cpp
+++ clang/test/SemaCXX/paren-list-agg-init.cpp
@@ -9,7 +9,7 @@
 struct B {
   A a;
   int b[20];
-  int & // expected-note {{reference member declared here}}
+  int &
 };
 
 struct C { // expected-note 5{{candidate constructor}}
@@ -21,9 +21,9 @@
   int a;
 };
 
-struct E { // expected-note 3{{candidate constructor}}
-  struct F {
-F(int, int);
+struct E {
+  struct F { // expected-note 2{{candidate constructor}}
+F(int, int); // expected-note {{candidate constructor}}
   };
   int a;
   F f;
@@ -56,6 +56,22 @@
   int b[]; // expected-note {{initialized flexible array member 'b' is here}}
 };
 
+enum K { K0, K1, K2 };
+
+struct L {
+  K k : 1;
+};
+
+struct M {
+  struct N {
+private:
+N(int);
+// expected-note@-1 {{declared private here}}
+  };
+  int i;
+  N n;
+};
+
 union U {
   int a;
   char* b;
@@ -74,7 +90,7 @@
   // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
 }
 
-void foo() {
+void foo(int n) {
   A a1(1954, 9, 21);
   // expected-error@-1 {{excess elements in struct initializer}}
   A a2(2.1);
@@ -96,9 +112,8 @@
   B b1(2022, {7, 8});
   // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
   B b2(A(1), {}, 1);
-  // expected-error@-1 {{reference member 'c' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
-  // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
-  // beforecxx20-warning@-3 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
 
   C c(A(1), 1, 2, 3, 4);
   // expected-error@-1 {{array initializer must be an initializer list}}
@@ -130,7 +145,7 @@
   // expected-error@-1 {{excess elements in union initializer}}
 
   E e1(1);
-  // expected-error@-1 {{no matching constructor for initialization of 'E'}}
+  // expected-error@-1 {{no matching constructor for initialization of 'F'}}
 
   constexpr F f1(1);
   // expected-error@-1 {{constexpr variable 'f1' must be initialized by a constant expression}}
@@ -148,18 +163,29 @@
   A a7 = Construct('i', 2.2);
   // beforecxx20-note@-1 {{in instantiation of function template specialization 'Construct' requested here}}
 
+  L l(K::K2);
+  // expected-warning@-1 {{implicit truncation}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'L' from a parenthesized list of values is a C++20 extension}}
+
   int arr4[](1, 2);
   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
 
   int arr5[2](1, 2);
   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
 
+  int arr6[n](1, 2, 3);
+  // expected-error@-1 {{variable-sized object may not be initialized}}
+
   I i(1, 2);
   // expected-error@-1 {{no matching constructor for initialization of 'I'}}
 
   J j(1, {2, 3});
   // expected-error@-1 {{initialization of flexible array member is not allowed}}
 
+  M m(1, 1);
+  // expected-error@-1 {{field of type 'N' has private constructor}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'M' from a parenthesized list of values is a C++20 extension}}
+
   static_assert(__is_trivially_constructible(A, char, double));
   static_assert(__is_trivially_constructible(A, char, int));
   static_assert(__is_trivially_constructible(A, char));
@@ -221,5 +247,22 @@
 N n(43);
 // expected-error@-1 {{field of type 'L' has protected constructor}}
 // beforecxx20-warning@-2 {{aggregate initialization of type 'N' from a parenthesized list of values is a C++20 extension}}
+}
+
+namespace gh61567 {
+struct O {
+  int i;
+  int &
+  // expected-note@-1 {{uninitialized reference member is here}}
+  int & = 1;
+};
+
+O o1(0, 0, 0); // no-error
+// beforecxx20-warning@-1 {{aggregate initialization of type 'O' from a parenthesized list of values 

[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-26 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added a comment.

LGTM, I'll leave approval to @shafik :)




Comment at: clang/lib/Sema/SemaInit.cpp:5379
+} else {
   ArrayLength = Args.size();
+}

Can we assert that we have an `IncompleteArrayType` here? (That is, that we 
don't have a `DependentSizedArrayType`.)



Comment at: clang/lib/Sema/SemaInit.cpp:5513
+  InitializedEntity SubEntity =
+  InitializedEntity::InitializeMember(FD, );
+  InitializationKind SubKind = InitializationKind::CreateValue(

Is there a reason to not use `InitializeMemberFromParenAggInit` here? That'd 
mean we use the same `InitializedEntity` for every case in this loop, and could 
pull it out of the individual `if` branches.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-26 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 517250.
ayzhao added a comment.

add another test


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/Sema/SemaAccess.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/test/CodeGen/paren-list-agg-init.cpp
  clang/test/SemaCXX/paren-list-agg-init.cpp

Index: clang/test/SemaCXX/paren-list-agg-init.cpp
===
--- clang/test/SemaCXX/paren-list-agg-init.cpp
+++ clang/test/SemaCXX/paren-list-agg-init.cpp
@@ -9,7 +9,7 @@
 struct B {
   A a;
   int b[20];
-  int & // expected-note {{reference member declared here}}
+  int &
 };
 
 struct C { // expected-note 5{{candidate constructor}}
@@ -21,9 +21,9 @@
   int a;
 };
 
-struct E { // expected-note 3{{candidate constructor}}
-  struct F {
-F(int, int);
+struct E {
+  struct F { // expected-note 2{{candidate constructor}}
+F(int, int); // expected-note {{candidate constructor}}
   };
   int a;
   F f;
@@ -56,6 +56,22 @@
   int b[]; // expected-note {{initialized flexible array member 'b' is here}}
 };
 
+enum K { K0, K1, K2 };
+
+struct L {
+  K k : 1;
+};
+
+struct M {
+  struct N {
+private:
+N(int);
+// expected-note@-1 {{declared private here}}
+  };
+  int i;
+  N n;
+};
+
 union U {
   int a;
   char* b;
@@ -74,7 +90,7 @@
   // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
 }
 
-void foo() {
+void foo(int n) {
   A a1(1954, 9, 21);
   // expected-error@-1 {{excess elements in struct initializer}}
   A a2(2.1);
@@ -96,9 +112,8 @@
   B b1(2022, {7, 8});
   // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
   B b2(A(1), {}, 1);
-  // expected-error@-1 {{reference member 'c' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
-  // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
-  // beforecxx20-warning@-3 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
 
   C c(A(1), 1, 2, 3, 4);
   // expected-error@-1 {{array initializer must be an initializer list}}
@@ -130,7 +145,7 @@
   // expected-error@-1 {{excess elements in union initializer}}
 
   E e1(1);
-  // expected-error@-1 {{no matching constructor for initialization of 'E'}}
+  // expected-error@-1 {{no matching constructor for initialization of 'F'}}
 
   constexpr F f1(1);
   // expected-error@-1 {{constexpr variable 'f1' must be initialized by a constant expression}}
@@ -148,18 +163,29 @@
   A a7 = Construct('i', 2.2);
   // beforecxx20-note@-1 {{in instantiation of function template specialization 'Construct' requested here}}
 
+  L l(K::K2);
+  // expected-warning@-1 {{implicit truncation}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'L' from a parenthesized list of values is a C++20 extension}}
+
   int arr4[](1, 2);
   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
 
   int arr5[2](1, 2);
   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
 
+  int arr6[n](1, 2, 3);
+  // expected-error@-1 {{variable-sized object may not be initialized}}
+
   I i(1, 2);
   // expected-error@-1 {{no matching constructor for initialization of 'I'}}
 
   J j(1, {2, 3});
   // expected-error@-1 {{initialization of flexible array member is not allowed}}
 
+  M m(1, 1);
+  // expected-error@-1 {{field of type 'N' has private constructor}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'M' from a parenthesized list of values is a C++20 extension}}
+
   static_assert(__is_trivially_constructible(A, char, double));
   static_assert(__is_trivially_constructible(A, char, int));
   static_assert(__is_trivially_constructible(A, char));
@@ -200,3 +226,21 @@
   // expected-error@-1 {{call to implicitly-deleted copy constructor of 'V'}}
 }
 }
+
+namespace gh61567 {
+struct O {
+  int i;
+  int &
+  // expected-note@-1 {{uninitialized reference member is here}}
+  int & = 1;
+};
+
+O o1(0, 0, 0); // no-error
+// beforecxx20-warning@-1 {{aggregate initialization of type 'O' from a parenthesized list of values is a C++20 extension}}
+
+O o2(0, 0); // no-error
+// beforecxx20-warning@-1 {{aggregate initialization of type 'O' from a parenthesized list of values is a C++20 extension}}
+
+O o3(0);
+// expected-error@-1 {{reference 

[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-26 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 517249.
ayzhao added a comment.

add another test and fix whitespace


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/Sema/SemaAccess.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/test/CodeGen/paren-list-agg-init.cpp
  clang/test/SemaCXX/paren-list-agg-init.cpp

Index: clang/test/SemaCXX/paren-list-agg-init.cpp
===
--- clang/test/SemaCXX/paren-list-agg-init.cpp
+++ clang/test/SemaCXX/paren-list-agg-init.cpp
@@ -9,7 +9,7 @@
 struct B {
   A a;
   int b[20];
-  int & // expected-note {{reference member declared here}}
+  int &
 };
 
 struct C { // expected-note 5{{candidate constructor}}
@@ -21,9 +21,9 @@
   int a;
 };
 
-struct E { // expected-note 3{{candidate constructor}}
-  struct F {
-F(int, int);
+struct E {
+  struct F { // expected-note 2{{candidate constructor}}
+F(int, int); // expected-note {{candidate constructor}}
   };
   int a;
   F f;
@@ -56,6 +56,22 @@
   int b[]; // expected-note {{initialized flexible array member 'b' is here}}
 };
 
+enum K { K0, K1, K2 };
+
+struct L {
+  K k : 1;
+};
+
+struct M {
+  struct N {
+private:
+N(int);
+// expected-note@-1 {{declared private here}}
+  };
+  int i;
+  N n;
+};
+
 union U {
   int a;
   char* b;
@@ -74,7 +90,7 @@
   // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
 }
 
-void foo() {
+void foo(int n) {
   A a1(1954, 9, 21);
   // expected-error@-1 {{excess elements in struct initializer}}
   A a2(2.1);
@@ -96,9 +112,8 @@
   B b1(2022, {7, 8});
   // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
   B b2(A(1), {}, 1);
-  // expected-error@-1 {{reference member 'c' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
-  // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
-  // beforecxx20-warning@-3 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
 
   C c(A(1), 1, 2, 3, 4);
   // expected-error@-1 {{array initializer must be an initializer list}}
@@ -130,7 +145,7 @@
   // expected-error@-1 {{excess elements in union initializer}}
 
   E e1(1);
-  // expected-error@-1 {{no matching constructor for initialization of 'E'}}
+  // expected-error@-1 {{no matching constructor for initialization of 'F'}}
 
   constexpr F f1(1);
   // expected-error@-1 {{constexpr variable 'f1' must be initialized by a constant expression}}
@@ -148,18 +163,29 @@
   A a7 = Construct('i', 2.2);
   // beforecxx20-note@-1 {{in instantiation of function template specialization 'Construct' requested here}}
 
+  L l(K::K2);
+  // expected-warning@-1 {{implicit truncation}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'L' from a parenthesized list of values is a C++20 extension}}
+
   int arr4[](1, 2);
   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
 
   int arr5[2](1, 2);
   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
 
+  int arr6[n](1, 2, 3);
+  // expected-error@-1 {{variable-sized object may not be initialized}}
+
   I i(1, 2);
   // expected-error@-1 {{no matching constructor for initialization of 'I'}}
 
   J j(1, {2, 3});
   // expected-error@-1 {{initialization of flexible array member is not allowed}}
 
+  M m(1, 1);
+  // expected-error@-1 {{field of type 'N' has private constructor}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'M' from a parenthesized list of values is a C++20 extension}}
+
   static_assert(__is_trivially_constructible(A, char, double));
   static_assert(__is_trivially_constructible(A, char, int));
   static_assert(__is_trivially_constructible(A, char));
@@ -200,3 +226,18 @@
   // expected-error@-1 {{call to implicitly-deleted copy constructor of 'V'}}
 }
 }
+
+namespace gh61567 {
+struct O {
+  int i;
+  int & = 1;
+  int &
+  // expected-note@-1 {{uninitialized reference member is here}}
+};
+
+O o2(0, 0, 0); // no-error
+// beforecxx20-warning@-1 {{aggregate initialization of type 'O' from a parenthesized list of values is a C++20 extension}}
+
+O o1(0);
+// expected-error@-1 {{reference member of type 'int &&' uninitialized}}
+}
Index: clang/test/CodeGen/paren-list-agg-init.cpp

[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-26 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added inline comments.



Comment at: clang/lib/Sema/SemaInit.cpp:5364-5368
 if (const ConstantArrayType *CAT =
 S.getASTContext().getAsConstantArrayType(Entity.getType()))
   ArrayLength = CAT->getSize().getZExtValue();
 else
   ArrayLength = Args.size();

rsmith wrote:
> What happens if the array is of `VariableArrayType` or 
> `DependentSizedArrayType`? I guess we shouldn't get here in the latter case, 
> but the former case seems possible, and presumably shouldn't result in 
> constructing a value of `ConstantArrayType`. 
> [Test](https://godbolt.org/z/377TWzn7r):
> 
> ```
> constexpr int f(int n, int i) {
> int arr[n](1, 2, 3);
> return arr[i];
> }
> 
> constexpr int a = f(1, 2);
> constexpr int b = f(4, 3);
> ```
> 
> GCC appears to leave the type alone in this case, and treats the evaluation 
> as UB if `n` is less than the number of initializers given. That matches what 
> GCC does for a `{...}` initializer of a VLA. We should probably match what 
> Clang does for `{...}` initialization of a VLA and reject.
Clang simply does not allow braced-initialization for `VariableArrayType`, even 
if `n` is greater than or equal to the number of initializers given:  
https://godbolt.org/z/MaPjvn694. I updated the patch to make parenthesized 
aggregate initialization do the same thing.



Comment at: clang/lib/Sema/SemaInit.cpp:5391-5393
+ResultType = S.Context.getConstantArrayType(
+AT->getElementType(), llvm::APInt(/*numBits=*/32, ArrayLength),
+/*SizeExpr=*/nullptr, ArrayType::Normal, 0);

rsmith wrote:
> It would be nice to use the original type here in the case where we didn't 
> add an array bound, so we preserve type sugar (typedefs etc). Also, do we 
> ever need to preserve type qualifiers from the original entity's type?
> It would be nice to use the original type here in the case where we didn't 
> add an array bound, so we preserve type sugar (typedefs etc).

Done 

> Also, do we ever need to preserve type qualifiers from the original entity's 
> type?

I don't think so. In the case of `IncompleteArrayType`, which is the only 
situation where we would need to deduce the `ConstantArrayType` based on the 
number of arguments, the corresponding `QualType` object is always created with 
`Quals = 0` [0].

[0]: 
https://github.com/llvm/llvm-project/blob/c95533a7be2858893ec32b8abaa37a2d912ebe63/clang/lib/AST/ASTContext.cpp#L3888



Comment at: clang/lib/Sema/SemaInit.cpp:5401
+InitializedEntity SubEntity =
+InitializedEntity::InitializeBase(S.getASTContext(), , false);
+if (EntityIndexToProcess < Args.size()) {

rsmith wrote:
> Does this have the same wrong-lifetime-kind problem as members did?
I don't think so:

1. This will never initialize a reference because it's initializing a base 
class.
1. In the case where the constructor of a base class accepts a reference 
parameter, the lifetime is not extended: https://godbolt.org/z/MaqhTr1rP



Comment at: clang/lib/Sema/SemaInit.cpp:5476
+  InitializedEntity SubEntity =
+  InitializedEntity::InitializeMemberFromDefaultMemberInitializer(
+  FD);

rsmith wrote:
> Does this entity kind do the right thing for lifetime warnings? (I'm not sure 
> why this is a distinct kind of `InitializedEntity`; the thing that changes 
> here is not the entity, it's how it's initialized.)
This now uses `InitializeMemberFromParenAggInit(..)` (before, it would emit 
[the same error it emits for braced init 
lists](https://godbolt.org/z/d3qfzh73z)). I also added a test for this.



Comment at: clang/lib/Sema/SemaInit.cpp:5486-5487
+  //   The remaining elements...otherwise are value initialzed
+  InitializedEntity SubEntity =
+  InitializedEntity::InitializeMember(FD, );
+  InitializationKind SubKind = InitializationKind::CreateValue(

rsmith wrote:
> Is there any possibility of lifetime warnings here? I don't *think* value 
> initialization can ever create problems, but it would seem more obviously 
> right to use the parenthesized aggregate initialization entity kind here.
GCC rejects value initialization of references: https://godbolt.org/z/nhhehrf7r

This patch currently rejects value initialization of references, but I updated 
the diagnostics to match those Clang emits with braced initialization: 
https://godbolt.org/z/rbh17ecqe


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-26 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 517246.
ayzhao marked 5 inline comments as done.
ayzhao added a comment.

code review comments + rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/Sema/SemaAccess.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/test/CodeGen/paren-list-agg-init.cpp
  clang/test/SemaCXX/paren-list-agg-init.cpp

Index: clang/test/SemaCXX/paren-list-agg-init.cpp
===
--- clang/test/SemaCXX/paren-list-agg-init.cpp
+++ clang/test/SemaCXX/paren-list-agg-init.cpp
@@ -9,7 +9,7 @@
 struct B {
   A a;
   int b[20];
-  int & // expected-note {{reference member declared here}}
+  int &
 };
 
 struct C { // expected-note 5{{candidate constructor}}
@@ -21,9 +21,9 @@
   int a;
 };
 
-struct E { // expected-note 3{{candidate constructor}}
-  struct F {
-F(int, int);
+struct E {
+  struct F { // expected-note 2{{candidate constructor}}
+F(int, int); // expected-note {{candidate constructor}}
   };
   int a;
   F f;
@@ -56,6 +56,22 @@
   int b[]; // expected-note {{initialized flexible array member 'b' is here}}
 };
 
+enum K { K0, K1, K2 };
+
+struct L {
+  K k : 1;
+};
+
+struct M {
+  struct N {
+private:
+N(int);
+// expected-note@-1 {{declared private here}}
+  };
+  int i;
+  N n;
+};
+
 union U {
   int a;
   char* b;
@@ -74,7 +90,7 @@
   // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
 }
 
-void foo() {
+void foo(int n) {
   A a1(1954, 9, 21);
   // expected-error@-1 {{excess elements in struct initializer}}
   A a2(2.1);
@@ -96,9 +112,8 @@
   B b1(2022, {7, 8});
   // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
   B b2(A(1), {}, 1);
-  // expected-error@-1 {{reference member 'c' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
-  // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
-  // beforecxx20-warning@-3 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
 
   C c(A(1), 1, 2, 3, 4);
   // expected-error@-1 {{array initializer must be an initializer list}}
@@ -130,12 +145,12 @@
   // expected-error@-1 {{excess elements in union initializer}}
 
   E e1(1);
-  // expected-error@-1 {{no matching constructor for initialization of 'E'}}
+  // expected-error@-1 {{no matching constructor for initialization of 'F'}}
 
   constexpr F f1(1);
   // expected-error@-1 {{constexpr variable 'f1' must be initialized by a constant expression}}
   // beforecxx20-warning@-2 {{aggregate initialization of type 'const F' from a parenthesized list of values is a C++20 extension}}
-
+  
   constexpr F f2(1, 1); // OK: f2.b is initialized by a constant expression.
   // beforecxx20-warning@-1 {{aggregate initialization of type 'const F' from a parenthesized list of values is a C++20 extension}}
 
@@ -148,18 +163,29 @@
   A a7 = Construct('i', 2.2);
   // beforecxx20-note@-1 {{in instantiation of function template specialization 'Construct' requested here}}
 
+  L l(K::K2);
+  // expected-warning@-1 {{implicit truncation}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'L' from a parenthesized list of values is a C++20 extension}}
+
   int arr4[](1, 2);
   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
 
   int arr5[2](1, 2);
   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
 
+  int arr6[n](1, 2, 3);
+  // expected-error@-1 {{variable-sized object may not be initialized}}
+
   I i(1, 2);
   // expected-error@-1 {{no matching constructor for initialization of 'I'}}
 
   J j(1, {2, 3});
   // expected-error@-1 {{initialization of flexible array member is not allowed}}
 
+  M m(1, 1);
+  // expected-error@-1 {{field of type 'N' has private constructor}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'M' from a parenthesized list of values is a C++20 extension}}
+
   static_assert(__is_trivially_constructible(A, char, double));
   static_assert(__is_trivially_constructible(A, char, int));
   static_assert(__is_trivially_constructible(A, char));
@@ -200,3 +226,14 @@
   // expected-error@-1 {{call to implicitly-deleted copy constructor of 'V'}}
 }
 }
+
+namespace gh61567 {
+struct O {
+  int i;
+  int &
+  // expected-note@-1 

[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-24 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: clang/lib/Sema/SemaInit.cpp:5364-5368
 if (const ConstantArrayType *CAT =
 S.getASTContext().getAsConstantArrayType(Entity.getType()))
   ArrayLength = CAT->getSize().getZExtValue();
 else
   ArrayLength = Args.size();

What happens if the array is of `VariableArrayType` or 
`DependentSizedArrayType`? I guess we shouldn't get here in the latter case, 
but the former case seems possible, and presumably shouldn't result in 
constructing a value of `ConstantArrayType`. 
[Test](https://godbolt.org/z/377TWzn7r):

```
constexpr int f(int n, int i) {
int arr[n](1, 2, 3);
return arr[i];
}

constexpr int a = f(1, 2);
constexpr int b = f(4, 3);
```

GCC appears to leave the type alone in this case, and treats the evaluation as 
UB if `n` is less than the number of initializers given. That matches what GCC 
does for a `{...}` initializer of a VLA. We should probably match what Clang 
does for `{...}` initialization of a VLA and reject.



Comment at: clang/lib/Sema/SemaInit.cpp:5391-5393
+ResultType = S.Context.getConstantArrayType(
+AT->getElementType(), llvm::APInt(/*numBits=*/32, ArrayLength),
+/*SizeExpr=*/nullptr, ArrayType::Normal, 0);

It would be nice to use the original type here in the case where we didn't add 
an array bound, so we preserve type sugar (typedefs etc). Also, do we ever need 
to preserve type qualifiers from the original entity's type?



Comment at: clang/lib/Sema/SemaInit.cpp:5401
+InitializedEntity SubEntity =
+InitializedEntity::InitializeBase(S.getASTContext(), , false);
+if (EntityIndexToProcess < Args.size()) {

Does this have the same wrong-lifetime-kind problem as members did?



Comment at: clang/lib/Sema/SemaInit.cpp:5476
+  InitializedEntity SubEntity =
+  InitializedEntity::InitializeMemberFromDefaultMemberInitializer(
+  FD);

Does this entity kind do the right thing for lifetime warnings? (I'm not sure 
why this is a distinct kind of `InitializedEntity`; the thing that changes here 
is not the entity, it's how it's initialized.)



Comment at: clang/lib/Sema/SemaInit.cpp:5486-5487
+  //   The remaining elements...otherwise are value initialzed
+  InitializedEntity SubEntity =
+  InitializedEntity::InitializeMember(FD, );
+  InitializationKind SubKind = InitializationKind::CreateValue(

Is there any possibility of lifetime warnings here? I don't *think* value 
initialization can ever create problems, but it would seem more obviously right 
to use the parenthesized aggregate initialization entity kind here.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-17 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 514425.
ayzhao marked 3 inline comments as done.
ayzhao added a comment.

code review comments + rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/Sema/SemaAccess.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/test/CodeGen/paren-list-agg-init.cpp
  clang/test/SemaCXX/paren-list-agg-init.cpp

Index: clang/test/SemaCXX/paren-list-agg-init.cpp
===
--- clang/test/SemaCXX/paren-list-agg-init.cpp
+++ clang/test/SemaCXX/paren-list-agg-init.cpp
@@ -9,7 +9,7 @@
 struct B {
   A a;
   int b[20];
-  int & // expected-note {{reference member declared here}}
+  int &
 };
 
 struct C { // expected-note 5{{candidate constructor}}
@@ -21,9 +21,9 @@
   int a;
 };
 
-struct E { // expected-note 3{{candidate constructor}}
-  struct F {
-F(int, int);
+struct E {
+  struct F { // expected-note 2{{candidate constructor}}
+F(int, int); // expected-note {{candidate constructor}}
   };
   int a;
   F f;
@@ -56,6 +56,12 @@
   int b[]; // expected-note {{initialized flexible array member 'b' is here}}
 };
 
+enum K { K0, K1, K2 };
+
+struct L {
+  K k : 1;
+};
+
 union U {
   int a;
   char* b;
@@ -96,9 +102,8 @@
   B b1(2022, {7, 8});
   // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
   B b2(A(1), {}, 1);
-  // expected-error@-1 {{reference member 'c' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
-  // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
-  // beforecxx20-warning@-3 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
 
   C c(A(1), 1, 2, 3, 4);
   // expected-error@-1 {{array initializer must be an initializer list}}
@@ -130,7 +135,7 @@
   // expected-error@-1 {{excess elements in union initializer}}
 
   E e1(1);
-  // expected-error@-1 {{no matching constructor for initialization of 'E'}}
+  // expected-error@-1 {{no matching constructor for initialization of 'F'}}
 
   constexpr F f1(1);
   // expected-error@-1 {{constexpr variable 'f1' must be initialized by a constant expression}}
@@ -148,6 +153,10 @@
   A a7 = Construct('i', 2.2);
   // beforecxx20-note@-1 {{in instantiation of function template specialization 'Construct' requested here}}
 
+  L l(K::K2);
+  // expected-warning@-1 {{implicit truncation}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'L' from a parenthesized list of values is a C++20 extension}}
+
   int arr4[](1, 2);
   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
 
@@ -200,3 +209,21 @@
   // expected-error@-1 {{call to implicitly-deleted copy constructor of 'V'}}
 }
 }
+
+namespace gh61567 {
+  struct K {
+struct L {
+ private:
+  L(int);
+  // expected-note@-1 {{declared private here}}
+};
+int i;
+L l;
+  };
+
+  void foo() {
+K k(1, 1);
+// expected-error@-1 {{field of type 'L' has private constructor}}
+// beforecxx20-warning@-2 {{aggregate initialization of type 'K' from a parenthesized list of values is a C++20 extension}}
+  }
+}
Index: clang/test/CodeGen/paren-list-agg-init.cpp
===
--- clang/test/CodeGen/paren-list-agg-init.cpp
+++ clang/test/CodeGen/paren-list-agg-init.cpp
@@ -90,6 +90,14 @@
   };
 }
 
+namespace gh61567 {
+  // CHECK-DAG: [[STRUCT_H:%.*H.*]] = type { i32, ptr }
+  struct H {
+int a;
+int&& r;
+  };
+}
+
 // CHECK-DAG: [[A1:@.*a1.*]] = internal constant [[STRUCT_A]] { i8 3, double 2.00e+00 }, align 8
 constexpr A a1(3.1, 2.0);
 // CHECK-DAG: [[A2:@.*a2.*]] = internal constant [[STRUCT_A]] { i8 99, double 0.00e+00 }, align 8
@@ -421,3 +429,50 @@
 make2<0>();
   }
 }
+
+namespace gh61567 {
+  int foo20();
+
+  // CHECK: define {{.*}} void @{{.*foo21.*}} {
+  // CHECK-NEXT: entry
+  // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_H]], align 8
+  // CHECK-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4
+  // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0
+  // CHECK-NEXT: store i32 0, ptr [[A]], align 8
+  // CHECK-NEXT: [[R:%.*r.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 1
+  // CHECK-NEXT: store i32 1, ptr [[REF_TMP]], align 4
+  // CHECK-NEXT: store ptr [[REF_TMP]], ptr [[R]], align 8
+  // CHECK-NEXT: 

[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-17 Thread Shafik Yaghmour via Phabricator via cfe-commits
shafik added a comment.

I am mostly done but others should also look at this.




Comment at: clang/lib/Sema/SemaInit.cpp:5348
+  };
+  ExprResult ER = CreateExprResult();
+  if (InitExpr)

Why not just use a conditional expression here or alternatively just turn it 
into an IIILE?



Comment at: clang/lib/Sema/SemaInit.cpp:5394
+ResultType = S.Context.getConstantArrayType(
+AT->getElementType(), llvm::APInt(/*numBits=*/32, ArrayLength), 
nullptr,
+ArrayType::Normal, 0);





Comment at: clang/lib/Sema/SemaInit.cpp:5421
+  InitializationKind SubKind = InitializationKind::CreateValue(
+  Kind.getLocation(), Kind.getLocation(), Kind.getLocation(), 
true);
+  if (!HandleInitializedEntity(SubEntity, SubKind, nullptr))




Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-17 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 514389.
ayzhao marked an inline comment as done.
ayzhao added a comment.

remove unrelated formatting changes


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/Sema/SemaAccess.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/test/CodeGen/paren-list-agg-init.cpp
  clang/test/SemaCXX/paren-list-agg-init.cpp

Index: clang/test/SemaCXX/paren-list-agg-init.cpp
===
--- clang/test/SemaCXX/paren-list-agg-init.cpp
+++ clang/test/SemaCXX/paren-list-agg-init.cpp
@@ -9,7 +9,7 @@
 struct B {
   A a;
   int b[20];
-  int & // expected-note {{reference member declared here}}
+  int &
 };
 
 struct C { // expected-note 5{{candidate constructor}}
@@ -21,9 +21,9 @@
   int a;
 };
 
-struct E { // expected-note 3{{candidate constructor}}
-  struct F {
-F(int, int);
+struct E {
+  struct F { // expected-note 2{{candidate constructor}}
+F(int, int); // expected-note {{candidate constructor}}
   };
   int a;
   F f;
@@ -56,6 +56,12 @@
   int b[]; // expected-note {{initialized flexible array member 'b' is here}}
 };
 
+enum K { K0, K1, K2 };
+
+struct L {
+  K k : 1;
+};
+
 union U {
   int a;
   char* b;
@@ -96,9 +102,8 @@
   B b1(2022, {7, 8});
   // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
   B b2(A(1), {}, 1);
-  // expected-error@-1 {{reference member 'c' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
-  // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
-  // beforecxx20-warning@-3 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
 
   C c(A(1), 1, 2, 3, 4);
   // expected-error@-1 {{array initializer must be an initializer list}}
@@ -130,7 +135,7 @@
   // expected-error@-1 {{excess elements in union initializer}}
 
   E e1(1);
-  // expected-error@-1 {{no matching constructor for initialization of 'E'}}
+  // expected-error@-1 {{no matching constructor for initialization of 'F'}}
 
   constexpr F f1(1);
   // expected-error@-1 {{constexpr variable 'f1' must be initialized by a constant expression}}
@@ -148,6 +153,10 @@
   A a7 = Construct('i', 2.2);
   // beforecxx20-note@-1 {{in instantiation of function template specialization 'Construct' requested here}}
 
+  L l(K::K2);
+  // expected-warning@-1 {{implicit truncation}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'L' from a parenthesized list of values is a C++20 extension}}
+
   int arr4[](1, 2);
   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
 
@@ -200,3 +209,21 @@
   // expected-error@-1 {{call to implicitly-deleted copy constructor of 'V'}}
 }
 }
+
+namespace gh61567 {
+  struct K {
+struct L {
+ private:
+  L(int);
+  // expected-note@-1 {{declared private here}}
+};
+int i;
+L l;
+  };
+
+  void foo() {
+K k(1, 1);
+// expected-error@-1 {{field of type 'L' has private constructor}}
+// beforecxx20-warning@-2 {{aggregate initialization of type 'K' from a parenthesized list of values is a C++20 extension}}
+  }
+}
Index: clang/test/CodeGen/paren-list-agg-init.cpp
===
--- clang/test/CodeGen/paren-list-agg-init.cpp
+++ clang/test/CodeGen/paren-list-agg-init.cpp
@@ -90,6 +90,14 @@
   };
 }
 
+namespace gh61567 {
+  // CHECK-DAG: [[STRUCT_H:%.*H.*]] = type { i32, ptr }
+  struct H {
+int a;
+int&& r;
+  };
+}
+
 // CHECK-DAG: [[A1:@.*a1.*]] = internal constant [[STRUCT_A]] { i8 3, double 2.00e+00 }, align 8
 constexpr A a1(3.1, 2.0);
 // CHECK-DAG: [[A2:@.*a2.*]] = internal constant [[STRUCT_A]] { i8 99, double 0.00e+00 }, align 8
@@ -421,3 +429,50 @@
 make2<0>();
   }
 }
+
+namespace gh61567 {
+  int foo20();
+
+  // CHECK: define {{.*}} void @{{.*foo21.*}} {
+  // CHECK-NEXT: entry
+  // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_H]], align 8
+  // CHECK-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4
+  // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0
+  // CHECK-NEXT: store i32 0, ptr [[A]], align 8
+  // CHECK-NEXT: [[R:%.*r.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 1
+  // CHECK-NEXT: store i32 1, ptr [[REF_TMP]], align 4
+  // CHECK-NEXT: store ptr [[REF_TMP]], ptr [[R]], align 8
+  // 

[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-17 Thread Shafik Yaghmour via Phabricator via cfe-commits
shafik added inline comments.



Comment at: clang/lib/Sema/SemaInit.cpp:9723
+// initialize this base/member.
+CXXConstructorDecl *Constructor =
+cast(S.CurContext);

This and the changes below looks like unrelated formatting changes.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-17 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 514291.
ayzhao added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/Sema/SemaAccess.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/test/CodeGen/paren-list-agg-init.cpp
  clang/test/SemaCXX/paren-list-agg-init.cpp

Index: clang/test/SemaCXX/paren-list-agg-init.cpp
===
--- clang/test/SemaCXX/paren-list-agg-init.cpp
+++ clang/test/SemaCXX/paren-list-agg-init.cpp
@@ -9,7 +9,7 @@
 struct B {
   A a;
   int b[20];
-  int & // expected-note {{reference member declared here}}
+  int &
 };
 
 struct C { // expected-note 5{{candidate constructor}}
@@ -21,9 +21,9 @@
   int a;
 };
 
-struct E { // expected-note 3{{candidate constructor}}
-  struct F {
-F(int, int);
+struct E {
+  struct F { // expected-note 2{{candidate constructor}}
+F(int, int); // expected-note {{candidate constructor}}
   };
   int a;
   F f;
@@ -56,6 +56,12 @@
   int b[]; // expected-note {{initialized flexible array member 'b' is here}}
 };
 
+enum K { K0, K1, K2 };
+
+struct L {
+  K k : 1;
+};
+
 union U {
   int a;
   char* b;
@@ -96,9 +102,8 @@
   B b1(2022, {7, 8});
   // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
   B b2(A(1), {}, 1);
-  // expected-error@-1 {{reference member 'c' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
-  // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
-  // beforecxx20-warning@-3 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
 
   C c(A(1), 1, 2, 3, 4);
   // expected-error@-1 {{array initializer must be an initializer list}}
@@ -130,7 +135,7 @@
   // expected-error@-1 {{excess elements in union initializer}}
 
   E e1(1);
-  // expected-error@-1 {{no matching constructor for initialization of 'E'}}
+  // expected-error@-1 {{no matching constructor for initialization of 'F'}}
 
   constexpr F f1(1);
   // expected-error@-1 {{constexpr variable 'f1' must be initialized by a constant expression}}
@@ -148,6 +153,10 @@
   A a7 = Construct('i', 2.2);
   // beforecxx20-note@-1 {{in instantiation of function template specialization 'Construct' requested here}}
 
+  L l(K::K2);
+  // expected-warning@-1 {{implicit truncation}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'L' from a parenthesized list of values is a C++20 extension}}
+
   int arr4[](1, 2);
   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
 
@@ -200,3 +209,21 @@
   // expected-error@-1 {{call to implicitly-deleted copy constructor of 'V'}}
 }
 }
+
+namespace gh61567 {
+  struct K {
+struct L {
+ private:
+  L(int);
+  // expected-note@-1 {{declared private here}}
+};
+int i;
+L l;
+  };
+
+  void foo() {
+K k(1, 1);
+// expected-error@-1 {{field of type 'L' has private constructor}}
+// beforecxx20-warning@-2 {{aggregate initialization of type 'K' from a parenthesized list of values is a C++20 extension}}
+  }
+}
Index: clang/test/CodeGen/paren-list-agg-init.cpp
===
--- clang/test/CodeGen/paren-list-agg-init.cpp
+++ clang/test/CodeGen/paren-list-agg-init.cpp
@@ -90,6 +90,14 @@
   };
 }
 
+namespace gh61567 {
+  // CHECK-DAG: [[STRUCT_H:%.*H.*]] = type { i32, ptr }
+  struct H {
+int a;
+int&& r;
+  };
+}
+
 // CHECK-DAG: [[A1:@.*a1.*]] = internal constant [[STRUCT_A]] { i8 3, double 2.00e+00 }, align 8
 constexpr A a1(3.1, 2.0);
 // CHECK-DAG: [[A2:@.*a2.*]] = internal constant [[STRUCT_A]] { i8 99, double 0.00e+00 }, align 8
@@ -421,3 +429,50 @@
 make2<0>();
   }
 }
+
+namespace gh61567 {
+  int foo20();
+
+  // CHECK: define {{.*}} void @{{.*foo21.*}} {
+  // CHECK-NEXT: entry
+  // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_H]], align 8
+  // CHECK-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4
+  // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0
+  // CHECK-NEXT: store i32 0, ptr [[A]], align 8
+  // CHECK-NEXT: [[R:%.*r.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 1
+  // CHECK-NEXT: store i32 1, ptr [[REF_TMP]], align 4
+  // CHECK-NEXT: store ptr [[REF_TMP]], ptr [[R]], align 8
+  // CHECK-NEXT: ret void
+  void foo21() {
+H(0, 1);
+  }
+
+  // CHECK: 

[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-14 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 513808.
ayzhao added a comment.

fix comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/Sema/SemaAccess.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/test/CodeGen/paren-list-agg-init.cpp
  clang/test/SemaCXX/paren-list-agg-init.cpp

Index: clang/test/SemaCXX/paren-list-agg-init.cpp
===
--- clang/test/SemaCXX/paren-list-agg-init.cpp
+++ clang/test/SemaCXX/paren-list-agg-init.cpp
@@ -9,7 +9,7 @@
 struct B {
   A a;
   int b[20];
-  int & // expected-note {{reference member declared here}}
+  int &
 };
 
 struct C { // expected-note 5{{candidate constructor}}
@@ -21,9 +21,9 @@
   int a;
 };
 
-struct E { // expected-note 3{{candidate constructor}}
-  struct F {
-F(int, int);
+struct E {
+  struct F { // expected-note 2{{candidate constructor}}
+F(int, int); // expected-note {{candidate constructor}}
   };
   int a;
   F f;
@@ -56,6 +56,12 @@
   int b[]; // expected-note {{initialized flexible array member 'b' is here}}
 };
 
+enum K { K0, K1, K2 };
+
+struct L {
+  K k : 1;
+};
+
 union U {
   int a;
   char* b;
@@ -96,9 +102,8 @@
   B b1(2022, {7, 8});
   // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
   B b2(A(1), {}, 1);
-  // expected-error@-1 {{reference member 'c' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
-  // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
-  // beforecxx20-warning@-3 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
 
   C c(A(1), 1, 2, 3, 4);
   // expected-error@-1 {{array initializer must be an initializer list}}
@@ -130,7 +135,7 @@
   // expected-error@-1 {{excess elements in union initializer}}
 
   E e1(1);
-  // expected-error@-1 {{no matching constructor for initialization of 'E'}}
+  // expected-error@-1 {{no matching constructor for initialization of 'F'}}
 
   constexpr F f1(1);
   // expected-error@-1 {{constexpr variable 'f1' must be initialized by a constant expression}}
@@ -148,6 +153,10 @@
   A a7 = Construct('i', 2.2);
   // beforecxx20-note@-1 {{in instantiation of function template specialization 'Construct' requested here}}
 
+  L l(K::K2);
+  // expected-warning@-1 {{implicit truncation}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'L' from a parenthesized list of values is a C++20 extension}}
+
   int arr4[](1, 2);
   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
 
@@ -200,3 +209,21 @@
   // expected-error@-1 {{call to implicitly-deleted copy constructor of 'V'}}
 }
 }
+
+namespace gh61567 {
+  struct K {
+struct L {
+ private:
+  L(int);
+  // expected-note@-1 {{declared private here}}
+};
+int i;
+L l;
+  };
+
+  void foo() {
+K k(1, 1);
+// expected-error@-1 {{field of type 'L' has private constructor}}
+// beforecxx20-warning@-2 {{aggregate initialization of type 'K' from a parenthesized list of values is a C++20 extension}}
+  }
+}
Index: clang/test/CodeGen/paren-list-agg-init.cpp
===
--- clang/test/CodeGen/paren-list-agg-init.cpp
+++ clang/test/CodeGen/paren-list-agg-init.cpp
@@ -90,6 +90,14 @@
   };
 }
 
+namespace gh61567 {
+  // CHECK-DAG: [[STRUCT_H:%.*H.*]] = type { i32, ptr }
+  struct H {
+int a;
+int&& r;
+  };
+}
+
 // CHECK-DAG: [[A1:@.*a1.*]] = internal constant [[STRUCT_A]] { i8 3, double 2.00e+00 }, align 8
 constexpr A a1(3.1, 2.0);
 // CHECK-DAG: [[A2:@.*a2.*]] = internal constant [[STRUCT_A]] { i8 99, double 0.00e+00 }, align 8
@@ -421,3 +429,50 @@
 make2<0>();
   }
 }
+
+namespace gh61567 {
+  int foo20();
+
+  // CHECK: define {{.*}} void @{{.*foo21.*}} {
+  // CHECK-NEXT: entry
+  // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_H]], align 8
+  // CHECK-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4
+  // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0
+  // CHECK-NEXT: store i32 0, ptr [[A]], align 8
+  // CHECK-NEXT: [[R:%.*r.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 1
+  // CHECK-NEXT: store i32 1, ptr [[REF_TMP]], align 4
+  // CHECK-NEXT: store ptr [[REF_TMP]], ptr [[R]], align 8
+  // CHECK-NEXT: ret void
+  void foo21() {
+H(0, 1);
+  }
+
+  // 

[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-14 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added inline comments.



Comment at: clang/include/clang/Sema/Initialization.h:509
   bool isImplicitMemberInitializer() const {
-return getKind() == EK_Member && Variable.IsImplicitFieldInit;
+return (getKind() == EK_Member || getKind() == EK_ParenAggInitMember) &&
+   Variable.IsImplicitFieldInit;

shafik wrote:
> Does this really apply? It looks like this function is only used in 
> `canPerformArrayCopy`
Reverted.

Also reverted `isDefaultMemberInitializer` since this is never true for 
`EK_ParenAggInitMember`



Comment at: clang/lib/Sema/SemaInit.cpp:583
+  EK == InitializedEntity::EK_Member ||
+  EK == InitializedEntity::EK_ParenAggInitMember)
 SemaRef.Diag(Entity.getDecl()->getLocation(),

shafik wrote:
> I don't see a test triggering this diagnostic for parens init.
Removed since this is part of `InitListChecker` and 
`InitializedEntity::EK_ParenAggInitMember` does not get created when an 
`InitListExpr` is created.



Comment at: clang/lib/Sema/SemaInit.cpp:597
+  EK == InitializedEntity::EK_Member ||
+  EK == InitializedEntity::EK_ParenAggInitMember)
 SemaRef.Diag(Entity.getDecl()->getLocation(),

shafik wrote:
> I don't see a test triggering this diagnostic for parens init.
Removed.



Comment at: clang/lib/Sema/SemaInit.cpp:5332
+if (Arg)
+  IS.Diagnose(S, SubEntity, SubKind, Arg);
+else

shafik wrote:
> Do we have tests that trigger this diagnostic and the one right below?
Yes:

* For when `Arg` is non-null (failing to initializing members with provided 
argument): 
https://github.com/llvm/llvm-project/blob/af78197857115716802189ef073f83cdac9ede15/clang/test/SemaCXX/paren-list-agg-init.cpp#L96-L97
* For when `Arg` is null (failing to value or default-initialize a member): 
https://github.com/llvm/llvm-project/blob/af78197857115716802189ef073f83cdac9ede15/clang/test/SemaCXX/paren-list-agg-init.cpp#L132-L133
 (diagnostics have been fixed in this patch, see [my 
comment](https://reviews.llvm.org/D148274#4266575) in 
`SemaCXX/paren-list-agg-init.cpp`).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-14 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 513805.
ayzhao marked 7 inline comments as done.
ayzhao added a comment.

Address code review comments and (try) to fix Windows bot failure


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/Sema/SemaAccess.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/test/CodeGen/paren-list-agg-init.cpp
  clang/test/SemaCXX/paren-list-agg-init.cpp

Index: clang/test/SemaCXX/paren-list-agg-init.cpp
===
--- clang/test/SemaCXX/paren-list-agg-init.cpp
+++ clang/test/SemaCXX/paren-list-agg-init.cpp
@@ -9,7 +9,7 @@
 struct B {
   A a;
   int b[20];
-  int & // expected-note {{reference member declared here}}
+  int &
 };
 
 struct C { // expected-note 5{{candidate constructor}}
@@ -21,9 +21,9 @@
   int a;
 };
 
-struct E { // expected-note 3{{candidate constructor}}
-  struct F {
-F(int, int);
+struct E {
+  struct F { // expected-note 2{{candidate constructor}}
+F(int, int); // expected-note {{candidate constructor}}
   };
   int a;
   F f;
@@ -56,6 +56,12 @@
   int b[]; // expected-note {{initialized flexible array member 'b' is here}}
 };
 
+enum K { K0, K1, K2 };
+
+struct L {
+  K k : 1;
+};
+
 union U {
   int a;
   char* b;
@@ -96,9 +102,8 @@
   B b1(2022, {7, 8});
   // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
   B b2(A(1), {}, 1);
-  // expected-error@-1 {{reference member 'c' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
-  // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
-  // beforecxx20-warning@-3 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
 
   C c(A(1), 1, 2, 3, 4);
   // expected-error@-1 {{array initializer must be an initializer list}}
@@ -130,7 +135,7 @@
   // expected-error@-1 {{excess elements in union initializer}}
 
   E e1(1);
-  // expected-error@-1 {{no matching constructor for initialization of 'E'}}
+  // expected-error@-1 {{no matching constructor for initialization of 'F'}}
 
   constexpr F f1(1);
   // expected-error@-1 {{constexpr variable 'f1' must be initialized by a constant expression}}
@@ -148,6 +153,10 @@
   A a7 = Construct('i', 2.2);
   // beforecxx20-note@-1 {{in instantiation of function template specialization 'Construct' requested here}}
 
+  L l(K::K2);
+  // expected-warning@-1 {{implicit truncation}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'L' from a parenthesized list of values is a C++20 extension}}
+
   int arr4[](1, 2);
   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
 
@@ -200,3 +209,21 @@
   // expected-error@-1 {{call to implicitly-deleted copy constructor of 'V'}}
 }
 }
+
+namespace gh61567 {
+  struct K {
+struct L {
+ private:
+  L(int);
+  // expected-note@-1 {{declared private here}}
+};
+int i;
+L l;
+  };
+
+  void foo() {
+K k(1, 1);
+// expected-error@-1 {{field of type 'L' has private constructor}}
+// beforecxx20-warning@-2 {{aggregate initialization of type 'K' from a parenthesized list of values is a C++20 extension}}
+  }
+}
Index: clang/test/CodeGen/paren-list-agg-init.cpp
===
--- clang/test/CodeGen/paren-list-agg-init.cpp
+++ clang/test/CodeGen/paren-list-agg-init.cpp
@@ -90,6 +90,14 @@
   };
 }
 
+namespace gh61567 {
+  // CHECK-DAG: [[STRUCT_H:%.*H.*]] = type { i32, ptr }
+  struct H {
+int a;
+int&& r;
+  };
+}
+
 // CHECK-DAG: [[A1:@.*a1.*]] = internal constant [[STRUCT_A]] { i8 3, double 2.00e+00 }, align 8
 constexpr A a1(3.1, 2.0);
 // CHECK-DAG: [[A2:@.*a2.*]] = internal constant [[STRUCT_A]] { i8 99, double 0.00e+00 }, align 8
@@ -421,3 +429,50 @@
 make2<0>();
   }
 }
+
+namespace gh61567 {
+  int foo20();
+
+  // CHECK: define {{.*}} void @{{.*foo21.*}} {
+  // CHECK-NEXT: entry
+  // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_H]], align 8
+  // CHECK-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4
+  // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0
+  // CHECK-NEXT: store i32 0, ptr [[A]], align 8
+  // CHECK-NEXT: [[R:%.*r.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 1
+  // CHECK-NEXT: store i32 1, ptr [[REF_TMP]], align 4
+  // CHECK-NEXT: store ptr [[REF_TMP]], 

[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-14 Thread Shafik Yaghmour via Phabricator via cfe-commits
shafik added inline comments.



Comment at: clang/lib/Sema/SemaInit.cpp:5332
+if (Arg)
+  IS.Diagnose(S, SubEntity, SubKind, Arg);
+else

Do we have tests that trigger this diagnostic and the one right below?



Comment at: clang/lib/Sema/SemaInit.cpp:9264
   cast(Entity.getDecl())->isBitField())
 S.CheckBitFieldInitialization(Kind.getLocation(),
   cast(Entity.getDecl()),

I don't see any tests that checks this set of diagnostics for parens init. 


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-14 Thread Shafik Yaghmour via Phabricator via cfe-commits
shafik added inline comments.



Comment at: clang/include/clang/Sema/Initialization.h:400
+  static InitializedEntity InitializeMemberFromParenAggInit(FieldDecl *Member) 
{
+return InitializedEntity(Member, nullptr, false, false, true);
+  }





Comment at: clang/include/clang/Sema/Initialization.h:509
   bool isImplicitMemberInitializer() const {
-return getKind() == EK_Member && Variable.IsImplicitFieldInit;
+return (getKind() == EK_Member || getKind() == EK_ParenAggInitMember) &&
+   Variable.IsImplicitFieldInit;

Does this really apply? It looks like this function is only used in 
`canPerformArrayCopy`



Comment at: clang/lib/Sema/SemaAccess.cpp:1657
 const FieldDecl *Field = cast(Entity.getDecl());
 PD = PDiag(diag::err_access_field_ctor);
 PD << Field->getType() << getSpecialMember(Constructor);

It looks like don't have a test that triggers this diagnostic, I was looking 
for `field of type.*has.*` 



Comment at: clang/lib/Sema/SemaInit.cpp:583
+  EK == InitializedEntity::EK_Member ||
+  EK == InitializedEntity::EK_ParenAggInitMember)
 SemaRef.Diag(Entity.getDecl()->getLocation(),

I don't see a test triggering this diagnostic for parens init.



Comment at: clang/lib/Sema/SemaInit.cpp:597
+  EK == InitializedEntity::EK_Member ||
+  EK == InitializedEntity::EK_ParenAggInitMember)
 SemaRef.Diag(Entity.getDecl()->getLocation(),

I don't see a test triggering this diagnostic for parens init.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-13 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:2130
+  "initializer|a related result|a parameter of CF audited function|a "
+  "structured binding|a member subobject}0 "
   "%diff{of type $ with an %select{rvalue|lvalue}2 of type $|"

This was missing an entry for `EK_BINDING`, so I added one (otherwise, we hit 
an assertion failure).



Comment at: clang/test/SemaCXX/paren-list-agg-init.cpp:132
   E e1(1);
-  // expected-error@-1 {{no matching constructor for initialization of 'E'}}
+  // expected-error@-1 {{no matching constructor for initialization of 'F'}}
 

This turned out to be a bug in the original implementation. Currently, 
diagnostics are only emitted for class members if we fail a parenthesized 
aggregate init. However, this used to not be the case with value initialized 
members, which emits the diagnostic for the class itself. Refactoring 
`TryOrBuildParenListInit(...)` fixes this and makes things consistent.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-13 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 513377.
ayzhao added a comment.

fix missing EOF newline


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148274/new/

https://reviews.llvm.org/D148274

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/Sema/SemaAccess.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/test/CodeGen/paren-list-agg-init.cpp
  clang/test/SemaCXX/paren-list-agg-init.cpp

Index: clang/test/SemaCXX/paren-list-agg-init.cpp
===
--- clang/test/SemaCXX/paren-list-agg-init.cpp
+++ clang/test/SemaCXX/paren-list-agg-init.cpp
@@ -9,7 +9,7 @@
 struct B {
   A a;
   int b[20];
-  int & // expected-note {{reference member declared here}}
+  int &
 };
 
 struct C { // expected-note 5{{candidate constructor}}
@@ -21,9 +21,9 @@
   int a;
 };
 
-struct E { // expected-note 3{{candidate constructor}}
-  struct F {
-F(int, int);
+struct E {
+  struct F { // expected-note 2{{candidate constructor}}
+F(int, int); // expected-note {{candidate constructor}}
   };
   int a;
   F f;
@@ -96,9 +96,8 @@
   B b1(2022, {7, 8});
   // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
   B b2(A(1), {}, 1);
-  // expected-error@-1 {{reference member 'c' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
-  // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
-  // beforecxx20-warning@-3 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
 
   C c(A(1), 1, 2, 3, 4);
   // expected-error@-1 {{array initializer must be an initializer list}}
@@ -130,7 +129,7 @@
   // expected-error@-1 {{excess elements in union initializer}}
 
   E e1(1);
-  // expected-error@-1 {{no matching constructor for initialization of 'E'}}
+  // expected-error@-1 {{no matching constructor for initialization of 'F'}}
 
   constexpr F f1(1);
   // expected-error@-1 {{constexpr variable 'f1' must be initialized by a constant expression}}
Index: clang/test/CodeGen/paren-list-agg-init.cpp
===
--- clang/test/CodeGen/paren-list-agg-init.cpp
+++ clang/test/CodeGen/paren-list-agg-init.cpp
@@ -90,6 +90,14 @@
   };
 }
 
+namespace gh61567 {
+  // CHECK-DAG: [[STRUCT_H:%.*H.*]] = type { i32, ptr }
+  struct H {
+int a;
+int&& r;
+  };
+}
+
 // CHECK-DAG: [[A1:@.*a1.*]] = internal constant [[STRUCT_A]] { i8 3, double 2.00e+00 }, align 8
 constexpr A a1(3.1, 2.0);
 // CHECK-DAG: [[A2:@.*a2.*]] = internal constant [[STRUCT_A]] { i8 99, double 0.00e+00 }, align 8
@@ -421,3 +429,50 @@
 make2<0>();
   }
 }
+
+namespace gh61567 {
+  int foo20();
+
+  // CHECK: define {{.*}} void @{{.*foo21.*}} {
+  // CHECK-NEXT: entry
+  // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_H]], align 8
+  // CHECK-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4
+  // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0
+  // CHECK-NEXT: store i32 0, ptr [[A]], align 8
+  // CHECK-NEXT: [[R:%.*r.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 1
+  // CHECK-NEXT: store i32 1, ptr [[REF_TMP]], align 4
+  // CHECK-NEXT: store ptr [[REF_TMP]], ptr [[R]], align 8
+  // CHECK-NEXT: ret void
+  void foo21() {
+H(0, 1);
+  }
+
+  // CHECK: define {{.*}} void @{{.*foo22.*}} {
+  // CHECK-NEXT: entry
+  // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_H]], align 8
+  // CHECK-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4
+  // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0
+  // CHECK-NEXT: store i32 0, ptr [[A]], align 8
+  // CHECK-NEXT: [[R:%.*r.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 1
+  // CHECK-NEXT: [[CALL:%.*call*]] = call noundef i32 @{{.*foo20.*}}
+  // CHECK-NEXT: store i32 [[CALL]], ptr [[REF_TMP]], align 4
+  // CHECK-NEXT: store ptr [[REF_TMP]], ptr [[R]], align 8
+  // CHECK-NEXT: ret void
+  void foo22() {
+H(0, foo20());
+  }
+
+  // CHECK: define {{.*}} void @{{.*foo23.*}}(i32 noundef [[I:%.*i.*]])
+  // CHECK-NEXT: entry
+  // CHECK-NEXT: [[I_ADDR:%.*i.*]] = alloca i32, align 4
+  // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_H]], align 8
+  // CHECK-NEXT: store i32 [[I]], ptr [[I_ADDR]], align 4
+  // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0
+  // CHECK-NEXT: store i32 0, ptr [[A]], align 8
+  // CHECK-NEXT: [[R:%.*r.*]] = getelementptr 

[PATCH] D148274: [clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization

2023-04-13 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao created this revision.
Herald added a project: All.
ayzhao requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Before this patch, initialized class members would have the LifetimeKind
LK_MemInitializer, which does not allow for binding a temporary to a
reference. Binding to a temporary however is allowed in parenthesized
aggregate initialization, even if it leads to a dangling reference. To
fix this, we create a new EntityKind, EK_ParenAggInitMember, which has
LifetimeKind LK_FullExpression.

This patch does *not* attempt to diagnose dangling references as a
result of using this feature.

This patch also refactors TryOrBuildParenListInitialization(...) to
accomodate creating different InitializedEntity objects.

Fixes #61567

[0]: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0960r3.html


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D148274

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/Sema/SemaAccess.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/test/CodeGen/paren-list-agg-init.cpp
  clang/test/SemaCXX/paren-list-agg-init.cpp

Index: clang/test/SemaCXX/paren-list-agg-init.cpp
===
--- clang/test/SemaCXX/paren-list-agg-init.cpp
+++ clang/test/SemaCXX/paren-list-agg-init.cpp
@@ -9,7 +9,7 @@
 struct B {
   A a;
   int b[20];
-  int & // expected-note {{reference member declared here}}
+  int &
 };
 
 struct C { // expected-note 5{{candidate constructor}}
@@ -21,9 +21,9 @@
   int a;
 };
 
-struct E { // expected-note 3{{candidate constructor}}
-  struct F {
-F(int, int);
+struct E {
+  struct F { // expected-note 2{{candidate constructor}}
+F(int, int); // expected-note {{candidate constructor}}
   };
   int a;
   F f;
@@ -96,9 +96,8 @@
   B b1(2022, {7, 8});
   // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
   B b2(A(1), {}, 1);
-  // expected-error@-1 {{reference member 'c' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
-  // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
-  // beforecxx20-warning@-3 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
+  // beforecxx20-warning@-2 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
 
   C c(A(1), 1, 2, 3, 4);
   // expected-error@-1 {{array initializer must be an initializer list}}
@@ -130,7 +129,7 @@
   // expected-error@-1 {{excess elements in union initializer}}
 
   E e1(1);
-  // expected-error@-1 {{no matching constructor for initialization of 'E'}}
+  // expected-error@-1 {{no matching constructor for initialization of 'F'}}
 
   constexpr F f1(1);
   // expected-error@-1 {{constexpr variable 'f1' must be initialized by a constant expression}}
Index: clang/test/CodeGen/paren-list-agg-init.cpp
===
--- clang/test/CodeGen/paren-list-agg-init.cpp
+++ clang/test/CodeGen/paren-list-agg-init.cpp
@@ -90,6 +90,14 @@
   };
 }
 
+namespace gh61567 {
+  // CHECK-DAG: [[STRUCT_H:%.*H.*]] = type { i32, ptr }
+  struct H {
+int a;
+int&& r;
+  };
+}
+
 // CHECK-DAG: [[A1:@.*a1.*]] = internal constant [[STRUCT_A]] { i8 3, double 2.00e+00 }, align 8
 constexpr A a1(3.1, 2.0);
 // CHECK-DAG: [[A2:@.*a2.*]] = internal constant [[STRUCT_A]] { i8 99, double 0.00e+00 }, align 8
@@ -421,3 +429,50 @@
 make2<0>();
   }
 }
+
+namespace gh61567 {
+  int foo20();
+
+  // CHECK: define {{.*}} void @{{.*foo21.*}} {
+  // CHECK-NEXT: entry
+  // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_H]], align 8
+  // CHECK-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4
+  // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0
+  // CHECK-NEXT: store i32 0, ptr [[A]], align 8
+  // CHECK-NEXT: [[R:%.*r.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 1
+  // CHECK-NEXT: store i32 1, ptr [[REF_TMP]], align 4
+  // CHECK-NEXT: store ptr [[REF_TMP]], ptr [[R]], align 8
+  // CHECK-NEXT: ret void
+  void foo21() {
+H(0, 1);
+  }
+
+  // CHECK: define {{.*}} void @{{.*foo22.*}} {
+  // CHECK-NEXT: entry
+  // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_H]], align 8
+  // CHECK-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4
+  // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0
+  // CHECK-NEXT: store i32 0, ptr [[A]], align 8
+  // CHECK-NEXT: [[R:%.*r.*]] = getelementptr inbounds [[STRUCT_H]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 1
+  // CHECK-NEXT: [[CALL:%.*call*]] = call