[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-11-07 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 473746.
ayzhao added a comment.

rebase + update commit message


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/SemaCXX/P0960R3.cpp

Index: clang/test/SemaCXX/P0960R3.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/P0960R3.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 3{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B { // expected-note 3{{candidate constructor}}
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 6{{candidate constructor}}
+  A a;
+  int b[20];
+};
+
+struct D : public C, public A { // expected-note 6{{candidate constructor}}
+  int a;
+};
+
+void foo() {
+  A a(1954, 9, 21);
+  // expected-error@-1 {{no matching constructor for initialization of 'A'}}
+  A b(2.1);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A e(-1.2, 9.8);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A s = static_cast(1.1);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A h = (A)3.1;
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A i = A(8.7);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+
+  B n(2022, {7, 8});
+  // expected-error@-1 {{no matching constructor for initialization}}
+  B z(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}}
+
+  C o(A(1), 1, 2, 3, 4);
+  // expected-error@-1 {{no matching constructor for initialization of 'C'}}
+  D R(1);
+  // expected-error@-1 {{no matching constructor for initialization}}
+  D I(C(1));
+  // expected-error@-1 {{no matching conversion for functional-style cast from 'int' to 'C'}}
+  D P(C(A(1)), 1);
+  // expected-error@-1 {{no matching constructor for initialization}}
+
+  int arr1[](0, 1, 2, A(1));
+  // expected-error@-1 {{no viable conversion from 'A' to 'int'}}
+  int arr2[2](0, 1, 2);
+  // expected-error@-1 {{excess elements in array initializer}}
+}
Index: clang/test/CodeGen/P0960R3.cpp
===
--- /dev/null
+++ clang/test/CodeGen/P0960R3.cpp
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -std=c++20 %s -emit-llvm -o - | FileCheck %s
+
+struct A {
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b;
+};
+
+struct C : public B, public A {};
+
+// CHECK-LABEL:   entry:
+// CHECK-NEXT:[[A1:%.*]] = alloca [[STRUCT_A:%.*]], align 8
+// CHECK-NEXT:[[B1:%.*]] = alloca [[STRUCT_B:%.*]], align 8
+// CHECK-NEXT:[[C1:%.*]] = alloca [[STRUCT_C:%.*]], align 8
+// CHECK-NEXT:[[REF_TMP:%.*]] = alloca [[STRUCT_B]], align 8
+// CHECK-NEXT:[[REF_TMP5:%.*]] = alloca [[STRUCT_A]], align 8
+// CHECK-NEXT:[[I:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[A1]], i32 0, i32 0
+// CHECK-NEXT:store i8 3, ptr [[I]], align 8
+// CHECK-NEXT:[[J:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[A1]], i32 0, i32 1
+// CHECK-NEXT:store double 2.00e+00, ptr [[J]], align 8
+// CHECK-NEXT:[[A:%.*]] = getelementptr inbounds [[STRUCT_B]], ptr [[B1]], i32 0, i32 0
+// CHECK-NEXT:[[I1:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[A]], i32 0, i32 0
+// CHECK-NEXT:store i8 99, ptr [[I1]], align 8
+// CHECK-NEXT:[[A2:%.*]] = getelementptr inbounds [[STRUCT_B]], ptr [[REF_TMP]], i32 0, i32 0
+// CHECK-NEXT:[[I3:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[A2]], i32 0, i32 0
+// CHECK-NEXT:store i8 1, ptr [[I3]], align 8
+// CHECK-NEXT:[[J4:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[A2]], i32 0, i32 1
+// CHECK-NEXT:store double 1.00e+00, ptr [[J4]], align 8
+// CHECK-NEXT:[[B:%.*]] = getelementptr inbounds [[STRUCT_B]], ptr [[REF_TMP]], i32 0, i32 1
+// CHECK-NEXT:store i32 1, ptr [[B]], align 8
+// CHECK-NEXT:

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-11-02 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 472702.
ayzhao marked 3 inline comments as done.
ayzhao added a comment.

addressed code review comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang-c/Index.h
  clang/include/clang/AST/ComputeDependence.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/ComputeDependence.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/paren-list-agg-init.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/PCH/cxx_paren_init.cpp
  clang/test/PCH/cxx_paren_init.h
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/test/SemaCXX/paren-list-agg-init.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1156,7 +1156,7 @@
 
   Parenthesized initialization of aggregates
   https://wg21.link/p0960r3;>P0960R3
-  No
+  Clang 16
 

 https://wg21.link/p1975r0;>P1975R0
Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,9 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  EnqueueChildren(E);
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5578,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/paren-list-agg-init.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/paren-list-agg-init.cpp
@@ -0,0 +1,172 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+// RUN: %clang_cc1 -verify=expected,beforecxx20 -Wc++20-extensions -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  A a;
+  int b[20];
+};
+
+struct D : public C, public A {
+  int a;
+};
+
+struct E { // expected-note 3{{candidate constructor}}
+  struct F {
+F(int, int);
+  };
+  int a;
+  F f;
+};
+
+int getint(); // expected-note {{declared here}}
+
+struct F {
+  int a;
+  int b = getint(); // expected-note {{non-constexpr function 'getint' 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-11-02 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin added a comment.

I think this is basically good to go, but I'll let other people give it a look 
too




Comment at: clang/lib/AST/ExprConstant.cpp:9987-9990
+} else {
+  llvm_unreachable(
+  "Expression is neither an init list nor a C++ paren list");
+}





Comment at: clang/lib/CodeGen/CGExprAgg.cpp:91
+  void EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, QualType 
ArrayQTy,
+ Expr *E, ArrayRef InitExprs);
 

Could you give `E` a better name?



Comment at: clang/lib/CodeGen/CGExprAgg.cpp:479
 void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
-   QualType ArrayQTy, InitListExpr *E) {
-  uint64_t NumInitElements = E->getNumInits();
+   QualType ArrayQTy, Expr *E,
+   ArrayRef InitExprs) {

Ditto


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

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


[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-11-01 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 472441.
ayzhao marked an inline comment as done.
ayzhao added a comment.

Merge CXXParenListInitExpr with VisitInitListExpr, also friendly ping as all 
comments are addressed


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang-c/Index.h
  clang/include/clang/AST/ComputeDependence.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/ComputeDependence.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/paren-list-agg-init.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/PCH/cxx_paren_init.cpp
  clang/test/PCH/cxx_paren_init.h
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/test/SemaCXX/paren-list-agg-init.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1156,7 +1156,7 @@
 
   Parenthesized initialization of aggregates
   https://wg21.link/p0960r3;>P0960R3
-  No
+  Clang 16
 

 https://wg21.link/p1975r0;>P1975R0
Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,9 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  EnqueueChildren(E);
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5578,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/paren-list-agg-init.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/paren-list-agg-init.cpp
@@ -0,0 +1,172 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+// RUN: %clang_cc1 -verify=expected,beforecxx20 -Wc++20-extensions -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  A a;
+  int b[20];
+};
+
+struct D : public C, public A {
+  int a;
+};
+
+struct E { // expected-note 3{{candidate constructor}}
+  struct F {
+F(int, int);
+  };
+  int a;
+  F f;
+};
+
+int getint(); // expected-note {{declared here}}
+
+struct F {
+  int a;
+ 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-11-01 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 472405.
ayzhao added a comment.

clang-format + rebase


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang-c/Index.h
  clang/include/clang/AST/ComputeDependence.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/ComputeDependence.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/paren-list-agg-init.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/PCH/cxx_paren_init.cpp
  clang/test/PCH/cxx_paren_init.h
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/test/SemaCXX/paren-list-agg-init.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1156,7 +1156,7 @@
 
   Parenthesized initialization of aggregates
   https://wg21.link/p0960r3;>P0960R3
-  No
+  Clang 16
 

 https://wg21.link/p1975r0;>P1975R0
Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,9 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  EnqueueChildren(E);
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5578,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/paren-list-agg-init.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/paren-list-agg-init.cpp
@@ -0,0 +1,172 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+// RUN: %clang_cc1 -verify=expected,beforecxx20 -Wc++20-extensions -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  A a;
+  int b[20];
+};
+
+struct D : public C, public A {
+  int a;
+};
+
+struct E { // expected-note 3{{candidate constructor}}
+  struct F {
+F(int, int);
+  };
+  int a;
+  F f;
+};
+
+int getint(); // expected-note {{declared here}}
+
+struct F {
+  int a;
+  int b = getint(); // expected-note {{non-constexpr function 'getint' cannot be used in a constant expression}}
+};
+

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-31 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added a comment.

Status update:

While investigating @cor3ntin's comment about refactoring `VisitInitListExpr` 
and `VisitCXXParenListInitExpr` as they share common code, I discovered that 
flexible array members would cause this patch to explode. Specifically, the 
following code:

  struct S {
  int b;
  int a[];
  };
  
  S s2(1, {1, 2});

was causing this assertion 

 to fail.

I took a look at GCC, and it turns out that GCC doesn't allow flexible array 
members at all in paren list initialization of aggregates, even in contexts 
where the corresponding designated initializer expression succeeds: 
https://godbolt.org/z/E73433erb

For now, I updated this implementation to follow GCC's behavior and disallow 
flexible array members, as IIRC in C++ they are a GCC extension and we should 
therefore follow GCC behavior. However, I am open to other thoughts.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

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


[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-31 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 472190.
ayzhao marked 6 inline comments as done.
ayzhao added a comment.

address some comments and implement disallowing flexible array members


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang-c/Index.h
  clang/include/clang/AST/ComputeDependence.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/ComputeDependence.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/paren-list-agg-init.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/PCH/cxx_paren_init.cpp
  clang/test/PCH/cxx_paren_init.h
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/test/SemaCXX/paren-list-agg-init.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1160,7 +1160,7 @@
 
   Parenthesized initialization of aggregates
   https://wg21.link/p0960r3;>P0960R3
-  No
+  Clang 16
 

 https://wg21.link/p1975r0;>P1975R0
Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,9 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  EnqueueChildren(E);
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5578,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/paren-list-agg-init.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/paren-list-agg-init.cpp
@@ -0,0 +1,172 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+// RUN: %clang_cc1 -verify=expected,beforecxx20 -Wc++20-extensions -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  A a;
+  int b[20];
+};
+
+struct D : public C, public A {
+  int a;
+};
+
+struct E { // expected-note 3{{candidate constructor}}
+  struct F {
+F(int, int);
+  };
+  int a;
+  F f;
+};
+
+int getint(); // expected-note {{declared here}}
+
+struct F {
+  int a;
+  int b = getint(); // 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-30 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin added a comment.

I added a few more comments, mostly nitpicks




Comment at: clang/lib/AST/ExprConstant.cpp:9952-9953
+const FieldDecl *Field;
+if (isa(E)) {
+  Field = cast(E)->getInitializedFieldInUnion();
+} else if (isa(E)) {





Comment at: clang/lib/AST/ExprConstant.cpp:9956
+  assert(InitExprs.size() == 1 &&
+ "Number of expressions in C++ paren list is not 1");
+

Maybe that message could be a bit more clear.

"Union should have exactly 1 initializer in in C++ paren list" or something 
like that.



Comment at: clang/lib/CodeGen/CGExprAgg.cpp:1595
 
+void AggExprEmitter::VisitCXXParenListInitExpr(CXXParenListInitExpr *E) {
+  ArrayRef InitExprs = E->getInitExprs();

There are some overlaps with `VisitInitListExpr`, I wonder if we should try to 
factor out some of the code, especially the base class initialization



Comment at: clang/lib/CodeGen/CGExprAgg.cpp:1600
+  if (const ArrayType *AT = dyn_cast(E->getType())) {
+for (auto Pair : llvm::enumerate(InitExprs)) {
+  // Initialization for every element of the array.

Maybe it would be cleaner to use a structured binding here.



Comment at: clang/lib/CodeGen/CGExprAgg.cpp:1616
+const CXXRecordDecl *BaseRD = Base.getType()->getAsCXXRecordDecl();
+Address V = CGF.GetAddressOfDirectBaseInCompleteClass(
+Dest.getAddress(), RD, BaseRD,

Should we assert that the base is not virtual?



Comment at: clang/lib/Sema/SemaInit.cpp:5281
+
+  // Unnamed bitfields should not be initialized at all,either with an arg
+  // or by default.





Comment at: clang/lib/Sema/TreeTransform.h:13930
+ InitExprs.size(), true, TransformedInits,
+ ))
+return ExprError();

`ArgumentChanged` is not used, and is defaulted by the function, so you should 
be able to remove it


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

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


[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-28 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added a comment.

Friendly ping for reviewers as all comments should be addressed by now.

In D129531#3873775 , @cor3ntin wrote:

> It starting to look great.
> Should we add an extension warning? Note that I'm not suggesting to support 
> that in earlier modes, just an off-by-default warning that says "this is a 
> c++20 feature". but we are a bit inconsistent with those.

Done

> can you rename `test/SemaCXX/P0960R3.cpp` to something like 
> `test/SemaCXX/cxx20-paren-list-init.cpp` (and same for other tests?) it's 
> more consistent with other existing tests.

Done




Comment at: clang/lib/Sema/SemaInit.cpp:5263
 
+static void TryOrBuildParenListInitialization(
+Sema , const InitializedEntity , const InitializationKind ,

shafik wrote:
> I feel like this function could use a lot of comments, I found it hard to 
> follow the flow of logic and I think I get it mostly now but comments would 
> have helped a lot.
I added some comments, did a little refactoring, and renamed some variables. 
PTAL and LMKWYT.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

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


[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-28 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 471694.
ayzhao marked 2 inline comments as done.
ayzhao added a comment.

add C++20 extension diagnostics and some other code review feedback


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang-c/Index.h
  clang/include/clang/AST/ComputeDependence.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/ComputeDependence.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/paren-list-agg-init.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/PCH/cxx_paren_init.cpp
  clang/test/PCH/cxx_paren_init.h
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/test/SemaCXX/paren-list-agg-init.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1160,7 +1160,7 @@
 
   Parenthesized initialization of aggregates
   https://wg21.link/p0960r3;>P0960R3
-  No
+  Clang 16
 

 https://wg21.link/p1975r0;>P1975R0
Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,9 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  EnqueueChildren(E);
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5578,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/paren-list-agg-init.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/paren-list-agg-init.cpp
@@ -0,0 +1,152 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+// RUN: %clang_cc1 -verify=expected,beforecxx20 -Wc++20-extensions -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  A a;
+  int b[20];
+};
+
+struct D : public C, public A {
+  int a;
+};
+
+struct E { // expected-note 3{{candidate constructor}}
+  struct F {
+F(int, int);
+  };
+  int a;
+  F f;
+};
+
+int getint(); // expected-note {{declared here}}
+
+struct F {
+  int a;
+  int b = getint(); // 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-27 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 471338.
ayzhao added a comment.

we don't need CHECK-DAG here


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang-c/Index.h
  clang/include/clang/AST/ComputeDependence.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/ComputeDependence.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/CodeGen/P1975R0.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/PCH/cxx_paren_init.cpp
  clang/test/PCH/cxx_paren_init.h
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1160,7 +1160,7 @@
 
   Parenthesized initialization of aggregates
   https://wg21.link/p0960r3;>P0960R3
-  No
+  Clang 16
 

 https://wg21.link/p1975r0;>P1975R0
Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,9 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  EnqueueChildren(E);
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5578,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-27 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added a comment.

In D129531#3880875 , @ayzhao wrote:

> In D129531#3873872 , @royjacobson 
> wrote:
>
>> Thanks for working on it! It looks really good. Please remember to update 
>> the feature test macro (__cpp_aggregate_paren_init).
>
> Done
>
>> Also, I think there's no test coverage for the ASTReader/Writer changes? I 
>> would like to see some as well.
>
> I added a precompiled header test. Currently, the ASTReader/Writer change is 
> broken with the following error:
>
> ...
>
> I'm currently looking into this - I suspect it has to do with 
> `CXXParenListInitExpr` storing all it's subexpressions in an 
> `llvm::TrailingObjects` base class, but I have yet to confirm one way or 
> another.

The PCH test is fixed now, so we now have coverage for the ASTReader/Writer 
changes.




Comment at: clang/lib/AST/Expr.cpp:3699
+// FIXME: unimplemented
+llvm_unreachable("unimplemented");
   }

shafik wrote:
> cor3ntin wrote:
> > You can probably just fall through, a list of expression only has side 
> > effects if the individual expressions do, which the code just below is 
> > doing.
> On Discourse, the suggestion was made to have use `InitListExpr` as a base 
> class and in that case I believe we should do the same that that we do for 
> `InitListExpr`.
See the response from @ilya-biryukov for why I decided against inheriting from 
`InitListExpr`.



Comment at: clang/lib/AST/ExprClassification.cpp:446
+
+  case Expr::CXXParenListInitExprClass:
+// FIXME: unimplemented

shafik wrote:
> This looks like we should handle this similar to `InitListExpr` but I am not 
> sure if single element if it is bound to a reference can be an lvalue holds 
> as well here as well CC @erichkeane 
IMO; no. 

I believe the comment for `InitListExpr` refers to statements like:

```
int a;
int {a};
```

This doesn't apply to `CXXParenListInitExprClass` because the corresponding 
statement with parentheses wouldn't be parsed as a `CXXParenListInitExpr` in 
the first place.



Comment at: clang/lib/AST/StmtPrinter.cpp:2459
+void StmtPrinter::VisitCXXParenListInitExpr(CXXParenListInitExpr *Node) {
+  // FIXME: unimplemented
+  llvm_unreachable("unimplemented");

shafik wrote:
> Assuming we go w/ `InitListExpr` as a base class then you should do something 
> similar to ` StmtPrinter::VisitInitListExpr(...)`  except with parens.
See the response from @ilya-biryukov for why I decided against inheriting from 
`InitListExpr`.



Comment at: clang/lib/Sema/TreeTransform.h:13922
 
+template 
+ExprResult

This is an extra change, but `clang-format` would always make it.



Comment at: clang/lib/Serialization/ASTReaderStmt.cpp:2179
+  for (unsigned I = 0; I < E->NumExprs; I++)
+E->getTrailingObjects()[I] = Record.readSubExpr();
+}

ilya-biryukov wrote:
> ayzhao wrote:
> > ilya-biryukov wrote:
> > > FYI: I think this is where the crash comes from.
> > > We should allocate the trailing objects first.
> > > E.g. see how `PragmaCommentDecl::CreateDeserialized` does this.
> > This sounds like it could be the solution - thanks for looking at it!
> > 
> > Currently, I'm working on the refactor that shafik@ suggested, which was to 
> > inherit from `InitListExpr`. Hopefully, that refactor will fix this issue 
> > as `InitListExpr` stores it's subexpressions in a class member instead of 
> > using `llvm::TrailingObjects`.
> Are we trying to share code between two implementations? If so, I suggest to 
> consider alternatives, e.g. creating a new base class and inheriting both 
> `InitListExpr` and `CXXParentInitListExpr` to share the common code.
> 
> Inheriting `CXXParentInitListExpr` from `InitListExpr` breaks [Liskov 
> substitution 
> principle](https://en.wikipedia.org/wiki/Liskov_substitution_principle) and 
> will likely to lead to bugs that are hard to chase.  `InitListExpr` is widely 
> used and means`{}`. `CXXParenInitListExpr` is not `{}` and we do not know in 
> advance which code is going to work for both and which code is only valid for 
> `{}`. Reviewing all callsites that use `InitListExpr` does not seem 
> plausible. Note that in addition to Clang, there are also uses in 
> ast-matchers and in clang-tidy checks (quite a few of those are downstream).
So I figured out why this was failing. When I created the 
`CXXParenListInitExpr` object on the heap in 
`ASTReader::ReadStmtFromStream(...)` below, I just called `new` without 
allocating any space for the `TrailingObjects`. This is fixed now, and the PCH 
test passes.

> Inheriting CXXParentInitListExpr from InitListExpr breaks Liskov substitution 
> principle and will likely to lead to bugs that are hard to chase. 
> InitListExpr is widely used and means`{}. CXXParenInitListExpr` is not {} and 
> we do not know in advance 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-27 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 471329.
ayzhao marked 11 inline comments as done.
ayzhao added a comment.

Fix PCH test and address some code review comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang-c/Index.h
  clang/include/clang/AST/ComputeDependence.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/ComputeDependence.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/CodeGen/P1975R0.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/PCH/cxx_paren_init.cpp
  clang/test/PCH/cxx_paren_init.h
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1160,7 +1160,7 @@
 
   Parenthesized initialization of aggregates
   https://wg21.link/p0960r3;>P0960R3
-  No
+  Clang 16
 

 https://wg21.link/p1975r0;>P1975R0
Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,9 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  EnqueueChildren(E);
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5578,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-26 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov added inline comments.



Comment at: clang/lib/Serialization/ASTReaderStmt.cpp:2179
+  for (unsigned I = 0; I < E->NumExprs; I++)
+E->getTrailingObjects()[I] = Record.readSubExpr();
+}

ayzhao wrote:
> ilya-biryukov wrote:
> > FYI: I think this is where the crash comes from.
> > We should allocate the trailing objects first.
> > E.g. see how `PragmaCommentDecl::CreateDeserialized` does this.
> This sounds like it could be the solution - thanks for looking at it!
> 
> Currently, I'm working on the refactor that shafik@ suggested, which was to 
> inherit from `InitListExpr`. Hopefully, that refactor will fix this issue as 
> `InitListExpr` stores it's subexpressions in a class member instead of using 
> `llvm::TrailingObjects`.
Are we trying to share code between two implementations? If so, I suggest to 
consider alternatives, e.g. creating a new base class and inheriting both 
`InitListExpr` and `CXXParentInitListExpr` to share the common code.

Inheriting `CXXParentInitListExpr` from `InitListExpr` breaks [Liskov 
substitution 
principle](https://en.wikipedia.org/wiki/Liskov_substitution_principle) and 
will likely to lead to bugs that are hard to chase.  `InitListExpr` is widely 
used and means`{}`. `CXXParenInitListExpr` is not `{}` and we do not know in 
advance which code is going to work for both and which code is only valid for 
`{}`. Reviewing all callsites that use `InitListExpr` does not seem plausible. 
Note that in addition to Clang, there are also uses in ast-matchers and in 
clang-tidy checks (quite a few of those are downstream).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

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


[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-25 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added inline comments.



Comment at: clang/lib/Serialization/ASTReaderStmt.cpp:2179
+  for (unsigned I = 0; I < E->NumExprs; I++)
+E->getTrailingObjects()[I] = Record.readSubExpr();
+}

ilya-biryukov wrote:
> FYI: I think this is where the crash comes from.
> We should allocate the trailing objects first.
> E.g. see how `PragmaCommentDecl::CreateDeserialized` does this.
This sounds like it could be the solution - thanks for looking at it!

Currently, I'm working on the refactor that shafik@ suggested, which was to 
inherit from `InitListExpr`. Hopefully, that refactor will fix this issue as 
`InitListExpr` stores it's subexpressions in a class member instead of using 
`llvm::TrailingObjects`.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

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


[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-25 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov added inline comments.



Comment at: clang/lib/Serialization/ASTReaderStmt.cpp:2179
+  for (unsigned I = 0; I < E->NumExprs; I++)
+E->getTrailingObjects()[I] = Record.readSubExpr();
+}

FYI: I think this is where the crash comes from.
We should allocate the trailing objects first.
E.g. see how `PragmaCommentDecl::CreateDeserialized` does this.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

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


[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-24 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 470314.
ayzhao added a comment.

remove whitespace change and disable test


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang-c/Index.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/CodeGen/P1975R0.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/PCH/cxx_paren_init.cpp
  clang/test/PCH/cxx_paren_init.h
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1160,7 +1160,7 @@
 
   Parenthesized initialization of aggregates
   https://wg21.link/p0960r3;>P0960R3
-  No
+  Clang 16
 

 https://wg21.link/p1975r0;>P1975R0
Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,9 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  EnqueueChildren(E);
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5578,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-24 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 470311.
ayzhao added a comment.

some comment fixes, add a test for serialization which doesn't work yet


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang-c/Index.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/CodeGen/P1975R0.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/PCH/cxx_paren_init.cpp
  clang/test/PCH/cxx_paren_init.h
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1160,7 +1160,7 @@
 
   Parenthesized initialization of aggregates
   https://wg21.link/p0960r3;>P0960R3
-  No
+  Clang 16
 

 https://wg21.link/p1975r0;>P1975R0
Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,9 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  EnqueueChildren(E);
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5578,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-24 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao marked 11 inline comments as done.
ayzhao added a comment.

In D129531#3873872 , @royjacobson 
wrote:

> Thanks for working on it! It looks really good. Please remember to update the 
> feature test macro (__cpp_aggregate_paren_init).

Done

> Also, I think there's no test coverage for the ASTReader/Writer changes? I 
> would like to see some as well.

I added a precompiled header test. Currently, the ASTReader/Writer change is 
broken with the following error:


   "hunter-bidens-laptop." 15:58 
24-Oct-22
  $ bin/llvm-lit -vv --debug ../clang/test/PCH/cxx_paren_init.cpp
  [553/553] Creating executable symlink bin/clang
  llvm-lit: /llvm-project/llvm/utils/lit/lit/discovery.py:62: note: loading 
suite config '/llvm-project/build/tools/clang/test/lit.site.cfg.py'
  llvm-lit: /llvm-project/llvm/utils/lit/lit/LitConfig.py:116: note: 
load_config from '/llvm-project/clang/test/lit.cfg.py'
  llvm-lit: /llvm-project/llvm/utils/lit/lit/llvm/config.py:456: note: using 
clang: /llvm-project/build/bin/clang
  llvm-lit: /llvm-project/llvm/utils/lit/lit/TestingConfig.py:129: note: ... 
loaded config '/llvm-project/clang/test/lit.cfg.py'
  llvm-lit: /llvm-project/llvm/utils/lit/lit/TestingConfig.py:129: note: ... 
loaded config '/llvm-project/build/tools/clang/test/lit.site.cfg.py'
  llvm-lit: /llvm-project/llvm/utils/lit/lit/discovery.py:136: note: resolved 
input '../clang/test/PCH/cxx_paren_init.cpp' to 'Clang'::('PCH', 
'cxx_paren_init.cpp')
  -- Testing: 1 tests, 1 workers --
  FAIL: Clang :: PCH/cxx_paren_init.cpp (1 of 1)
   TEST 'Clang :: PCH/cxx_paren_init.cpp' FAILED 

  Script:
  --
  : 'RUN: at line 1';   /llvm-project/build/bin/clang -cc1 -internal-isystem 
/llvm-project/build/lib/clang/16.0.0/include -nostdsysteminc -x c++ -std=c++20 
-emit-pc
  h -o /llvm-project/build/tools/clang/test/PCH/Output/cxx_paren_init.cpp.tmp 
/llvm-project/clang/test/PCH/cxx_paren_init.h
  : 'RUN: at line 2';   /llvm-project/build/bin/clang -cc1 -internal-isystem 
/llvm-project/build/lib/clang/16.0.0/include -nostdsysteminc -x c++ -std=c++20 
-include
  -pch /llvm-project/build/tools/clang/test/PCH/Output/cxx_paren_init.cpp.tmp 
-fsyntax-only -S -o -
  --
  Exit Code: 139
  
  Command Output (stderr):
  --
  + : 'RUN: at line 1'
  + /llvm-project/build/bin/clang -cc1 -internal-isystem 
/llvm-project/build/lib/clang/16.0.0/include -nostdsysteminc -x c++ -std=c++20 
-emit-pch -o /dev/shm/ayzhao
  _llvm/llvm-project/build/tools/clang/test/PCH/Output/cxx_paren_init.cpp.tmp 
/llvm-project/clang/test/PCH/cxx_paren_init.h
  + : 'RUN: at line 2'
  + /llvm-project/build/bin/clang -cc1 -internal-isystem 
/llvm-project/build/lib/clang/16.0.0/include -nostdsysteminc -x c++ -std=c++20 
-include-pch /dev/shm/ayzhao
  _llvm/llvm-project/build/tools/clang/test/PCH/Output/cxx_paren_init.cpp.tmp 
-fsyntax-only -S -o -
  PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ 
and include the crash backtrace, preprocessed source, and associated run script.
  Stack dump:
  0.  Program arguments: /llvm-project/build/bin/clang -cc1 
-internal-isystem /llvm-project/build/lib/clang/16.0.0/include -nostdsysteminc 
-x c++ -std=c++20 -in
  clude-pch 
/llvm-project/build/tools/clang/test/PCH/Output/cxx_paren_init.cpp.tmp 
-fsyntax-only -S -o -
  1.   parser at end of file
  2.  /llvm-project/clang/test/PCH/cxx_paren_init.h:4:3: LLVM IR generation 
of declaration 'foo'
  3.  /llvm-project/clang/test/PCH/cxx_paren_init.h:4:3: Generating code 
for declaration 'foo'
   #0 0x55ac3d88eeea llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) 
/src/llvm_tmpfs/llvm-project/llvm/lib/Support/Unix/Signals.inc:569:11
   #1 0x55ac3d88f09b PrintStackTraceSignalHandler(void*) 
/src/llvm_tmpfs/llvm-project/llvm/lib/Support/Unix/Signals.inc:636:1
   #2 0x55ac3d88d6e6 llvm::sys::RunSignalHandlers() 
/src/llvm_tmpfs/llvm-project/llvm/lib/Support/Signals.cpp:104:5
   #3 0x55ac3d88f7c5 SignalHandler(int) 
/src/llvm_tmpfs/llvm-project/llvm/lib/Support/Unix/Signals.inc:407:1
   #4 0x7fbe3c83daf0 (/lib/x86_64-linux-gnu/libc.so.6+0x3daf0)
   #5 0x55ac3dd9e32c clang::Stmt::getStmtClass() const 
/src/llvm_tmpfs/llvm-project/clang/include/clang/AST/Stmt.h:1166:44
   #6 0x55ac3e40c735 clang::ImplicitValueInitExpr::classof(clang::Stmt 
const*) /src/llvm_tmpfs/llvm-project/clang/include/clang/AST/Expr.h:5527:30
   #7 0x55ac3e40c715 llvm::isa_impl::doit(clang::Expr const&) 
/src/llvm_tmpfs/llvm-project/llvm/include/llvm/Support/Casting.h:64:46
   #8 0x55ac3e40c6f3 llvm::isa_impl_cl::doit(clang::Expr const*) 
/src/llvm_tmpfs/llvm-project/llvm/include/llvm/Support/Casting.h:110:5
   #9 0x55ac3e40c678 llvm::isa_impl_wrap::doit(clang::Expr const* const&) 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-24 Thread Shafik Yaghmour via Phabricator via cfe-commits
shafik added a comment.

I am going to do another pass but this is my initial set of comments.




Comment at: clang/include/clang-c/Index.h:1537
+   * initializer.
+   *
+   */

nit: extra line



Comment at: clang/include/clang/AST/ExprCXX.h:4728-4729
+/// void foo() {
+///   A a1(0);// legal in C++20
+///   A a2(1.5, 1.0); // legal in C++20
+/// }





Comment at: clang/include/clang/AST/ExprCXX.h:4741-4742
+/// void foo() {
+///   A a(1.5); // legal in C++20
+///   A b{1.5}; // illegal !
+/// }





Comment at: clang/include/clang/AST/ExprCXX.h:4779
+  const ArrayRef getInitExprs() const {
+return {getTrailingObjects(), NumExprs};
+  }

Should we prefer `makeArrayRef`?



Comment at: clang/lib/AST/Expr.cpp:3699
+// FIXME: unimplemented
+llvm_unreachable("unimplemented");
   }

cor3ntin wrote:
> You can probably just fall through, a list of expression only has side 
> effects if the individual expressions do, which the code just below is doing.
On Discourse, the suggestion was made to have use `InitListExpr` as a base 
class and in that case I believe we should do the same that that we do for 
`InitListExpr`.



Comment at: clang/lib/AST/ExprClassification.cpp:446
+
+  case Expr::CXXParenListInitExprClass:
+// FIXME: unimplemented

This looks like we should handle this similar to `InitListExpr` but I am not 
sure if single element if it is bound to a reference can be an lvalue holds as 
well here as well CC @erichkeane 



Comment at: clang/lib/AST/StmtPrinter.cpp:2459
+void StmtPrinter::VisitCXXParenListInitExpr(CXXParenListInitExpr *Node) {
+  // FIXME: unimplemented
+  llvm_unreachable("unimplemented");

Assuming we go w/ `InitListExpr` as a base class then you should do something 
similar to ` StmtPrinter::VisitInitListExpr(...)`  except with parens.



Comment at: clang/lib/CodeGen/CGExprAgg.cpp:1618
+Dest.getAddress(), RD, BaseRD,
+/*isBaseVirtual*/ false);
+AggValueSlot AggSlot = AggValueSlot::forAddr(





Comment at: clang/lib/Sema/SemaInit.cpp:5263
 
+static void TryOrBuildParenListInitialization(
+Sema , const InitializedEntity , const InitializationKind ,

I feel like this function could use a lot of comments, I found it hard to 
follow the flow of logic and I think I get it mostly now but comments would 
have helped a lot.



Comment at: clang/lib/Sema/SemaInit.cpp:5273
+for (InitializedEntity SubEntity : Range) {
+  if (Index == 1 && Entity.getType()->isUnionType())
+// Unions should only have one initializer expression.

Or some other clarifying comment.



Comment at: clang/lib/Sema/SemaInit.cpp:5310
+  InitializationKind SubKind = InitializationKind::CreateForInit(
+  E->getExprLoc(), /*isDirectInit*/ false, E);
+  InitializationSequence Seq(S, SubEntity, SubKind, E);




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

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


[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-21 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added inline comments.



Comment at: clang/test/SemaCXX/P0960R3.cpp:54
+}
+
+void foo() {

Could you add test that this works with variadic templates? Something like

```
template
T construct(Args... args) {
  return T(args...);
}
```

Similar to the intended use case of make_unique/emplace_back etc.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

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


[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-21 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

Thanks for working on it! It looks really good. Please remember to update the 
feature test macro (__cpp_aggregate_paren_init).

Also, I think there's no test coverage for the ASTReader/Writer changes? I 
would like to see some as well.




Comment at: clang/docs/ReleaseNotes.rst:546
   ([temp.func.order]p6.2.1 is not implemented, matching GCC).
+- Implemented `P0634R3: 
`_
+  and `P1975R0: 
`_,




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

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


[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-21 Thread Sheng via Phabricator via cfe-commits
0x59616e added inline comments.



Comment at: clang/lib/Sema/SemaInit.cpp:6114-6116
+// const ValueDecl *VD = Entity.getDecl();
+// if (const VarDecl *VarD = dyn_cast_or_null(VD);
+// VarD && VarD->hasInit() && !VarD->getInit()->containsErrors())

cor3ntin wrote:
> Is that code meant to be commented?
This is a legacy from me. I guess it is for debugging purpose IIRC (sorry, it 
is too long ago to remember clearly). If so, t should be deleted.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

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


[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-21 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin added a comment.

It starting to look great.
Should we add an extension warning? Note that I'm not suggesting to support 
that in earlier modes, just an off-by-default warning that says "this is a 
c++20 feature". but we are a bit inconsistent with those.

can you rename `test/SemaCXX/P0960R3.cpp` to something like 
`test/SemaCXX/cxx20-paren-list-init.cpp` (and same for other tests?) it's more 
consistent with other existing tests.




Comment at: clang/include/clang/Sema/Sema.h:6200
 
-
   /// Instantiate or parse a C++ default argument expression as necessary.

Whitespace change



Comment at: clang/lib/Sema/SemaInit.cpp:3528
 delete ICS;
+break;
   }

It seems unrelated. but reasonable.



Comment at: clang/lib/Sema/SemaInit.cpp:5379-5380
+} else {
+  Sequence.SetFailed(
+  InitializationSequence::FK_ParenthesizedListInitFailed);
+}

Shouldn't we do that unconditionally?



Comment at: clang/lib/Sema/SemaInit.cpp:6106
+
+  // We fall back to the "no matching constructor "path iff the
+  // failed candidate set has function other than the three default





Comment at: clang/lib/Sema/SemaInit.cpp:6107
+  // We fall back to the "no matching constructor "path iff the
+  // failed candidate set has function other than the three default
+  // constructors. For example, conversion function.





Comment at: clang/lib/Sema/SemaInit.cpp:6114-6116
+// const ValueDecl *VD = Entity.getDecl();
+// if (const VarDecl *VarD = dyn_cast_or_null(VD);
+// VarD && VarD->hasInit() && !VarD->getInit()->containsErrors())

Is that code meant to be commented?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

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


[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-20 Thread Sheng via Phabricator via cfe-commits
0x59616e added a comment.

I can only nitpick some of the peripheral issues since I have no knowledge in 
most of the part of clang. Perhaps implementing the new standard feature is too 
arduous for a tyro like me. It's great to see the real expert to complete this.




Comment at: clang/lib/AST/ExprConstant.cpp:9959-9962
+if (!FD->isUnnamedBitfield()) {
+  Field = FD;
+  break;
+}

nit: Maybe use early exit to reduce indentation for better readability ?



Comment at: clang/lib/AST/StmtPrinter.cpp:2465-2471
+  unsigned i = 0;
+  for (Expr *E : Node->getInitExprs()) {
+if (i)
+  OS << ", ";
+PrintExpr(E);
+i++;
+  }

nit: Is it possible to use `llvm::interleaveComma` [0] here without any bad 
effect (e.g. increase in compiling time, since STLExtras.h is not a trivial 
header) ?

[0] 
https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/ADT/STLExtras.h#L1902


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

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


[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-20 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added a comment.

Friendly ping for reviewers since (I think) this is more or less complete.

Additionally, I found out that the GCC implementation [0] allows references to 
aggregates to be paren-initialized - i.e. it accepts the following:

  struct A {
int a;
int b;
  };
  const A& r(1, 2);
  int (&)[](1, 2, 3);

however; I don't see anything in the standard that supports these kinds of 
expressions. Moreover, MSVC also doesn't support paren-initialized aggregate 
references [1].

Could someone familiar with the standard comment on this?

[0]: 
https://github.com/gcc-mirror/gcc/commit/43aae289866f5ea55d187444520412554aa2e171
[1]: https://godbolt.org/z/87cdn6c19


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

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


[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-20 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 469411.
ayzhao added a comment.

Update ReleaseNotes.rst and cxx_status.html


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang-c/Index.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/CodeGen/P1975R0.cpp
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1160,7 +1160,7 @@
 
   Parenthesized initialization of aggregates
   https://wg21.link/p0960r3;>P0960R3
-  No
+  Clang 16
 

 https://wg21.link/p1975r0;>P1975R0
Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,9 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  EnqueueChildren(E);
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5578,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct initializer}}
+// expected-note@-3 {{in instantiation of template class}}
 
 template
 struct B {
Index: 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-20 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added inline comments.



Comment at: clang/lib/Sema/SemaInit.cpp:6052
+} else if (S.getLangOpts().CPlusPlus20 && !TopLevelOfInitList)
+  TryOrBuildParenListInitialization(S, Entity, Kind, Args, *this,
+/*VerifyOnly=*/true);

ayzhao wrote:
> ayzhao wrote:
> > Status update:
> > 
> > Right now this is causing the following 2 bugs:
> > 
> > 1. Currently, the below incorrect line of code:
> > 
> > ```
> > int arr[2] = 1;
> > ```
> > 
> > is being incorrectly treated the same as
> > 
> > ```
> > int arr[2](1);
> > ```
> > 
> > 2. The following below correct line of code:
> > ```
> > int arr[2] = static_cast(1);
> > ```
> > 
> > fails with the error:
> > 
> > ```
> > test-static-cast.cc:1:12: error: static_cast from 'int' to 'int[2]' is not 
> > allowed
> > int a[2] = static_cast(1);
> >^~
> > 1 error generated.
> > ```
> small fix: the incorrect error message for the 2nd bug is:
> 
> ```
> test-static-cast.cc:1:12: error: cannot initialize an array element of type 
> 'int' with an rvalue of type 'int[2]'
> int a[2] = static_cast(1);
>^~
> 1 error generated.
> ```
So I fixed `int arr[2] = 1;` incorrectly being recognized as correct by 
allowing only `IK_DIRECT`.

I also noticed that my second example is incorrect since the `static_assert` 
expression is an rvalue, so it can't be assigned to an l-value array with an 
explicit type declaration. The correct test therefore should be

```
int (&)[2] = static_cast(1);
```

which I've added to the test cases and does indeed pass.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

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


[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-20 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 469406.
ayzhao added a comment.

add test for p1975r0 static_cast


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/include/clang-c/Index.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/CodeGen/P1975R0.cpp
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp

Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,9 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  EnqueueChildren(E);
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5578,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct initializer}}
+// expected-note@-3 {{in instantiation of template class}}
 
 template
 struct B {
Index: clang/test/SemaCXX/P0960R3.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/P0960R3.cpp
@@ -0,0 +1,108 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-20 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 469393.
ayzhao added a comment.

Add test for p1975r0 and add fix (hack?) for IK_COPY


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/include/clang-c/Index.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/CodeGen/P1975R0.cpp
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp

Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,9 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  EnqueueChildren(E);
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5578,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct initializer}}
+// expected-note@-3 {{in instantiation of template class}}
 
 template
 struct B {
Index: clang/test/SemaCXX/P0960R3.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/P0960R3.cpp
@@ -0,0 +1,108 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-20 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added inline comments.



Comment at: clang/lib/Sema/SemaInit.cpp:6052
+} else if (S.getLangOpts().CPlusPlus20 && !TopLevelOfInitList)
+  TryOrBuildParenListInitialization(S, Entity, Kind, Args, *this,
+/*VerifyOnly=*/true);

ayzhao wrote:
> Status update:
> 
> Right now this is causing the following 2 bugs:
> 
> 1. Currently, the below incorrect line of code:
> 
> ```
> int arr[2] = 1;
> ```
> 
> is being incorrectly treated the same as
> 
> ```
> int arr[2](1);
> ```
> 
> 2. The following below correct line of code:
> ```
> int arr[2] = static_cast(1);
> ```
> 
> fails with the error:
> 
> ```
> test-static-cast.cc:1:12: error: static_cast from 'int' to 'int[2]' is not 
> allowed
> int a[2] = static_cast(1);
>^~
> 1 error generated.
> ```
small fix: the incorrect error message for the 2nd bug is:

```
test-static-cast.cc:1:12: error: cannot initialize an array element of type 
'int' with an rvalue of type 'int[2]'
int a[2] = static_cast(1);
   ^~
1 error generated.
```


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

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


[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-20 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added inline comments.



Comment at: clang/lib/Sema/SemaInit.cpp:6052
+} else if (S.getLangOpts().CPlusPlus20 && !TopLevelOfInitList)
+  TryOrBuildParenListInitialization(S, Entity, Kind, Args, *this,
+/*VerifyOnly=*/true);

Status update:

Right now this is causing the following 2 bugs:

1. Currently, the below incorrect line of code:

```
int arr[2] = 1;
```

is being incorrectly treated the same as

```
int arr[2](1);
```

2. The following below correct line of code:
```
int arr[2] = static_cast(1);
```

fails with the error:

```
test-static-cast.cc:1:12: error: static_cast from 'int' to 'int[2]' is not 
allowed
int a[2] = static_cast(1);
   ^~
1 error generated.
```


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

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


[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-19 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 469073.
ayzhao added a comment.

implement TreeTransform + add a test


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/include/clang-c/Index.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp

Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,9 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  EnqueueChildren(E);
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5578,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct initializer}}
+// expected-note@-3 {{in instantiation of template class}}
 
 template
 struct B {
Index: clang/test/SemaCXX/P0960R3.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/P0960R3.cpp
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-17 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 468366.
ayzhao added a comment.

accidentally removed an extra curly brace


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/include/clang-c/Index.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp

Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,9 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  EnqueueChildren(E);
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5578,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct initializer}}
+// expected-note@-3 {{in instantiation of template class}}
 
 template
 struct B {
Index: clang/test/SemaCXX/P0960R3.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/P0960R3.cpp
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  A a;
+  int b[20];
+};
+

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-17 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 468347.
ayzhao added a comment.

Fill out ItaniumMangle.cpp


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/include/clang-c/Index.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp

Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,9 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  EnqueueChildren(E);
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5578,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct initializer}}
+// expected-note@-3 {{in instantiation of template class}}
 
 template
 struct B {
Index: clang/test/SemaCXX/P0960R3.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/P0960R3.cpp
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  A a;
+  int b[20];
+};
+
+struct D : public 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-17 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 468333.
ayzhao added a comment.

implement CIndex.cpp


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/include/clang-c/Index.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp

Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,9 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  EnqueueChildren(E);
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5578,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct initializer}}
+// expected-note@-3 {{in instantiation of template class}}
 
 template
 struct B {
Index: clang/test/SemaCXX/P0960R3.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/P0960R3.cpp
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  A a;
+  int b[20];
+};
+
+struct D : public C, 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-14 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 467940.
ayzhao added a comment.

implement StmtProfiler and Sema::canThrow


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/include/clang-c/Index.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp

Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,10 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  // FIXME: implement
+  llvm_unreachable("unimplemented");
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5579,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct initializer}}
+// expected-note@-3 {{in instantiation of template class}}
 
 template
 struct B {
Index: clang/test/SemaCXX/P0960R3.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/P0960R3.cpp
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-14 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 467932.
ayzhao added a comment.

implement serialization stuff


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/include/clang-c/Index.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp

Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,10 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  // FIXME: implement
+  llvm_unreachable("unimplemented");
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5579,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct initializer}}
+// expected-note@-3 {{in instantiation of template class}}
 
 template
 struct B {
Index: clang/test/SemaCXX/P0960R3.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/P0960R3.cpp
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  A 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-14 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 467900.
ayzhao added a comment.

run clang-format again


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/include/clang-c/Index.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp

Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,10 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  // FIXME: implement
+  llvm_unreachable("unimplemented");
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5579,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct initializer}}
+// expected-note@-3 {{in instantiation of template class}}
 
 template
 struct B {
Index: clang/test/SemaCXX/P0960R3.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/P0960R3.cpp
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  A a;
+  int b[20];
+};
+
+struct D : public C, public A {
+  int a;
+};
+
+struct E { // 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-13 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 467674.
ayzhao added a comment.

add test for constexpr array and a whitespace fix


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/include/clang-c/Index.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp

Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,10 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  // FIXME: implement
+  llvm_unreachable("unimplemented");
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5579,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct initializer}}
+// expected-note@-3 {{in instantiation of template class}}
 
 template
 struct B {
Index: clang/test/SemaCXX/P0960R3.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/P0960R3.cpp
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  A a;
+  int b[20];
+};
+
+struct D : public C, public A {
+  int a;
+};
+

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-13 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 467661.
ayzhao added a comment.

run clang-format


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/include/clang-c/Index.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp

Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,10 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  // FIXME: implement
+  llvm_unreachable("unimplemented");
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5579,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct initializer}}
+// expected-note@-3 {{in instantiation of template class}}
 
 template
 struct B {
Index: clang/test/SemaCXX/P0960R3.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/P0960R3.cpp
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  A a;
+  int b[20];
+};
+
+struct D : public C, public A {
+  int a;
+};
+
+struct E { // expected-note 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-13 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 467647.
ayzhao added a comment.

Fix object lifetime issue


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/include/clang-c/Index.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp

Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,10 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  // FIXME: implement
+  llvm_unreachable("unimplemented");
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5579,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct initializer}}
+// expected-note@-3 {{in instantiation of template class}}
 
 template
 struct B {
Index: clang/test/SemaCXX/P0960R3.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/P0960R3.cpp
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  A a;
+  int b[20];
+};
+
+struct D : public C, public A {
+  int a;
+};
+
+struct E { // 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-13 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 467626.
ayzhao added a comment.

Restrict CodeGen test to Linux only since Windows semantics for bitfields are 
weird


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/include/clang-c/Index.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp

Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,10 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  // FIXME: implement
+  llvm_unreachable("unimplemented");
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5579,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct initializer}}
+// expected-note@-3 {{in instantiation of template class}}
 
 template
 struct B {
Index: clang/test/SemaCXX/P0960R3.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/P0960R3.cpp
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  A a;
+  int b[20];
+};
+
+struct D : 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-13 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added inline comments.



Comment at: clang/lib/AST/ExprConstant.cpp:15717
+// FIXME: unimplemented
+llvm_unreachable("unimplemented");
   }

0x59616e wrote:
> cor3ntin wrote:
> > This is fairly important, ie you should make sure the feature works in 
> > constexpr contextes
> I just let it fall through to the 'NotICE' path.
FYI `constexpr` is now implemented and tested.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

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


[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-13 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 467622.
ayzhao added a comment.

unify spacing in CodeGen tests


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/include/clang-c/Index.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp

Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,10 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  // FIXME: implement
+  llvm_unreachable("unimplemented");
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5579,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct initializer}}
+// expected-note@-3 {{in instantiation of template class}}
 
 template
 struct B {
Index: clang/test/SemaCXX/P0960R3.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/P0960R3.cpp
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  A a;
+  int b[20];
+};
+
+struct D : public C, public A {
+  int a;
+};
+
+struct E { // 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-13 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 467621.
ayzhao added a comment.
Herald added a subscriber: arphaman.

implement constexpr and anonymous bitfields


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/include/clang-c/Index.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp

Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -643,6 +643,10 @@
 K = CXCursor_RequiresExpr;
 break;
 
+  case Stmt::CXXParenListInitExprClass:
+K = CXCursor_CXXParenListInitExpr;
+break;
+
   case Stmt::MSDependentExistsStmtClass:
 K = CXCursor_UnexposedStmt;
 break;
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,7 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   void VisitRequiresExpr(const RequiresExpr *E);
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
   void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -2999,6 +3000,10 @@
   for (ParmVarDecl *VD : E->getLocalParameters())
 AddDecl(VD);
 }
+void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
+  // FIXME: implement
+  llvm_unreachable("unimplemented");
+}
 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
   // Treat the expression like its syntactic form.
   Visit(E->getSyntacticForm());
@@ -5574,6 +5579,8 @@
 return cxstring::createRef("ConceptSpecializationExpr");
   case CXCursor_RequiresExpr:
 return cxstring::createRef("RequiresExpr");
+  case CXCursor_CXXParenListInitExpr:
+return cxstring::createRef("CXXParenListInitExpr");
   case CXCursor_UnexposedStmt:
 return cxstring::createRef("UnexposedStmt");
   case CXCursor_DeclStmt:
Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct initializer}}
+// expected-note@-3 {{in instantiation of template class}}
 
 template
 struct B {
Index: clang/test/SemaCXX/P0960R3.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/P0960R3.cpp
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  A a;
+  int b[20];
+};
+
+struct D : 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-06 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 465943.
ayzhao added a comment.

Fill out implementation for ClassifyExprValueKind(...)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp

Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct initializer}}
+// expected-note@-3 {{in instantiation of template class}}
 
 template
 struct B {
Index: clang/test/SemaCXX/P0960R3.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/P0960R3.cpp
@@ -0,0 +1,76 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  A a;
+  int b[20];
+};
+
+struct D : public C, public A {
+  int a;
+};
+
+struct E { // expected-note 3{{candidate constructor}}
+  struct F {
+F(int, int);
+  };
+  int a;
+  F f;
+};
+
+union U {
+  int a;
+  char* b;
+};
+
+void foo() {
+  A a(1954, 9, 21);
+  // expected-error@-1 {{excess elements in struct initializer}}
+  A b(2.1);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A e(-1.2, 9.8);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A s = static_cast(1.1);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A h = (A)3.1;
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A i = A(8.7);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+
+  B n(2022, {7, 8});
+  // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
+  B z(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}}
+
+  C o(A(1), 1, 2, 3, 4);
+  // expected-error@-1 {{excess elements in struct initializer}}
+  D R(1);
+  // expected-error@-1 {{no viable conversion from 'int' to 'C'}}
+  D I(C(1));
+  // expected-error@-1 {{functional-style cast from 'int' to 'C' is not allowed}}
+  D P(C(A(1)), 1);
+  // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
+
+  int arr1[](0, 1, 2, A(1));
+  // expected-error@-1 {{no viable conversion from 'A' to 'int'}}
+  int arr2[2](0, 1, 2);
+  // expected-error@-1 {{excess elements in array initializer}}
+
+  U u1("abcd");
+  // expected-error@-1 {{cannot initialize a member subobject of type 'int' with an lvalue of type 'const char[5]'}}
+  U u2(1, "efgh");
+  // expected-error@-1 {{excess elements in union initializer}}
+
+  E e1(1);
+  // expected-error@-1 {{no matching constructor for initialization of 'E'}}
+}
Index: clang/test/CodeGen/P0960R3.cpp

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-06 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 465927.
ayzhao added a comment.

implement StmtPrinter::VisitCXXParenListInitExpr(...)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp

Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct initializer}}
+// expected-note@-3 {{in instantiation of template class}}
 
 template
 struct B {
Index: clang/test/SemaCXX/P0960R3.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/P0960R3.cpp
@@ -0,0 +1,76 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  A a;
+  int b[20];
+};
+
+struct D : public C, public A {
+  int a;
+};
+
+struct E { // expected-note 3{{candidate constructor}}
+  struct F {
+F(int, int);
+  };
+  int a;
+  F f;
+};
+
+union U {
+  int a;
+  char* b;
+};
+
+void foo() {
+  A a(1954, 9, 21);
+  // expected-error@-1 {{excess elements in struct initializer}}
+  A b(2.1);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A e(-1.2, 9.8);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A s = static_cast(1.1);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A h = (A)3.1;
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A i = A(8.7);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+
+  B n(2022, {7, 8});
+  // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
+  B z(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}}
+
+  C o(A(1), 1, 2, 3, 4);
+  // expected-error@-1 {{excess elements in struct initializer}}
+  D R(1);
+  // expected-error@-1 {{no viable conversion from 'int' to 'C'}}
+  D I(C(1));
+  // expected-error@-1 {{functional-style cast from 'int' to 'C' is not allowed}}
+  D P(C(A(1)), 1);
+  // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
+
+  int arr1[](0, 1, 2, A(1));
+  // expected-error@-1 {{no viable conversion from 'A' to 'int'}}
+  int arr2[2](0, 1, 2);
+  // expected-error@-1 {{excess elements in array initializer}}
+
+  U u1("abcd");
+  // expected-error@-1 {{cannot initialize a member subobject of type 'int' with an lvalue of type 'const char[5]'}}
+  U u2(1, "efgh");
+  // expected-error@-1 {{excess elements in union initializer}}
+
+  E e1(1);
+  // expected-error@-1 {{no matching constructor for initialization of 'E'}}
+}
Index: clang/test/CodeGen/P0960R3.cpp

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-06 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 465913.
ayzhao added a comment.

implement initialization of remaining elements not in the list


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp

Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct initializer}}
+// expected-note@-3 {{in instantiation of template class}}
 
 template
 struct B {
Index: clang/test/SemaCXX/P0960R3.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/P0960R3.cpp
@@ -0,0 +1,76 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  A a;
+  int b[20];
+};
+
+struct D : public C, public A {
+  int a;
+};
+
+struct E { // expected-note 3{{candidate constructor}}
+  struct F {
+F(int, int);
+  };
+  int a;
+  F f;
+};
+
+union U {
+  int a;
+  char* b;
+};
+
+void foo() {
+  A a(1954, 9, 21);
+  // expected-error@-1 {{excess elements in struct initializer}}
+  A b(2.1);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A e(-1.2, 9.8);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A s = static_cast(1.1);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A h = (A)3.1;
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A i = A(8.7);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+
+  B n(2022, {7, 8});
+  // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
+  B z(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}}
+
+  C o(A(1), 1, 2, 3, 4);
+  // expected-error@-1 {{excess elements in struct initializer}}
+  D R(1);
+  // expected-error@-1 {{no viable conversion from 'int' to 'C'}}
+  D I(C(1));
+  // expected-error@-1 {{functional-style cast from 'int' to 'C' is not allowed}}
+  D P(C(A(1)), 1);
+  // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
+
+  int arr1[](0, 1, 2, A(1));
+  // expected-error@-1 {{no viable conversion from 'A' to 'int'}}
+  int arr2[2](0, 1, 2);
+  // expected-error@-1 {{excess elements in array initializer}}
+
+  U u1("abcd");
+  // expected-error@-1 {{cannot initialize a member subobject of type 'int' with an lvalue of type 'const char[5]'}}
+  U u2(1, "efgh");
+  // expected-error@-1 {{excess elements in union initializer}}
+
+  E e1(1);
+  // expected-error@-1 {{no matching constructor for initialization of 'E'}}
+}
Index: clang/test/CodeGen/P0960R3.cpp

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-05 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 465606.
ayzhao added a comment.

implement union support

Unions actually work as-is - the only thing I had to do was to cap the number 
of parameters at 1

Also add some tests.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp

Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct initializer}}
+// expected-note@-3 {{in instantiation of template class}}
 
 template
 struct B {
Index: clang/test/SemaCXX/P0960R3.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/P0960R3.cpp
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  A a;
+  int b[20];
+};
+
+struct D : public C, public A {
+  int a;
+};
+
+union U {
+  int a;
+  char* b;
+};
+
+void foo() {
+  A a(1954, 9, 21);
+  // expected-error@-1 {{excess elements in struct initializer}}
+  A b(2.1);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A e(-1.2, 9.8);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A s = static_cast(1.1);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A h = (A)3.1;
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A i = A(8.7);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+
+  B n(2022, {7, 8});
+  // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
+  B z(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}}
+
+  C o(A(1), 1, 2, 3, 4);
+  // expected-error@-1 {{excess elements in struct initializer}}
+  D R(1);
+  // expected-error@-1 {{no viable conversion from 'int' to 'C'}}
+  D I(C(1));
+  // expected-error@-1 {{functional-style cast from 'int' to 'C' is not allowed}}
+  D P(C(A(1)), 1);
+  // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
+
+  int arr1[](0, 1, 2, A(1));
+  // expected-error@-1 {{no viable conversion from 'A' to 'int'}}
+  int arr2[2](0, 1, 2);
+  // expected-error@-1 {{excess elements in array initializer}}
+
+  U u1("abcd");
+  // expected-error@-1 {{cannot initialize a member subobject of type 'int' with an lvalue of type 'const char[5]'}}
+  U u2(1, "efgh");
+  // expected-error@-1 {{excess elements in union initializer}}
+}
Index: clang/test/CodeGen/P0960R3.cpp
===
--- /dev/null
+++ clang/test/CodeGen/P0960R3.cpp
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 -std=c++20 

[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-05 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added inline comments.



Comment at: clang/lib/Sema/SemaInit.cpp:4151
+  QualType T = Entity.getType();
+  // FIXME: Union is unsupported.
+  int InitKind = T->isArrayType() ? 0 : 4;

ayzhao wrote:
> ayzhao wrote:
> > Hmm...it seems like as is this patch generates the correct code for 
> > parentheses-initialized `union`s:
> > 
> > ```
> > % cat ~/src/tests/test-union.cc
> > union C {
> >   float a;
> >   double b;
> > };
> > 
> > 
> > C foo() {
> >   return C(1);
> > }
> > 
> > % bin/clang++ -std=c++20 -emit-llvm -S -c -o - ~/src/tests/test-union.cc
> > ; ModuleID = '/usr/local/google/home/ayzhao/src/tests/test-union.cc'
> > source_filename = "/usr/local/google/home/ayzhao/src/tests/test-union.cc"
> > target datalayout = 
> > "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
> > target triple = "x86_64-unknown-linux-gnu"
> > 
> > %union.C = type { double }
> > 
> > ; Function Attrs: mustprogress noinline nounwind optnone uwtable
> > define dso_local double @_Z3foov() #0 {
> > entry:
> >   %retval = alloca %union.C, align 8
> >   store float 1.00e+00, ptr %retval, align 8
> >   %coerce.dive = getelementptr inbounds %union.C, ptr %retval, i32 0, i32 0
> >   %0 = load double, ptr %coerce.dive, align 8
> >   ret double %0
> > }
> > 
> > attributes #0 = { mustprogress noinline nounwind optnone uwtable 
> > "frame-pointer"="all" "min-legal-vector-width"="0" 
> > "no-trapping-math"="true" "stack-protector-buffer-size"="8" 
> > "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" 
> > "tune-cpu"="generic" }
> > 
> > !llvm.linker.options = !{}
> > !llvm.module.flags = !{!0, !1, !2, !3, !4}
> > !llvm.ident = !{!5}
> > 
> > !0 = !{i32 1, !"wchar_size", i32 4}
> > !1 = !{i32 8, !"PIC Level", i32 2}
> > !2 = !{i32 7, !"PIE Level", i32 2}
> > !3 = !{i32 7, !"uwtable", i32 2}
> > !4 = !{i32 7, !"frame-pointer", i32 2}
> > !5 = !{!"clang version 16.0.0"}
> > ```
> > 
> > I'm guessing this comment is specific to error messages.
> OK, I see what's going on. The following program fails to build:
> 
> ```
> #include 
> 
> union C {
>   int a;
>   std::string b;
> };
> 
> 
> C foo() {
>   return C("Hello, World!");
> }
> ```
> 
Actually, it turns out that the above example program is ill-formed because in 
a non-designated brace initialization, the parameter initializes the first 
element.

OTOH, there is a bug where

```
C(1, "Hello, World!");
```

compiles without errors because we check that # of parameters <= # of fields.

There may also be issues with anonymous `union`s in `struct`s - I'll have to 
investigate this further.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

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


[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-04 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added inline comments.



Comment at: clang/lib/Sema/SemaInit.cpp:4151
+  QualType T = Entity.getType();
+  // FIXME: Union is unsupported.
+  int InitKind = T->isArrayType() ? 0 : 4;

ayzhao wrote:
> Hmm...it seems like as is this patch generates the correct code for 
> parentheses-initialized `union`s:
> 
> ```
> % cat ~/src/tests/test-union.cc
> union C {
>   float a;
>   double b;
> };
> 
> 
> C foo() {
>   return C(1);
> }
> 
> % bin/clang++ -std=c++20 -emit-llvm -S -c -o - ~/src/tests/test-union.cc
> ; ModuleID = '/usr/local/google/home/ayzhao/src/tests/test-union.cc'
> source_filename = "/usr/local/google/home/ayzhao/src/tests/test-union.cc"
> target datalayout = 
> "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
> target triple = "x86_64-unknown-linux-gnu"
> 
> %union.C = type { double }
> 
> ; Function Attrs: mustprogress noinline nounwind optnone uwtable
> define dso_local double @_Z3foov() #0 {
> entry:
>   %retval = alloca %union.C, align 8
>   store float 1.00e+00, ptr %retval, align 8
>   %coerce.dive = getelementptr inbounds %union.C, ptr %retval, i32 0, i32 0
>   %0 = load double, ptr %coerce.dive, align 8
>   ret double %0
> }
> 
> attributes #0 = { mustprogress noinline nounwind optnone uwtable 
> "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" 
> "stack-protector-buffer-size"="8" "target-cpu"="x86-64" 
> "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
> 
> !llvm.linker.options = !{}
> !llvm.module.flags = !{!0, !1, !2, !3, !4}
> !llvm.ident = !{!5}
> 
> !0 = !{i32 1, !"wchar_size", i32 4}
> !1 = !{i32 8, !"PIC Level", i32 2}
> !2 = !{i32 7, !"PIE Level", i32 2}
> !3 = !{i32 7, !"uwtable", i32 2}
> !4 = !{i32 7, !"frame-pointer", i32 2}
> !5 = !{!"clang version 16.0.0"}
> ```
> 
> I'm guessing this comment is specific to error messages.
OK, I see what's going on. The following program fails to build:

```
#include 

union C {
  int a;
  std::string b;
};


C foo() {
  return C("Hello, World!");
}
```



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

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


[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-04 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao added inline comments.



Comment at: clang/lib/Sema/SemaInit.cpp:4151
+  QualType T = Entity.getType();
+  // FIXME: Union is unsupported.
+  int InitKind = T->isArrayType() ? 0 : 4;

Hmm...it seems like as is this patch generates the correct code for 
parentheses-initialized `union`s:

```
% cat ~/src/tests/test-union.cc
union C {
  float a;
  double b;
};


C foo() {
  return C(1);
}

% bin/clang++ -std=c++20 -emit-llvm -S -c -o - ~/src/tests/test-union.cc
; ModuleID = '/usr/local/google/home/ayzhao/src/tests/test-union.cc'
source_filename = "/usr/local/google/home/ayzhao/src/tests/test-union.cc"
target datalayout = 
"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

%union.C = type { double }

; Function Attrs: mustprogress noinline nounwind optnone uwtable
define dso_local double @_Z3foov() #0 {
entry:
  %retval = alloca %union.C, align 8
  store float 1.00e+00, ptr %retval, align 8
  %coerce.dive = getelementptr inbounds %union.C, ptr %retval, i32 0, i32 0
  %0 = load double, ptr %coerce.dive, align 8
  ret double %0
}

attributes #0 = { mustprogress noinline nounwind optnone uwtable 
"frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" 
"stack-protector-buffer-size"="8" "target-cpu"="x86-64" 
"target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }

!llvm.linker.options = !{}
!llvm.module.flags = !{!0, !1, !2, !3, !4}
!llvm.ident = !{!5}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
!3 = !{i32 7, !"uwtable", i32 2}
!4 = !{i32 7, !"frame-pointer", i32 2}
!5 = !{!"clang version 16.0.0"}
```

I'm guessing this comment is specific to error messages.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

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


[PATCH] D129531: [clang][C++20] P0960R3: Allow initializing aggregates from a parenthesized list of values

2022-10-03 Thread Alan Zhao via Phabricator via cfe-commits
ayzhao updated this revision to Diff 464738.
ayzhao edited the summary of this revision.
ayzhao added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

rebase


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129531

Files:
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Initialization.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
  clang/test/CXX/drs/dr2xx.cpp
  clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  clang/test/CodeGen/P0960R3.cpp
  clang/test/SemaCXX/P0960R3.cpp
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp

Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,pro20
 
 template  struct enable_ifv {};
 
@@ -20,7 +20,7 @@
 
 template
 struct A {
-// expected-note@-1+ {{candidate constructor}}
+// pre20-note@-1+ {{candidate constructor}}
   explicit(1 << a)
 // expected-note@-1 {{negative shift count -1}}
 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
@@ -28,8 +28,9 @@
 };
 
 A<-1> a(0);
-// expected-error@-1 {{no matching constructor}}
-// expected-note@-2 {{in instantiation of template class}}
+// pre20-error@-1 {{no matching constructor}}
+// pro20-error@-2 {{excess elements in struct initializer}}
+// expected-note@-3 {{in instantiation of template class}}
 
 template
 struct B {
Index: clang/test/SemaCXX/P0960R3.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/P0960R3.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
+
+struct A { // expected-note 4{{candidate constructor}}
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b[20];
+  int & // expected-note {{reference member declared here}}
+};
+
+struct C { // expected-note 2{{candidate constructor}}
+  A a;
+  int b[20];
+};
+
+struct D : public C, public A {
+  int a;
+};
+
+void foo() {
+  A a(1954, 9, 21);
+  // expected-error@-1 {{excess elements in struct initializer}}
+  A b(2.1);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A e(-1.2, 9.8);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A s = static_cast(1.1);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A h = (A)3.1;
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+  A i = A(8.7);
+  // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
+
+  B n(2022, {7, 8});
+  // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
+  B z(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}}
+
+  C o(A(1), 1, 2, 3, 4);
+  // expected-error@-1 {{excess elements in struct initializer}}
+  D R(1);
+  // expected-error@-1 {{no viable conversion from 'int' to 'C'}}
+  D I(C(1));
+  // expected-error@-1 {{functional-style cast from 'int' to 'C' is not allowed}}
+  D P(C(A(1)), 1);
+  // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
+
+  int arr1[](0, 1, 2, A(1));
+  // expected-error@-1 {{no viable conversion from 'A' to 'int'}}
+  int arr2[2](0, 1, 2);
+  // expected-error@-1 {{excess elements in array initializer}}
+}
Index: clang/test/CodeGen/P0960R3.cpp
===
--- /dev/null
+++ clang/test/CodeGen/P0960R3.cpp
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -std=c++20 %s -emit-llvm -o - | FileCheck %s
+
+struct A {
+  char i;
+  double j;
+};
+
+struct B {
+  A a;
+  int b;
+};
+
+struct C : public B, public A {};
+
+// CHECK-LABEL:   entry:
+// CHECK-NEXT:[[A1:%.*]] = alloca [[STRUCT_A:%.*]], align 8
+// CHECK-NEXT:[[B1:%.*]] = alloca