[clang] 4e02ff2 - [clang] Revert parentesized aggregate initalization patches
Alan Zhao via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 4 15:09:43 PST 2023
Author: Alan Zhao
Date: 2023-01-04T15:09:36-08:00
New Revision: 4e02ff2303f8a69cc2459b77bbb879b248df6ca9
URL: https://github.com/llvm/llvm-project/commit/4e02ff2303f8a69cc2459b77bbb879b248df6ca9
DIFF: https://github.com/llvm/llvm-project/commit/4e02ff2303f8a69cc2459b77bbb879b248df6ca9.diff
LOG: [clang] Revert parentesized aggregate initalization patches
This feature causes clang to crash when compiling Chrome - see
https://crbug.com/1405031 and
https://github.com/llvm/llvm-project/issues/59675
Revert "[clang] Fix a clang crash on invalid code in C++20 mode."
This reverts commit 32d7aae04fdb58e65a952f281ff2f2c3f396d98f.
Revert "[clang] Remove overly restrictive aggregate paren init logic"
This reverts commit c77a91bb7ba793ec3a6a5da3743ed55056291658.
Revert "[clang][C++20] P0960R3 and P1975R0: Allow initializing aggregates from a parenthesized list of values"
This reverts commit 40c52159d3ee337dbed14e4c73b5616ea354c337.
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang-c/Index.h
clang/include/clang/AST/ASTNodeTraverser.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/SemaCast.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/temp/temp.decls/temp.variadic/p4.cpp
clang/test/Lexer/cxx-features.cpp
clang/test/SemaCXX/cxx2a-explicit-bool.cpp
clang/test/SemaCXX/recovery-expr-type.cpp
clang/tools/libclang/CIndex.cpp
clang/tools/libclang/CXCursor.cpp
clang/www/cxx_status.html
Removed:
clang/test/CodeGen/paren-list-agg-init.cpp
clang/test/PCH/cxx_paren_init.cpp
clang/test/PCH/cxx_paren_init.h
clang/test/SemaCXX/paren-list-agg-init.cpp
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0fe0097400823..a3abdf45fead1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -714,10 +714,6 @@ C++20 Feature Support
(useful specially for constrained members). Fixes `GH50886 <https://github.com/llvm/llvm-project/issues/50886>`_.
- Implemented CWG2635 as a Defect Report, which prohibits structured bindings from being constrained.
-- Implemented `P0960R3: <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0960r3.html>`_
- and `P1975R0: <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1975r0.html>`_,
- which allows parenthesized aggregate-initialization.
-
C++2b Feature Support
^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index fd758ddde085d..5260085021928 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -1531,13 +1531,7 @@ enum CXCursorKind {
*/
CXCursor_RequiresExpr = 154,
- /**
- * Expression that references a C++20 parenthesized list aggregate
- * initializer.
- */
- CXCursor_CXXParenListInitExpr = 155,
-
- CXCursor_LastExpr = CXCursor_CXXParenListInitExpr,
+ CXCursor_LastExpr = CXCursor_RequiresExpr,
/* Statements */
CXCursor_FirstStmt = 200,
diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h
index cc60877805f98..151a9c6b58524 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -710,12 +710,6 @@ class ASTNodeTraverser
}
}
- void VisitCXXParenListInitExpr(const CXXParenListInitExpr *PLIE) {
- if (auto *Filler = PLIE->getArrayFiller()) {
- Visit(Filler, "array_filler");
- }
- }
-
void VisitBlockExpr(const BlockExpr *Node) { Visit(Node->getBlockDecl()); }
void VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
diff --git a/clang/include/clang/AST/ComputeDependence.h b/clang/include/clang/AST/ComputeDependence.h
index f62611cb4c3cf..3360fd11ab1f7 100644
--- a/clang/include/clang/AST/ComputeDependence.h
+++ b/clang/include/clang/AST/ComputeDependence.h
@@ -79,7 +79,6 @@ class CXXUnresolvedConstructExpr;
class CXXDependentScopeMemberExpr;
class MaterializeTemporaryExpr;
class CXXFoldExpr;
-class CXXParenListInitExpr;
class TypeTraitExpr;
class ConceptSpecializationExpr;
class SYCLUniqueStableNameExpr;
@@ -169,7 +168,6 @@ ExprDependence computeDependence(CXXUnresolvedConstructExpr *E);
ExprDependence computeDependence(CXXDependentScopeMemberExpr *E);
ExprDependence computeDependence(MaterializeTemporaryExpr *E);
ExprDependence computeDependence(CXXFoldExpr *E);
-ExprDependence computeDependence(CXXParenListInitExpr *E);
ExprDependence computeDependence(TypeTraitExpr *E);
ExprDependence computeDependence(ConceptSpecializationExpr *E,
bool ValueDependent);
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 858cd00efc4ec..f84ff303f235e 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -914,10 +914,7 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
CallInit,
/// Direct list-initialization (C++11)
- ListInit,
-
- /// Parenthesized list-initialization (C++20)
- ParenListInit
+ ListInit
};
/// Kinds of thread-local storage.
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index 715dba013e1bb..c2f6751d62ede 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -4713,130 +4713,6 @@ class CXXFoldExpr : public Expr {
}
};
-/// Represents a list-initialization with parenthesis.
-///
-/// As per P0960R3, this is a C++20 feature that allows aggregate to
-/// be initialized with a parenthesized list of values:
-/// ```
-/// struct A {
-/// int a;
-/// double b;
-/// };
-///
-/// void foo() {
-/// A a1(0); // Well-formed in C++20
-/// A a2(1.5, 1.0); // Well-formed in C++20
-/// }
-/// ```
-/// It has some sort of similiarity to braced
-/// list-initialization, with some
diff erences such as
-/// it allows narrowing conversion whilst braced
-/// list-initialization doesn't.
-/// ```
-/// struct A {
-/// char a;
-/// };
-/// void foo() {
-/// A a(1.5); // Well-formed in C++20
-/// A b{1.5}; // Ill-formed !
-/// }
-/// ```
-class CXXParenListInitExpr final
- : public Expr,
- private llvm::TrailingObjects<CXXParenListInitExpr, Expr *> {
- friend class TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
- unsigned NumExprs;
- unsigned NumUserSpecifiedExprs;
- SourceLocation InitLoc, LParenLoc, RParenLoc;
- Expr *ArrayFiller = nullptr;
-
- CXXParenListInitExpr(ArrayRef<Expr *> Args, QualType T,
- unsigned NumUserSpecifiedExprs, SourceLocation InitLoc,
- SourceLocation LParenLoc, SourceLocation RParenLoc)
- : Expr(CXXParenListInitExprClass, T,
- T->isLValueReferenceType() ? VK_LValue
- : T->isRValueReferenceType() ? VK_XValue
- : VK_PRValue,
- OK_Ordinary),
- NumExprs(Args.size()), NumUserSpecifiedExprs(NumUserSpecifiedExprs),
- InitLoc(InitLoc), LParenLoc(LParenLoc), RParenLoc(RParenLoc) {
- std::copy(Args.begin(), Args.end(), getTrailingObjects<Expr *>());
- assert(NumExprs >= NumUserSpecifiedExprs &&
- "number of user specified inits is greater than the number of "
- "passed inits");
- setDependence(computeDependence(this));
- }
-
- size_t numTrailingObjects(OverloadToken<Expr *>) const { return NumExprs; }
-
-public:
- static CXXParenListInitExpr *
- Create(ASTContext &C, ArrayRef<Expr *> Args, QualType T,
- unsigned NumUserSpecifiedExprs, SourceLocation InitLoc,
- SourceLocation LParenLoc, SourceLocation RParenLoc);
-
- static CXXParenListInitExpr *CreateEmpty(ASTContext &C, unsigned numExprs,
- EmptyShell Empty);
-
- explicit CXXParenListInitExpr(EmptyShell Empty, unsigned NumExprs)
- : Expr(CXXParenListInitExprClass, Empty), NumExprs(NumExprs),
- NumUserSpecifiedExprs(0) {}
-
- void updateDependence() { setDependence(computeDependence(this)); }
-
- ArrayRef<Expr *> getInitExprs() {
- return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumExprs);
- }
-
- const ArrayRef<Expr *> getInitExprs() const {
- return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumExprs);
- }
-
- ArrayRef<Expr *> getUserSpecifiedInitExprs() {
- return llvm::makeArrayRef(getTrailingObjects<Expr *>(),
- NumUserSpecifiedExprs);
- }
-
- const ArrayRef<Expr *> getUserSpecifiedInitExprs() const {
- return llvm::makeArrayRef(getTrailingObjects<Expr *>(),
- NumUserSpecifiedExprs);
- }
-
- SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; }
-
- SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
-
- SourceLocation getInitLoc() const LLVM_READONLY { return InitLoc; }
-
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getBeginLoc(), getEndLoc());
- }
-
- void setArrayFiller(Expr *E) { ArrayFiller = E; }
-
- Expr *getArrayFiller() { return ArrayFiller; }
-
- const Expr *getArrayFiller() const { return ArrayFiller; }
-
- child_range children() {
- Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
- return child_range(Begin, Begin + NumExprs);
- }
-
- const_child_range children() const {
- Stmt *const *Begin =
- reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>());
- return const_child_range(Begin, Begin + NumExprs);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXParenListInitExprClass;
- }
-};
-
/// Represents an expression that might suspend coroutine execution;
/// either a co_await or co_yield expression.
///
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 7036200c54866..127c86b163a6d 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -2852,7 +2852,6 @@ DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {})
DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
DEF_TRAVERSE_STMT(CXXFoldExpr, {})
DEF_TRAVERSE_STMT(AtomicExpr, {})
-DEF_TRAVERSE_STMT(CXXParenListInitExpr, {})
DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {
if (S->getLifetimeExtendedTemporaryDecl()) {
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 60ff607a3edc6..16ab35fcb7a67 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2164,9 +2164,6 @@ def err_init_list_bad_dest_type : Error<
def warn_cxx20_compat_aggregate_init_with_ctors : Warning<
"aggregate initialization of type %0 with user-declared constructors "
"is incompatible with C++20">, DefaultIgnore, InGroup<CXX20Compat>;
-def warn_cxx17_compat_aggregate_init_paren_list : Warning<
- "aggregate initialization of type %0 from a parenthesized list of values "
- "is a C++20 extension">, DefaultIgnore, InGroup<CXX20>;
def err_reference_bind_to_bitfield : Error<
"%select{non-const|volatile}0 reference cannot bind to "
diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td
index eeec01dd8c84d..c434b07c95a40 100644
--- a/clang/include/clang/Basic/StmtNodes.td
+++ b/clang/include/clang/Basic/StmtNodes.td
@@ -160,7 +160,6 @@ def FunctionParmPackExpr : StmtNode<Expr>;
def MaterializeTemporaryExpr : StmtNode<Expr>;
def LambdaExpr : StmtNode<Expr>;
def CXXFoldExpr : StmtNode<Expr>;
-def CXXParenListInitExpr: StmtNode<Expr>;
// C++ Coroutines TS expressions
def CoroutineSuspendExpr : StmtNode<Expr, 1>;
diff --git a/clang/include/clang/Sema/Initialization.h b/clang/include/clang/Sema/Initialization.h
index e5a98ba97f4f1..21adc9fa2ac0b 100644
--- a/clang/include/clang/Sema/Initialization.h
+++ b/clang/include/clang/Sema/Initialization.h
@@ -923,11 +923,7 @@ class InitializationSequence {
SK_OCLSamplerInit,
/// Initialize an opaque OpenCL type (event_t, queue_t, etc.) with zero
- SK_OCLZeroOpaqueType,
-
- /// Initialize an aggreagate with parenthesized list of values.
- /// This is a C++20 feature.
- SK_ParenthesizedListInit
+ SK_OCLZeroOpaqueType
};
/// A single step in the initialization sequence.
@@ -1103,10 +1099,6 @@ class InitializationSequence {
/// List-copy-initialization chose an explicit constructor.
FK_ExplicitConstructor,
-
- /// Parenthesized list initialization failed at some point.
- /// This is a C++20 feature.
- FK_ParenthesizedListInitFailed,
};
private:
@@ -1365,8 +1357,6 @@ class InitializationSequence {
/// from a zero constant.
void AddOCLZeroOpaqueTypeStep(QualType T);
- void AddParenthesizedListInitStep(QualType T);
-
/// Add steps to unwrap a initializer list for a reference around a
/// single element and rewrap it at the end.
void RewrapReferenceInitList(QualType T, InitListExpr *Syntactic);
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index 9ba94da03720e..81461e24b7a25 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -1861,9 +1861,6 @@ enum StmtCode {
/// A CXXBoolLiteralExpr record.
EXPR_CXX_BOOL_LITERAL,
- /// A CXXParenListInitExpr record.
- EXPR_CXX_PAREN_LIST_INIT,
-
EXPR_CXX_NULL_PTR_LITERAL, // CXXNullPtrLiteralExpr
EXPR_CXX_TYPEID_EXPR, // CXXTypeidExpr (of expr).
EXPR_CXX_TYPEID_TYPE, // CXXTypeidExpr (of type).
diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp
index f25b62d53f85d..40ebde06d7718 100644
--- a/clang/lib/AST/ComputeDependence.cpp
+++ b/clang/lib/AST/ComputeDependence.cpp
@@ -831,13 +831,6 @@ ExprDependence clang::computeDependence(CXXFoldExpr *E) {
return D;
}
-ExprDependence clang::computeDependence(CXXParenListInitExpr *E) {
- auto D = ExprDependence::None;
- for (const auto *A : E->getInitExprs())
- D |= A->getDependence();
- return D;
-}
-
ExprDependence clang::computeDependence(TypeTraitExpr *E) {
auto D = ExprDependence::None;
for (const auto *A : E->getArgs())
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index a735f95427d16..688f760b2234e 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -3644,7 +3644,6 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
case ShuffleVectorExprClass:
case ConvertVectorExprClass:
case AsTypeExprClass:
- case CXXParenListInitExprClass:
// These have a side-effect if any subexpression does.
break;
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index ea88b270b1e3f..b988f0fe13f7f 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -1757,21 +1757,3 @@ CUDAKernelCallExpr *CUDAKernelCallExpr::CreateEmpty(const ASTContext &Ctx,
alignof(CUDAKernelCallExpr));
return new (Mem) CUDAKernelCallExpr(NumArgs, HasFPFeatures, Empty);
}
-
-CXXParenListInitExpr *
-CXXParenListInitExpr::Create(ASTContext &C, ArrayRef<Expr *> Args, QualType T,
- unsigned NumUserSpecifiedExprs,
- SourceLocation InitLoc, SourceLocation LParenLoc,
- SourceLocation RParenLoc) {
- void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Args.size()));
- return new (Mem) CXXParenListInitExpr(Args, T, NumUserSpecifiedExprs, InitLoc,
- LParenLoc, RParenLoc);
-}
-
-CXXParenListInitExpr *CXXParenListInitExpr::CreateEmpty(ASTContext &C,
- unsigned NumExprs,
- EmptyShell Empty) {
- void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumExprs),
- alignof(CXXParenListInitExpr));
- return new (Mem) CXXParenListInitExpr(Empty, NumExprs);
-}
diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp
index 12193b7812f9b..88081d9ed73a5 100644
--- a/clang/lib/AST/ExprClassification.cpp
+++ b/clang/lib/AST/ExprClassification.cpp
@@ -445,11 +445,6 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
case Expr::SYCLUniqueStableNameExprClass:
return Cl::CL_PRValue;
break;
-
- case Expr::CXXParenListInitExprClass:
- if (isa<ArrayType>(E->getType()))
- return Cl::CL_ArrayTemporary;
- return Cl::CL_ClassTemporary;
}
llvm_unreachable("unhandled expression kind in classification");
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 120ceb9ad0814..78cfecbec9fd3 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -9836,9 +9836,6 @@ namespace {
bool VisitCXXConstructExpr(const CXXConstructExpr *E, QualType T);
bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E);
bool VisitBinCmp(const BinaryOperator *E);
- bool VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
- bool VisitCXXParenListOrInitListExpr(const Expr *ExprToVisit,
- ArrayRef<Expr *> Args);
};
}
@@ -9957,13 +9954,8 @@ bool RecordExprEvaluator::VisitCastExpr(const CastExpr *E) {
bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
if (E->isTransparent())
return Visit(E->getInit(0));
- return VisitCXXParenListOrInitListExpr(E, E->inits());
-}
-bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
- const Expr *ExprToVisit, ArrayRef<Expr *> Args) {
- const RecordDecl *RD =
- ExprToVisit->getType()->castAs<RecordType>()->getDecl();
+ const RecordDecl *RD = E->getType()->castAs<RecordType>()->getDecl();
if (RD->isInvalidDecl()) return false;
const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
@@ -9974,25 +9966,7 @@ bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
CXXRD && CXXRD->getNumBases());
if (RD->isUnion()) {
- const FieldDecl *Field;
- if (auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
- Field = ILE->getInitializedFieldInUnion();
- } else if (isa<CXXParenListInitExpr>(ExprToVisit)) {
- assert(Args.size() == 1 &&
- "Unions should have exactly 1 initializer in a C++ paren list");
-
- for (const FieldDecl *FD : RD->fields()) {
- if (FD->isUnnamedBitfield())
- continue;
-
- Field = FD;
- break;
- }
- } else {
- llvm_unreachable(
- "Expression is neither an init list nor a C++ paren list");
- }
-
+ const FieldDecl *Field = E->getInitializedFieldInUnion();
Result = APValue(Field);
if (!Field)
return true;
@@ -10003,7 +9977,7 @@ bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
// Is this
diff erence ever observable for initializer lists which
// we don't build?
ImplicitValueInitExpr VIE(Field->getType());
- const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
+ const Expr *InitExpr = E->getNumInits() ? E->getInit(0) : &VIE;
LValue Subobject = This;
if (!HandleLValueMember(Info, InitExpr, Subobject, Field, &Layout))
@@ -10032,8 +10006,8 @@ bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
// Initialize base classes.
if (CXXRD && CXXRD->getNumBases()) {
for (const auto &Base : CXXRD->bases()) {
- assert(ElementNo < Args.size() && "missing init for base class");
- const Expr *Init = Args[ElementNo];
+ assert(ElementNo < E->getNumInits() && "missing init for base class");
+ const Expr *Init = E->getInit(ElementNo);
LValue Subobject = This;
if (!HandleLValueBase(Info, Init, Subobject, CXXRD, &Base))
@@ -10060,18 +10034,18 @@ bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
LValue Subobject = This;
- bool HaveInit = ElementNo < Args.size();
+ bool HaveInit = ElementNo < E->getNumInits();
// FIXME: Diagnostics here should point to the end of the initializer
// list, not the start.
- if (!HandleLValueMember(Info, HaveInit ? Args[ElementNo] : ExprToVisit,
+ if (!HandleLValueMember(Info, HaveInit ? E->getInit(ElementNo) : E,
Subobject, Field, &Layout))
return false;
// Perform an implicit value-initialization for members beyond the end of
// the initializer list.
ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.IntTy : Field->getType());
- const Expr *Init = HaveInit ? Args[ElementNo++] : &VIE;
+ const Expr *Init = HaveInit ? E->getInit(ElementNo++) : &VIE;
if (Field->getType()->isIncompleteArrayType()) {
if (auto *CAT = Info.Ctx.getAsConstantArrayType(Init->getType())) {
@@ -10705,11 +10679,6 @@ namespace {
expandStringLiteral(Info, E, Result, AllocType);
return true;
}
- bool VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
- bool VisitCXXParenListOrInitListExpr(const Expr *ExprToVisit,
- ArrayRef<Expr *> Args,
- const Expr *ArrayFiller,
- QualType AllocType = QualType());
};
} // end anonymous namespace
@@ -10785,16 +10754,6 @@ bool ArrayExprEvaluator::VisitInitListExpr(const InitListExpr *E,
assert(!E->isTransparent() &&
"transparent array list initialization is not string literal init?");
- return VisitCXXParenListOrInitListExpr(E, E->inits(), E->getArrayFiller(),
- AllocType);
-}
-
-bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
- const Expr *ExprToVisit, ArrayRef<Expr *> Args, const Expr *ArrayFiller,
- QualType AllocType) {
- const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
- AllocType.isNull() ? ExprToVisit->getType() : AllocType);
-
bool Success = true;
assert((!Result.isArray() || Result.getArrayInitializedElts() == 0) &&
@@ -10803,12 +10762,13 @@ bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
if (Result.isArray() && Result.hasArrayFiller())
Filler = Result.getArrayFiller();
- unsigned NumEltsToInit = Args.size();
+ unsigned NumEltsToInit = E->getNumInits();
unsigned NumElts = CAT->getSize().getZExtValue();
+ const Expr *FillerExpr = E->hasArrayFiller() ? E->getArrayFiller() : nullptr;
// If the initializer might depend on the array index, run it for each
// array element.
- if (NumEltsToInit != NumElts && MaybeElementDependentArrayFiller(ArrayFiller))
+ if (NumEltsToInit != NumElts && MaybeElementDependentArrayFiller(FillerExpr))
NumEltsToInit = NumElts;
LLVM_DEBUG(llvm::dbgs() << "The number of elements to initialize: "
@@ -10826,9 +10786,10 @@ bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
}
LValue Subobject = This;
- Subobject.addArray(Info, ExprToVisit, CAT);
+ Subobject.addArray(Info, E, CAT);
for (unsigned Index = 0; Index != NumEltsToInit; ++Index) {
- const Expr *Init = Index < Args.size() ? Args[Index] : ArrayFiller;
+ const Expr *Init =
+ Index < E->getNumInits() ? E->getInit(Index) : FillerExpr;
if (!EvaluateInPlace(Result.getArrayInitializedElt(Index),
Info, Subobject, Init) ||
!HandleLValueArrayAdjustment(Info, Init, Subobject,
@@ -10844,10 +10805,9 @@ bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
// If we get here, we have a trivial filler, which we can just evaluate
// once and splat over the rest of the array elements.
- assert(ArrayFiller && "no array filler for incomplete init list");
+ assert(FillerExpr && "no array filler for incomplete init list");
return EvaluateInPlace(Result.getArrayFiller(), Info, Subobject,
- ArrayFiller) &&
- Success;
+ FillerExpr) && Success;
}
bool ArrayExprEvaluator::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) {
@@ -10964,15 +10924,6 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E,
.VisitCXXConstructExpr(E, Type);
}
-bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
- const CXXParenListInitExpr *E) {
- assert(dyn_cast<ConstantArrayType>(E->getType()) &&
- "Expression result is not a constant array type");
-
- return VisitCXXParenListOrInitListExpr(E, E->getInitExprs(),
- E->getArrayFiller());
-}
-
//===----------------------------------------------------------------------===//
// Integer Evaluation
//
@@ -13234,11 +13185,6 @@ bool RecordExprEvaluator::VisitBinCmp(const BinaryOperator *E) {
});
}
-bool RecordExprEvaluator::VisitCXXParenListInitExpr(
- const CXXParenListInitExpr *E) {
- return VisitCXXParenListOrInitListExpr(E, E->getInitExprs());
-}
-
bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
// We don't support assignment in C. C++ assignments don't get here because
// assignment is an lvalue in C++.
@@ -15682,7 +15628,6 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
case Expr::DependentCoawaitExprClass:
case Expr::CoyieldExprClass:
case Expr::SYCLUniqueStableNameExprClass:
- case Expr::CXXParenListInitExprClass:
return ICEDiag(IK_NotICE, E->getBeginLoc());
case Expr::InitListExprClass: {
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 0633e65f388f8..d63c626f95c82 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -4249,7 +4249,6 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
case Expr::OMPArrayShapingExprClass:
case Expr::OMPIteratorExprClass:
case Expr::CXXInheritedCtorInitExprClass:
- case Expr::CXXParenListInitExprClass:
llvm_unreachable("unexpected statement kind");
case Expr::ConstantExprClass:
diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp
index d174919609d79..69374f309e916 100644
--- a/clang/lib/AST/JSONNodeDumper.cpp
+++ b/clang/lib/AST/JSONNodeDumper.cpp
@@ -850,9 +850,6 @@ void JSONNodeDumper::VisitVarDecl(const VarDecl *VD) {
case VarDecl::CInit: JOS.attribute("init", "c"); break;
case VarDecl::CallInit: JOS.attribute("init", "call"); break;
case VarDecl::ListInit: JOS.attribute("init", "list"); break;
- case VarDecl::ParenListInit:
- JOS.attribute("init", "paren-list");
- break;
}
}
attributeOnlyIfTrue("isParameterPack", VD->isParameterPack());
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 1e0d8a5046755..bed7e67d30f9a 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -2465,13 +2465,6 @@ void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) {
OS << ")";
}
-void StmtPrinter::VisitCXXParenListInitExpr(CXXParenListInitExpr *Node) {
- OS << "(";
- llvm::interleaveComma(Node->getInitExprs(), OS,
- [&](Expr *E) { PrintExpr(E); });
- OS << ")";
-}
-
void StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
NestedNameSpecifierLoc NNS = E->getNestedNameSpecifierLoc();
if (NNS)
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 3820a78d74f0b..93c974314c58e 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -2193,10 +2193,6 @@ void StmtProfiler::VisitCXXFoldExpr(const CXXFoldExpr *S) {
ID.AddInteger(S->getOperator());
}
-void StmtProfiler::VisitCXXParenListInitExpr(const CXXParenListInitExpr *S) {
- VisitExpr(S);
-}
-
void StmtProfiler::VisitCoroutineBodyStmt(const CoroutineBodyStmt *S) {
VisitStmt(S);
}
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index a5573c117e629..02cd7541deb5e 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -1806,8 +1806,6 @@ void TextNodeDumper::VisitVarDecl(const VarDecl *D) {
case VarDecl::ListInit:
OS << " listinit";
break;
- case VarDecl::ParenListInit:
- OS << " parenlistinit";
}
}
if (D->needsDestruction(D->getASTContext()))
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 303bcc89f671c..5fdbc6a75201f 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -87,9 +87,8 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
void EmitMoveFromReturnSlot(const Expr *E, RValue Src);
- void EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, QualType ArrayQTy,
- Expr *ExprToVisit, ArrayRef<Expr *> Args,
- Expr *ArrayFiller);
+ void EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
+ QualType ArrayQTy, InitListExpr *E);
AggValueSlot::NeedsGCBarriers_t needsGC(QualType T) {
if (CGF.getLangOpts().getGC() && TypeRequiresGCollection(T))
@@ -173,9 +172,6 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
void VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO);
void VisitChooseExpr(const ChooseExpr *CE);
void VisitInitListExpr(InitListExpr *E);
- void VisitCXXParenListOrInitListExpr(Expr *ExprToVisit, ArrayRef<Expr *> Args,
- FieldDecl *InitializedFieldInUnion,
- Expr *ArrayFiller);
void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E,
llvm::Value *outerBegin = nullptr);
void VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
@@ -209,9 +205,6 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
}
void VisitVAArgExpr(VAArgExpr *E);
- void VisitCXXParenListInitExpr(CXXParenListInitExpr *E);
- void VisitCXXParenListOrInitListExpr(Expr *ExprToVisit, ArrayRef<Expr *> Args,
- Expr *ArrayFiller);
void EmitInitializationToLValue(Expr *E, LValue Address);
void EmitNullInitializationToLValue(LValue Address);
@@ -478,12 +471,10 @@ static bool isTrivialFiller(Expr *E) {
return false;
}
-/// Emit initialization of an array from an initializer list. ExprToVisit must
-/// be either an InitListEpxr a CXXParenInitListExpr.
+/// Emit initialization of an array from an initializer list.
void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
- QualType ArrayQTy, Expr *ExprToVisit,
- ArrayRef<Expr *> Args, Expr *ArrayFiller) {
- uint64_t NumInitElements = Args.size();
+ QualType ArrayQTy, InitListExpr *E) {
+ uint64_t NumInitElements = E->getNumInits();
uint64_t NumArrayElements = AType->getNumElements();
assert(NumInitElements <= NumArrayElements);
@@ -512,8 +503,7 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
CodeGen::CodeGenModule &CGM = CGF.CGM;
ConstantEmitter Emitter(CGF);
LangAS AS = ArrayQTy.getAddressSpace();
- if (llvm::Constant *C =
- Emitter.tryEmitForInitializer(ExprToVisit, AS, ArrayQTy)) {
+ if (llvm::Constant *C = Emitter.tryEmitForInitializer(E, AS, ArrayQTy)) {
auto GV = new llvm::GlobalVariable(
CGM.getModule(), C->getType(),
CGM.isTypeConstant(ArrayQTy, /* ExcludeCtorDtor= */ true),
@@ -578,11 +568,12 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
LValue elementLV = CGF.MakeAddrLValue(
Address(element, llvmElementType, elementAlign), elementType);
- EmitInitializationToLValue(Args[i], elementLV);
+ EmitInitializationToLValue(E->getInit(i), elementLV);
}
// Check whether there's a non-trivial array-fill expression.
- bool hasTrivialFiller = isTrivialFiller(ArrayFiller);
+ Expr *filler = E->getArrayFiller();
+ bool hasTrivialFiller = isTrivialFiller(filler);
// Any remaining elements need to be zero-initialized, possibly
// using the filler expression. We can skip this if the we're
@@ -625,8 +616,8 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
CodeGenFunction::RunCleanupsScope CleanupsScope(CGF);
LValue elementLV = CGF.MakeAddrLValue(
Address(currentElement, llvmElementType, elementAlign), elementType);
- if (ArrayFiller)
- EmitInitializationToLValue(ArrayFiller, elementLV);
+ if (filler)
+ EmitInitializationToLValue(filler, elementLV);
else
EmitNullInitializationToLValue(elementLV);
}
@@ -1600,76 +1591,46 @@ void AggExprEmitter::EmitNullInitializationToLValue(LValue lv) {
}
}
-void AggExprEmitter::VisitCXXParenListInitExpr(CXXParenListInitExpr *E) {
- ArrayRef<Expr *> InitExprs = E->getInitExprs();
- FieldDecl *InitializedFieldInUnion = nullptr;
- if (E->getType()->isUnionType()) {
- auto *RD =
- dyn_cast<CXXRecordDecl>(E->getType()->castAs<RecordType>()->getDecl());
- for (FieldDecl *FD : RD->fields()) {
- if (FD->isUnnamedBitfield())
- continue;
- InitializedFieldInUnion = FD;
- break;
- }
- }
-
- VisitCXXParenListOrInitListExpr(E, InitExprs, InitializedFieldInUnion,
- E->getArrayFiller());
-}
-
void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
- if (E->hadArrayRangeDesignator())
- CGF.ErrorUnsupported(E, "GNU array range designator extension");
-
- if (E->isTransparent())
- return Visit(E->getInit(0));
-
- VisitCXXParenListOrInitListExpr(
- E, E->inits(), E->getInitializedFieldInUnion(), E->getArrayFiller());
-}
-
-void AggExprEmitter::VisitCXXParenListOrInitListExpr(
- Expr *ExprToVisit, ArrayRef<Expr *> InitExprs,
- FieldDecl *InitializedFieldInUnion, Expr *ArrayFiller) {
#if 0
// FIXME: Assess perf here? Figure out what cases are worth optimizing here
// (Length of globals? Chunks of zeroed-out space?).
//
// If we can, prefer a copy from a global; this is a lot less code for long
// globals, and it's easier for the current optimizers to analyze.
- if (llvm::Constant *C =
- CGF.CGM.EmitConstantExpr(ExprToVisit, ExprToVisit->getType(), &CGF)) {
+ if (llvm::Constant* C = CGF.CGM.EmitConstantExpr(E, E->getType(), &CGF)) {
llvm::GlobalVariable* GV =
new llvm::GlobalVariable(CGF.CGM.getModule(), C->getType(), true,
llvm::GlobalValue::InternalLinkage, C, "");
- EmitFinalDestCopy(ExprToVisit->getType(),
- CGF.MakeAddrLValue(GV, ExprToVisit->getType()));
+ EmitFinalDestCopy(E->getType(), CGF.MakeAddrLValue(GV, E->getType()));
return;
}
#endif
+ if (E->hadArrayRangeDesignator())
+ CGF.ErrorUnsupported(E, "GNU array range designator extension");
- AggValueSlot Dest = EnsureSlot(ExprToVisit->getType());
+ if (E->isTransparent())
+ return Visit(E->getInit(0));
- LValue DestLV = CGF.MakeAddrLValue(Dest.getAddress(), ExprToVisit->getType());
+ AggValueSlot Dest = EnsureSlot(E->getType());
+
+ LValue DestLV = CGF.MakeAddrLValue(Dest.getAddress(), E->getType());
// Handle initialization of an array.
- if (ExprToVisit->getType()->isArrayType()) {
+ if (E->getType()->isArrayType()) {
auto AType = cast<llvm::ArrayType>(Dest.getAddress().getElementType());
- EmitArrayInit(Dest.getAddress(), AType, ExprToVisit->getType(), ExprToVisit,
- InitExprs, ArrayFiller);
+ EmitArrayInit(Dest.getAddress(), AType, E->getType(), E);
return;
}
- assert(ExprToVisit->getType()->isRecordType() &&
- "Only support structs/unions here!");
+ assert(E->getType()->isRecordType() && "Only support structs/unions here!");
// Do struct initialization; this code just sets each individual member
// to the approprate value. This makes bitfield support automatic;
// the disadvantage is that the generated code is more
diff icult for
// the optimizer, especially with bitfields.
- unsigned NumInitElements = InitExprs.size();
- RecordDecl *record = ExprToVisit->getType()->castAs<RecordType>()->getDecl();
+ unsigned NumInitElements = E->getNumInits();
+ RecordDecl *record = E->getType()->castAs<RecordType>()->getDecl();
// We'll need to enter cleanup scopes in case any of the element
// initializers throws an exception.
@@ -1687,7 +1648,7 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
// Emit initialization of base classes.
if (auto *CXXRD = dyn_cast<CXXRecordDecl>(record)) {
- assert(NumInitElements >= CXXRD->getNumBases() &&
+ assert(E->getNumInits() >= CXXRD->getNumBases() &&
"missing initializer for base class");
for (auto &Base : CXXRD->bases()) {
assert(!Base.isVirtual() && "should not see vbases here");
@@ -1701,7 +1662,7 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
AggValueSlot::DoesNotNeedGCBarriers,
AggValueSlot::IsNotAliased,
CGF.getOverlapForBaseInit(CXXRD, BaseRD, Base.isVirtual()));
- CGF.EmitAggExpr(InitExprs[curInitIndex++], AggSlot);
+ CGF.EmitAggExpr(E->getInit(curInitIndex++), AggSlot);
if (QualType::DestructionKind dtorKind =
Base.getType().isDestructedType()) {
@@ -1717,7 +1678,7 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
if (record->isUnion()) {
// Only initialize one field of a union. The field itself is
// specified by the initializer list.
- if (!InitializedFieldInUnion) {
+ if (!E->getInitializedFieldInUnion()) {
// Empty union; we have nothing to do.
#ifndef NDEBUG
@@ -1730,12 +1691,12 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
}
// FIXME: volatility
- FieldDecl *Field = InitializedFieldInUnion;
+ FieldDecl *Field = E->getInitializedFieldInUnion();
LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestLV, Field);
if (NumInitElements) {
// Store the initializer into the field
- EmitInitializationToLValue(InitExprs[0], FieldLoc);
+ EmitInitializationToLValue(E->getInit(0), FieldLoc);
} else {
// Default-initialize to null.
EmitNullInitializationToLValue(FieldLoc);
@@ -1759,7 +1720,7 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
// have a zeroed object, and the rest of the fields are
// zero-initializable.
if (curInitIndex == NumInitElements && Dest.isZeroed() &&
- CGF.getTypes().isZeroInitializable(ExprToVisit->getType()))
+ CGF.getTypes().isZeroInitializable(E->getType()))
break;
@@ -1769,7 +1730,7 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
if (curInitIndex < NumInitElements) {
// Store the initializer into the field.
- EmitInitializationToLValue(InitExprs[curInitIndex++], LV);
+ EmitInitializationToLValue(E->getInit(curInitIndex++), LV);
} else {
// We're out of initializers; default-initialize to null
EmitNullInitializationToLValue(LV);
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 208c6a8db1598..3e33d937e6a9c 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -674,7 +674,7 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
// C++20 features.
if (LangOpts.CPlusPlus20) {
- Builder.defineMacro("__cpp_aggregate_paren_init", "201902L");
+ // Builder.defineMacro("__cpp_aggregate_paren_init", "201902L");
// P0848 is implemented, but we're still waiting for other concepts
// issues to be addressed before bumping __cpp_concepts up to 202002L.
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 9fd9369c96418..bfdf06fc47c6f 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -451,7 +451,6 @@ static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT,
case InitializationSequence::FK_ConstructorOverloadFailed:
case InitializationSequence::FK_UserConversionOverloadFailed:
- case InitializationSequence::FK_ParenthesizedListInitFailed:
break;
}
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index ae0b4c62b1998..a1bfb57168c8a 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -13145,7 +13145,6 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
// Perform the initialization.
ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init);
- bool IsParenListInit = false;
if (!VDecl->isInvalidDecl()) {
InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl);
InitializationKind Kind = InitializationKind::CreateForInit(
@@ -13188,9 +13187,6 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
}
Init = Result.getAs<Expr>();
- IsParenListInit = !InitSeq.steps().empty() &&
- InitSeq.step_begin()->Kind ==
- InitializationSequence::SK_ParenthesizedListInit;
}
// Check for self-references within variable initializers.
@@ -13439,8 +13435,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
// class type.
if (CXXDirectInit) {
assert(DirectInit && "Call-style initializer must be direct init.");
- VDecl->setInitStyle(IsParenListInit ? VarDecl::ParenListInit
- : VarDecl::CallInit);
+ VDecl->setInitStyle(VarDecl::CallInit);
} else if (DirectInit) {
// This must be list-initialization. No other way is direct-initialization.
VDecl->setInitStyle(VarDecl::ListInit);
diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp
index 1786f3112d1a4..75ec180552f4f 100644
--- a/clang/lib/Sema/SemaExceptionSpec.cpp
+++ b/clang/lib/Sema/SemaExceptionSpec.cpp
@@ -1289,7 +1289,6 @@ CanThrowResult Sema::canThrow(const Stmt *S) {
case Expr::StmtExprClass:
case Expr::ConvertVectorExprClass:
case Expr::VAArgExprClass:
- case Expr::CXXParenListInitExprClass:
return canSubStmtsThrow(*this, S);
case Expr::CompoundLiteralExprClass:
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index d6ca63745f171..a92c24d577baa 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -3529,7 +3529,6 @@ void InitializationSequence::Step::Destroy() {
case SK_StdInitializerListConstructorCall:
case SK_OCLSamplerInit:
case SK_OCLZeroOpaqueType:
- case SK_ParenthesizedListInit:
break;
case SK_ConversionSequence:
@@ -3589,7 +3588,6 @@ bool InitializationSequence::isAmbiguous() const {
case FK_PlaceholderType:
case FK_ExplicitConstructor:
case FK_AddressOfUnaddressableFunction:
- case FK_ParenthesizedListInitFailed:
return false;
case FK_ReferenceInitOverloadFailed:
@@ -3825,13 +3823,6 @@ void InitializationSequence::AddOCLZeroOpaqueTypeStep(QualType T) {
Steps.push_back(S);
}
-void InitializationSequence::AddParenthesizedListInitStep(QualType T) {
- Step S;
- S.Kind = SK_ParenthesizedListInit;
- S.Type = T;
- Steps.push_back(S);
-}
-
void InitializationSequence::RewrapReferenceInitList(QualType T,
InitListExpr *Syntactic) {
assert(Syntactic->getNumInits() == 1 &&
@@ -5269,198 +5260,6 @@ static void TryDefaultInitialization(Sema &S,
}
}
-static void TryOrBuildParenListInitialization(
- Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind,
- ArrayRef<Expr *> Args, InitializationSequence &Sequence, bool VerifyOnly,
- ExprResult *Result = nullptr) {
- unsigned ArgIndexToProcess = 0;
- SmallVector<Expr *, 4> InitExprs;
- QualType ResultType;
- Expr *ArrayFiller = nullptr;
-
- // Process entities (i.e. array members, base classes, or class fields) by
- // adding an initialization expression to InitExprs for each entity to
- // initialize.
- auto ProcessEntities = [&](auto Range) -> bool {
- for (InitializedEntity SubEntity : Range) {
- // Unions should only have one initializer expression.
- // If there are more initializers than it will be caught when we check
- // whether Index equals Args.size().
- if (ArgIndexToProcess == 1 && Entity.getType()->isUnionType())
- return true;
-
- // Unnamed bitfields should not be initialized at all, either with an arg
- // or by default.
- if (SubEntity.getKind() == InitializedEntity::EK_Member &&
- cast<FieldDecl>(SubEntity.getDecl())->isUnnamedBitfield())
- continue;
-
- if (ArgIndexToProcess < Args.size()) {
- // There are still expressions in Args that haven't been processed.
- // Let's match them to the current entity to initialize.
- Expr *E = Args[ArgIndexToProcess++];
-
- // Incomplete array types indicate flexible array members. Do not allow
- // paren list initializations of structs with these members, as GCC
- // doesn't either.
- if (SubEntity.getKind() == InitializedEntity::EK_Member) {
- auto *FD = cast<FieldDecl>(SubEntity.getDecl());
- if (FD->getType()->isIncompleteArrayType()) {
- if (!VerifyOnly) {
- S.Diag(E->getBeginLoc(), diag::err_flexible_array_init)
- << SourceRange(E->getBeginLoc(), E->getEndLoc());
- S.Diag(FD->getLocation(), diag::note_flexible_array_member) << FD;
- }
- Sequence.SetFailed(
- InitializationSequence::FK_ParenthesizedListInitFailed);
- return false;
- }
- }
-
- InitializationKind SubKind = InitializationKind::CreateForInit(
- E->getExprLoc(), /*isDirectInit=*/false, E);
- InitializationSequence SubSeq(S, SubEntity, SubKind, E);
-
- if (SubSeq.Failed()) {
- if (!VerifyOnly)
- SubSeq.Diagnose(S, SubEntity, SubKind, E);
- else
- Sequence.SetFailed(
- InitializationSequence::FK_ParenthesizedListInitFailed);
-
- return false;
- }
- if (!VerifyOnly) {
- ExprResult ER = SubSeq.Perform(S, SubEntity, SubKind, E);
- InitExprs.push_back(ER.get());
- }
- } else {
- // We've processed all of the args, but there are still entities that
- // have to be initialized.
- if (SubEntity.getKind() == InitializedEntity::EK_Member) {
- // C++ [dcl.init]p17.6.2.2
- // The remaining elements are initialized with their default member
- // initializers, if any
- auto *FD = cast<FieldDecl>(SubEntity.getDecl());
- if (Expr *ICE = FD->getInClassInitializer(); ICE && !VerifyOnly) {
- ExprResult DIE = S.BuildCXXDefaultInitExpr(FD->getLocation(), FD);
- if (DIE.isInvalid())
- return false;
- S.checkInitializerLifetime(SubEntity, DIE.get());
- InitExprs.push_back(DIE.get());
- continue;
- };
- }
- // Remaining class elements without default member initializers and
- // array elements are value initialized:
- //
- // C++ [dcl.init]p17.6.2.2
- // The remaining elements...otherwise are value initialzed
- //
- // C++ [dcl.init]p17.5
- // if the destination type is an array, the object is initialized as
- // . follows. Let x1, . . . , xk be the elements of the expression-list
- // ...Let n denote the array size...the ith array element is...value-
- // initialized for each k < i <= n.
- InitializationKind SubKind = InitializationKind::CreateValue(
- Kind.getLocation(), Kind.getLocation(), Kind.getLocation(), true);
- InitializationSequence SubSeq(S, SubEntity, SubKind, std::nullopt);
- if (SubSeq.Failed()) {
- if (!VerifyOnly)
- SubSeq.Diagnose(S, SubEntity, SubKind, std::nullopt);
- return false;
- }
- if (!VerifyOnly) {
- ExprResult ER = SubSeq.Perform(S, SubEntity, SubKind, std::nullopt);
- if (SubEntity.getKind() == InitializedEntity::EK_ArrayElement) {
- ArrayFiller = ER.get();
- return true;
- }
- InitExprs.push_back(ER.get());
- }
- }
- }
- return true;
- };
-
- if (const ArrayType *AT =
- S.getASTContext().getAsArrayType(Entity.getType())) {
-
- SmallVector<InitializedEntity, 4> ElementEntities;
- uint64_t ArrayLength;
- // C++ [dcl.init]p17.5
- // if the destination type is an array, the object is initialized as
- // follows. Let x1, . . . , xk be the elements of the expression-list. If
- // the destination type is an array of unknown bound, it is define as
- // having k elements.
- if (const ConstantArrayType *CAT =
- S.getASTContext().getAsConstantArrayType(Entity.getType()))
- ArrayLength = CAT->getSize().getZExtValue();
- else
- ArrayLength = Args.size();
-
- if (ArrayLength >= Args.size()) {
- for (uint64_t I = 0; I < ArrayLength; ++I)
- ElementEntities.push_back(
- InitializedEntity::InitializeElement(S.getASTContext(), I, Entity));
-
- if (!ProcessEntities(ElementEntities))
- return;
-
- ResultType = S.Context.getConstantArrayType(
- AT->getElementType(), llvm::APInt(32, ArrayLength), nullptr,
- ArrayType::Normal, 0);
- }
- } else if (auto *RT = Entity.getType()->getAs<RecordType>()) {
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
-
- auto BaseRange = map_range(RD->bases(), [&S](auto &base) {
- return InitializedEntity::InitializeBase(S.getASTContext(), &base, false);
- });
- auto FieldRange = map_range(RD->fields(), [](auto *field) {
- return InitializedEntity::InitializeMember(field);
- });
-
- if (!ProcessEntities(BaseRange))
- return;
-
- if (!ProcessEntities(FieldRange))
- return;
-
- ResultType = Entity.getType();
- }
-
- // Not all of the args have been processed, so there must've been more args
- // then were required to initialize the element.
- if (ArgIndexToProcess < Args.size()) {
- Sequence.SetFailed(InitializationSequence::FK_ParenthesizedListInitFailed);
- if (!VerifyOnly) {
- QualType T = Entity.getType();
- int InitKind = T->isArrayType() ? 0 : T->isUnionType() ? 3 : 4;
- S.Diag(Kind.getLocation(), diag::err_excess_initializers)
- << InitKind << Args[ArgIndexToProcess]->getSourceRange();
- }
- return;
- }
-
- if (VerifyOnly) {
- Sequence.setSequenceKind(InitializationSequence::NormalSequence);
- Sequence.AddParenthesizedListInitStep(Entity.getType());
- } else if (Result) {
- SourceRange SR = Kind.getParenOrBraceRange();
- auto *CPLIE = CXXParenListInitExpr::Create(
- S.getASTContext(), InitExprs, ResultType, Args.size(),
- Kind.getLocation(), SR.getBegin(), SR.getEnd());
- CPLIE->setArrayFiller(ArrayFiller);
- *Result = CPLIE;
- S.Diag(Kind.getLocation(),
- diag::warn_cxx17_compat_aggregate_init_paren_list)
- << Kind.getLocation() << SR << ResultType;
- }
-
- return;
-}
-
/// Attempt a user-defined conversion between two types (C++ [dcl.init]),
/// which enumerates all conversion functions and performs overload resolution
/// to select the best.
@@ -6116,11 +5915,7 @@ void InitializationSequence::InitializeFrom(Sema &S,
TryListInitialization(S, Entity, Kind, cast<InitListExpr>(Initializer),
*this, TreatUnavailableAsInvalid);
AddParenthesizedArrayInitStep(DestType);
- } else if (S.getLangOpts().CPlusPlus20 && !TopLevelOfInitList &&
- Kind.getKind() == InitializationKind::IK_Direct)
- TryOrBuildParenListInitialization(S, Entity, Kind, Args, *this,
- /*VerifyOnly=*/true);
- else if (DestAT->getElementType()->isCharType())
+ } else if (DestAT->getElementType()->isCharType())
SetFailed(FK_ArrayNeedsInitListOrStringLiteral);
else if (IsWideCharCompatible(DestAT->getElementType(), Context))
SetFailed(FK_ArrayNeedsInitListOrWideStringLiteral);
@@ -6167,39 +5962,18 @@ void InitializationSequence::InitializeFrom(Sema &S,
if (Kind.getKind() == InitializationKind::IK_Direct ||
(Kind.getKind() == InitializationKind::IK_Copy &&
(Context.hasSameUnqualifiedType(SourceType, DestType) ||
- S.IsDerivedFrom(Initializer->getBeginLoc(), SourceType, DestType)))) {
- TryConstructorInitialization(S, Entity, Kind, Args, DestType, DestType,
- *this);
-
- // We fall back to the "no matching constructor" path if the
- // failed candidate set has functions other than the three default
- // constructors. For example, conversion function.
- if (const auto *RD =
- dyn_cast<CXXRecordDecl>(DestType->getAs<RecordType>()->getDecl());
- // In general, we should call isCompleteType for RD to check its
- // completeness, we don't call it here as it was already called in the
- // above TryConstructorInitialization.
- S.getLangOpts().CPlusPlus20 && RD && RD->hasDefinition() &&
- RD->isAggregate() && Failed() &&
- getFailureKind() == FK_ConstructorOverloadFailed) {
- // C++20 [dcl.init] 17.6.2.2:
- // - Otherwise, if no constructor is viable, the destination type is
- // an
- // aggregate class, and the initializer is a parenthesized
- // expression-list.
- TryOrBuildParenListInitialization(S, Entity, Kind, Args, *this,
- /*VerifyOnly=*/true);
- }
- } else {
- // - Otherwise (i.e., for the remaining copy-initialization cases),
- // user-defined conversion sequences that can convert from the
- // source type to the destination type or (when a conversion
- // function is used) to a derived class thereof are enumerated as
- // described in 13.3.1.4, and the best one is chosen through
- // overload resolution (13.3).
+ S.IsDerivedFrom(Initializer->getBeginLoc(), SourceType, DestType))))
+ TryConstructorInitialization(S, Entity, Kind, Args,
+ DestType, DestType, *this);
+ // - Otherwise (i.e., for the remaining copy-initialization cases),
+ // user-defined conversion sequences that can convert from the source
+ // type to the destination type or (when a conversion function is
+ // used) to a derived class thereof are enumerated as described in
+ // 13.3.1.4, and the best one is chosen through overload resolution
+ // (13.3).
+ else
TryUserDefinedConversion(S, DestType, Kind, Initializer, *this,
TopLevelOfInitList);
- }
return;
}
@@ -8459,7 +8233,6 @@ ExprResult InitializationSequence::Perform(Sema &S,
case SK_ConstructorInitializationFromList:
case SK_StdInitializerListConstructorCall:
case SK_ZeroInitialization:
- case SK_ParenthesizedListInit:
break;
}
@@ -9149,14 +8922,6 @@ ExprResult InitializationSequence::Perform(Sema &S,
CurInit.get()->getValueKind());
break;
}
- case SK_ParenthesizedListInit: {
- CurInit = nullptr;
- TryOrBuildParenListInitialization(S, Entity, Kind, Args, *this,
- /*VerifyOnly=*/false, &CurInit);
- if (CurInit.get() && ResultType)
- *ResultType = CurInit.get()->getType();
- break;
- }
}
}
@@ -9758,11 +9523,6 @@ bool InitializationSequence::Diagnose(Sema &S,
diag::note_explicit_ctor_deduction_guide_here) << false;
break;
}
-
- case FK_ParenthesizedListInitFailed:
- TryOrBuildParenListInitialization(S, Entity, Kind, Args, *this,
- /*VerifyOnly=*/false);
- break;
}
PrintInitLocationNote(S, Entity);
@@ -9929,10 +9689,6 @@ void InitializationSequence::dump(raw_ostream &OS) const {
case FK_ExplicitConstructor:
OS << "list copy initialization chose explicit constructor";
break;
-
- case FK_ParenthesizedListInitFailed:
- OS << "parenthesized list initialization failed";
- break;
}
OS << '\n';
return;
@@ -10104,9 +9860,6 @@ void InitializationSequence::dump(raw_ostream &OS) const {
case SK_OCLZeroOpaqueType:
OS << "OpenCL opaque type from zero";
break;
- case SK_ParenthesizedListInit:
- OS << "initialization from a parenthesized list of values";
- break;
}
OS << " [" << S->Type << ']';
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 36450892f9485..2ebd936b359f7 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -3859,16 +3859,6 @@ class TreeTransform {
return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
}
- ExprResult RebuildCXXParenListInitExpr(ArrayRef<Expr *> Args, QualType T,
- unsigned NumUserSpecifiedExprs,
- SourceLocation InitLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc) {
- return CXXParenListInitExpr::Create(getSema().Context, Args, T,
- NumUserSpecifiedExprs, InitLoc,
- LParenLoc, RParenLoc);
- }
-
/// Build a new atomic operation expression.
///
/// By default, performs semantic analysis to build the new expression.
@@ -14037,20 +14027,6 @@ TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
return Result;
}
-template <typename Derived>
-ExprResult
-TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
- SmallVector<Expr *, 4> TransformedInits;
- ArrayRef<Expr *> InitExprs = E->getInitExprs();
- if (TransformExprs(InitExprs.data(), InitExprs.size(), true,
- TransformedInits))
- return ExprError();
-
- return getDerived().RebuildCXXParenListInitExpr(
- TransformedInits, E->getType(), E->getUserSpecifiedInitExprs().size(),
- E->getInitLoc(), E->getBeginLoc(), E->getEndLoc());
-}
-
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 4ca6998b13370..2995becb7dd8d 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -2175,26 +2175,6 @@ void ASTStmtReader::VisitCXXFoldExpr(CXXFoldExpr *E) {
E->Opcode = (BinaryOperatorKind)Record.readInt();
}
-void ASTStmtReader::VisitCXXParenListInitExpr(CXXParenListInitExpr *E) {
- VisitExpr(E);
- unsigned ExpectedNumExprs = Record.readInt();
- assert(E->NumExprs == ExpectedNumExprs &&
- "expected number of expressions does not equal the actual number of "
- "serialized expressions.");
- E->NumUserSpecifiedExprs = Record.readInt();
- E->InitLoc = readSourceLocation();
- E->LParenLoc = readSourceLocation();
- E->RParenLoc = readSourceLocation();
- for (unsigned I = 0; I < ExpectedNumExprs; I++)
- E->getTrailingObjects<Expr *>()[I] = Record.readSubExpr();
-
- bool HasArrayFiller = Record.readBool();
- if (HasArrayFiller) {
- E->setArrayFiller(Record.readSubExpr());
- }
- E->updateDependence();
-}
-
void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
VisitExpr(E);
E->SourceExpr = Record.readSubExpr();
@@ -3986,11 +3966,6 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
S = new (Context) CXXFoldExpr(Empty);
break;
- case EXPR_CXX_PAREN_LIST_INIT:
- S = CXXParenListInitExpr::CreateEmpty(
- Context, /*numExprs=*/Record[ASTStmtReader::NumExprFields], Empty);
- break;
-
case EXPR_OPAQUE_VALUE:
S = new (Context) OpaqueValueExpr(Empty);
break;
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 935f3e7535ccb..6299a48708f7d 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -743,7 +743,6 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream,
RECORD(EXPR_USER_DEFINED_LITERAL);
RECORD(EXPR_CXX_STD_INITIALIZER_LIST);
RECORD(EXPR_CXX_BOOL_LITERAL);
- RECORD(EXPR_CXX_PAREN_LIST_INIT);
RECORD(EXPR_CXX_NULL_PTR_LITERAL);
RECORD(EXPR_CXX_TYPEID_EXPR);
RECORD(EXPR_CXX_TYPEID_TYPE);
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index 8ed7412070167..0dc9d4c7c859b 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -2081,23 +2081,6 @@ void ASTStmtWriter::VisitCXXFoldExpr(CXXFoldExpr *E) {
Code = serialization::EXPR_CXX_FOLD;
}
-void ASTStmtWriter::VisitCXXParenListInitExpr(CXXParenListInitExpr *E) {
- VisitExpr(E);
- ArrayRef<Expr *> InitExprs = E->getInitExprs();
- Record.push_back(InitExprs.size());
- Record.push_back(E->getUserSpecifiedInitExprs().size());
- Record.AddSourceLocation(E->getInitLoc());
- Record.AddSourceLocation(E->getBeginLoc());
- Record.AddSourceLocation(E->getEndLoc());
- for (Expr *InitExpr : E->getInitExprs())
- Record.AddStmt(InitExpr);
- bool HasArrayFiller = E->getArrayFiller();
- Record.push_back(HasArrayFiller);
- if (HasArrayFiller)
- Record.AddStmt(E->getArrayFiller());
- Code = serialization::EXPR_CXX_PAREN_LIST_INIT;
-}
-
void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
VisitExpr(E);
Record.AddStmt(E->getSourceExpr());
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index f9e76d85efdde..87a95d46f2987 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1901,7 +1901,6 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
case Stmt::ConceptSpecializationExprClass:
case Stmt::CXXRewrittenBinaryOperatorClass:
case Stmt::RequiresExprClass:
- case Expr::CXXParenListInitExprClass:
// Fall through.
// Cases we intentionally don't evaluate, since they don't need
diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
index cc5a406f7640d..2aa7dbf8a7633 100644
--- a/clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fexceptions -fcxx-exceptions -verify=expected,pre20 %s
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only -fexceptions -fcxx-exceptions -verify=expected,post20 %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fexceptions -fcxx-exceptions -verify %s
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only -fexceptions -fcxx-exceptions -verify %s
template<typename... Types> struct tuple;
template<int I> struct int_c;
@@ -99,12 +99,12 @@ struct HasMixins : public Mixins... {
HasMixins(int i);
};
-struct A { }; // pre20-note{{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const A' for 1st argument}} \
-// pre20-note{{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'A' for 1st argument}} \
-// pre20-note{{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}}
-struct B { }; // pre20-note{{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const B' for 1st argument}} \
-// pre20-note{{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'B' for 1st argument}} \
-// pre20-note{{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}}
+struct A { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const A' for 1st argument}} \
+// expected-note{{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'A' for 1st argument}} \
+// expected-note{{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}}
+struct B { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const B' for 1st argument}} \
+// expected-note{{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'B' for 1st argument}} \
+// expected-note{{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}}
struct C { };
struct D { };
@@ -126,10 +126,8 @@ HasMixins<Mixins...>::HasMixins(const HasMixins &other): Mixins(other)... { }
template<typename ...Mixins>
HasMixins<Mixins...>::HasMixins(int i): Mixins(i)... { }
-// pre20-error at -1 {{no matching constructor for initialization of 'A'}}
-// pre20-error at -2 {{no matching constructor for initialization of 'B'}}
-// post20-error at -3 {{excess elements in struct initializer}}
-// post20-error at -4 {{excess elements in struct initializer}}
+// expected-error at -1 {{no matching constructor for initialization of 'A'}}
+// expected-error at -2 {{no matching constructor for initialization of 'B'}}
void test_has_mixins() {
HasMixins<A, B> ab;
diff --git a/clang/test/CodeGen/paren-list-agg-init.cpp b/clang/test/CodeGen/paren-list-agg-init.cpp
deleted file mode 100644
index a7534fb907d2b..0000000000000
--- a/clang/test/CodeGen/paren-list-agg-init.cpp
+++ /dev/null
@@ -1,351 +0,0 @@
-// RUN: %clang_cc1 -std=c++20 %s -emit-llvm -triple x86_64-unknown-linux-gnu -o - | FileCheck %s
-
-template <typename T>
-struct IsChar {
- constexpr operator bool() const { return false; }
-};
-
-template<>
-struct IsChar<char> {
- constexpr operator bool() const { return true; }
-};
-
-template <typename T>
-concept SameAsChar = (bool)IsInt<T>();
-
-// CHECK-DAG: [[STRUCT_A:%.*]] = type { i8, double }
-struct A {
- char i;
- double j;
-
- template <SameAsChar T>
- operator T() const { return i; };
-};
-
-// CHECK-DAG: [[STRUCT_B:%.*]] = type { [[STRUCT_A]], i32 }
-struct B {
- A a;
- int b;
-};
-
-// CHECK-DAG: [[STRUCT_C:%.*]] = type <{ [[STRUCT_B]], [[STRUCT_A]], i32, [4 x i8] }>
-struct C : public B, public A {
- int c;
-};
-
-// CHECK-DAG: [[STRUCT_D:%.*]] = type { [[STRUCT_A]], [[STRUCT_A]], i8, [[STRUCT_A]] }
-struct D {
- A a;
- A b = A{2, 2.0};
- unsigned : 2;
- A c;
-};
-
-// CHECK-DAG: [[STRUCT_E:%.*]] = type { i32, ptr }
-struct E {
- int a;
- const char* fn = __builtin_FUNCTION();
- ~E() {};
-};
-
-// CHECK-DAG: [[STRUCT_F:%.*]] = type { i8 }
-struct F {
- F (int i = 1);
- F (const F &f) = delete;
- F (F &&f) = default;
-};
-
-// CHECK-DAG: [[STRUCT_G:%.*]] = type <{ i32, [[STRUCT_F]], [3 x i8] }>
-struct G {
- int a;
- F f;
-};
-
-// CHECK-DAG: [[UNION_U:%.*]] = type { [[STRUCT_A]] }
-// CHECK-DAG: [[STR:@.*]] = private unnamed_addr constant [6 x i8] {{.*}}foo18{{.*}}, align 1
-union U {
- unsigned : 1;
- A a;
- char b;
-};
-
-// CHECK-DAG: [[A1:@.*a1.*]] = internal constant [[STRUCT_A]] { i8 3, double 2.000000e+00 }, align 8
-constexpr A a1(3.1, 2.0);
-// CHECK-DAG: [[A2:@.*a2.*]] = internal constant [[STRUCT_A]] { i8 99, double 0.000000e+00 }, align 8
-constexpr auto a2 = static_cast<A>('c');
-// CHECK-DAG: [[B1:@.*b1.*]] = internal constant [[STRUCT_B]] { [[STRUCT_A]] { i8 99, double 0.000000e+00 }, i32 0 }, align 8
-constexpr B b1(A('c'));
-// CHECK-DAG: [[C1:@.*c1.*]] = internal constant { [[STRUCT_A]], i32, [4 x i8], i8, double, i32 } { [[STRUCT_A]] { i8 99, double 0.000000e+00 }, i32 0, [4 x i8] undef, i8 3, double 2.000000e+00, i32 0 }, align
-constexpr C c1(b1, a1);
-// CHECK-DAG: [[U1:@.*u1.*]] = internal constant [[UNION_U]] { [[STRUCT_A]] { i8 1, double 1.000000e+00 } }, align 8
-constexpr U u1(A(1, 1));
-// CHECK-DAG: [[D1:@.*d1.*]] = internal constant { [[STRUCT_A]], [[STRUCT_A]], [8 x i8], [[STRUCT_A]] } { [[STRUCT_A]] { i8 2, double 2.000000e+00 }, [[STRUCT_A]] { i8 2, double 2.000000e+00 }, [8 x i8] undef, [[STRUCT_A]] zeroinitializer }, align 8
-constexpr D d1(A(2, 2));
-// CHECK-DAG: [[ARR1:@.*arr1.*]] = internal constant [3 x i32] [i32 1, i32 2, i32 0], align 4
-constexpr int arr1[3](1, 2);
-// CHECK-DAG: [[ARR4:@.*arr4.*]] = internal constant [1 x i32] [i32 1], align 4
-constexpr int arr4[](1);
-// CHECK-DAG: [[ARR5:@.*arr5.*]] = internal constant [2 x i32] [i32 2, i32 0], align 4
-constexpr int arr5[2](2);
-
-// CHECK: define dso_local { i8, double } @{{.*foo1.*}}
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_A]], align 8
-// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[RETVAL]], ptr align 8 [[A1]], i64 16, i1 false)
-// CHECK-NEXT: [[TMP_0:%.*]] = load { i8, double }, ptr [[RETVAL]], align 8
-// CHECK-NEXT: ret { i8, double } [[TMP_0]]
-A foo1() {
- return a1;
-}
-
-// CHECK: define dso_local void @{{.*foo2.*}}(ptr noalias sret([[STRUCT_B]]) align 8 [[AGG_RESULT:%.*]])
-// CHECK-NEXT: entry:
-// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_RESULT]], ptr align 8 [[B1]], i64 24, i1 false)
-// CHECK-NEXT: ret void
-B foo2() {
- return b1;
-}
-
-// CHECK: define dso_local void @{{.*foo3.*}}(ptr noalias sret([[STRUCT_C]]) align 8 [[AGG_RESULT:%.*]])
-// CHECK-NEXT: entry:
-// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_RESULT]], ptr align 8 [[C1]], i64 48, i1 false)
-// CHECK-NEXT: ret void
-C foo3() {
- return c1;
-}
-
-// CHECK: define dso_local void @{{.*foo4.*}}
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[C2:%.*]] = alloca [[STRUCT_C:%.*]], align 8
-// CHECK-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_B:%.*]], align 8
-// CHECK-NEXT: [[REF_TMP_1:%.*]] = alloca [[STRUCT_A:%.*]], align 8
-// CHECK-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_B]], ptr [[REF_TMP]], i32 0, i32 0
-// CHECK-NEXT: [[I:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[A]], i32 0, i32 0
-// CHECK-NEXT: store i8 1, ptr [[I]], align 8
-// CHECK-NEXT: [[J:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[A]], i32 0, i32 1
-// CHECK-NEXT: store double 1.000000e+00, ptr [[J]], 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: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[C2]], ptr align 8 [[REF_TMP]], i64 24, i1 false)
-// CHECK-NEXT: [[TMP_0:%.*]] = getelementptr inbounds i8, ptr [[C2]], i64 24
-// CHECK-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[REF_TMP_1]], i32 0, i32 0
-// CHECK-NEXT: store i8 97, ptr [[I2]], align 8
-// CHECK-NEXT: [[J3:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[REF_TMP_1]], i32 0, i32 1
-// CHECK-NEXT: store double 0.000000e+00, ptr [[J3]], align 8
-// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[TMP_0]], ptr align 8 [[REF_TMP_1]], i64 16, i1 false)
-// CHECK-NEXT: [[C:%.*]] = getelementptr inbounds %struct.C, ptr %c2, i32 0, i32 2
-// CHECK-NEXT: store i32 2, ptr %c, align 8
-// CHECK-NEXT: ret void
-void foo4() {
- C c2(B(A(1, 1), 1), A('a'), 2);
-}
-
-// CHECK: define dso_local { i64, double } @{{.*foo5.*}}
-// CHECK-NEXT: entry:
-// CHECK-NEXT [[RETVAL:%.*]] = alloca [[UNION_U]], align 8
-// CHECK-NEXT call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[RETVAL]], ptr align 8 [[U1]], i64 16, i1 false)
-// CHECK-NEXT [[COERCE_DIVE:%.*]] = getelementptr inbounds [[UNION_U]], ptr %retval, i32 0, i32 0
-// CHECK-NEXT [[TMP_0:%.*]] = load { i64, double }, ptr [[COERCE_DIVE]], align 8
-// CHECK-NEXT ret { i64, double } [[TMP_0]]
-U foo5() {
- return u1;
-}
-
-
-// CHECK: define dso_local { i64, double } @{{.*foo6.*}}(i8 [[A_COERCE_0:%.*]], double [[A_COERCE_1:%.*]])
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[RETVAL:%.*]] = alloca [[UNION_U]], align 8
-// CHECK-NEXT: [[A:%.*]] = alloca [[STRUCT_A]], align 8
-// CHECK-NEXT: [[TMP_0:%.*]] = getelementptr inbounds { i8, double }, ptr [[A]], i32 0, i32 0
-// CHECK-NEXT: store i8 [[A_COERCE_0]], ptr [[TMP_0]], align 8
-// CHECK-NEXT: [[TMP_1:%.*]] = getelementptr inbounds { i8, double }, ptr [[A]], i32 0, i32 1
-// CHECK-NEXT: store double [[A_COERCE_1]], ptr [[TMP_1]], align 8
-// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[RETVAL]], ptr align 8 [[A]], i64 16, i1 false)
-// CHECK-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds [[UNION_U]], ptr [[RETVAL]], i32 0, i32 0
-// CHECK-NEXT: [[TMP_2:%.*]] = load { i64, double }, ptr [[COERCE_DIVE:%.*]], align 8
-// CHECK-NEXT: ret { i64, double } [[TMP_2]]
-U foo6(A a) {
- return U(a);
-}
-
-// CHECK: define dso_local void @{{.*foo7.*}}
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[D:%.*]] = alloca [[STRUCT_D:%.*]], align 8
-// CHECK-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_D]], ptr [[D]], i32 0, i32 0
-// CHECK-NEXT: [[I]] = getelementptr inbounds [[STRUCT_A:%.*]], ptr [[A]], i32 0, i32 0
-// CHECK-NEXT: store i8 1, ptr [[I]], align 8
-// CHECK-NEXT: [[J:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[A]], i32 0, i32 1
-// CHECK-NEXT: store double 1.000000e+00, ptr [[J]], align 8
-// CHECK-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_D]], ptr [[D]], i32 0, i32 1
-// CHECK-NEXT: [[I1:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[B]], i32 0, i32 0
-// CHECK-NEXT: store i8 11, ptr [[I1]], align 8
-// CHECK-NEXT: [[J2:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[B]], i32 0, i32 1
-// CHECK-NEXT: store double 1.100000e+01, ptr [[J2]], align 8
-// CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_D]], ptr [[D]], i32 0, i32 3
-// CHECK-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[C]], i32 0, i32 0
-// CHECK-NEXT: store i8 111, ptr [[I3]], align 8
-// CHECK-NEXT: [[J4:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[C]], i32 0, i32 1
-// CHECK-NEXT: store double 1.110000e+02, ptr [[J4]], align 8
-// CHECK-NEXT: ret void
-void foo7() {
- D d(A(1, 1), A(11, 11), A(111, 111));
-}
-
-// CHECK: dso_local void @{{.*foo8.*}}(ptr noalias sret([[STRUCT_D]]) align 8 [[AGG_RESULT:%.*]])
-// CHECK-NEXT: entry:
-// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_RESULT]], ptr align 8 [[D1]], i64 56, i1 false)
-// CHECK-NEXT: ret void
-D foo8() {
- return d1;
-}
-
-// CHECK: define dso_local void @{{.*foo9.*}}
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[D:%.*]] = alloca [[STRUCT_D:%.*]], align 8
-// CHECK-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_D]], ptr [[D]], i32 0, i32 0
-// CHECK-NEXT: [[I]] = getelementptr inbounds [[STRUCT_A:%.*]], ptr [[A]], i32 0, i32 0
-// CHECK-NEXT: store i8 1, ptr [[I]], align 8
-// CHECK-NEXT: [[J:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[A]], i32 0, i32 1
-// CHECK-NEXT: store double 1.000000e+00, ptr [[J]], align 8
-// CHECK-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_D]], ptr [[D]], i32 0, i32 1
-// CHECK-NEXT: [[I1:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[B]], i32 0, i32 0
-// CHECK-NEXT: store i8 2, ptr [[I1]], align 8
-// CHECK-NEXT: [[J2:%.*]] = getelementptr inbounds [[STRUCT_A]], ptr [[B]], i32 0, i32 1
-// CHECK-NEXT: store double 2.000000e+00, ptr [[J2]], align 8
-// CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_D]], ptr [[D]], i32 0, i32 3
-// CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[C]], i8 0, i64 16, i1 false)
-// CHECK-NEXT: ret void
-void foo9() {
- D d(A(1, 1));
-}
-
-// CHECK: define dso_local noundef ptr @{{.*foo10.*}}()
-// CHECK-NEXT: entry:
-// CHECK-NEXT: ret ptr [[ARR1]]
-const int* foo10() {
- return arr1;
-}
-
-// CHECK: define dso_local void @{{.*foo11.*}}
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
-// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
-// CHECK-NEXT: [[ARR_2:%.*]] = alloca [4 x i32], align 16
-// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
-// CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
-// CHECK-NEXT: [[ARRINIT_BEGIN:%.*]] = getelementptr inbounds [4 x i32], ptr [[ARR_2]], i64 0, i64 0
-// CHECK-NEXT: [[TMP_0:%.*]] = load i32, ptr [[A_ADDR]], align 4
-// CHECK-NEXT: store i32 [[TMP_0]], ptr [[ARRINIT_BEGIN]], align 4
-// CHECK-NEXT: [[ARRINIT_ELEM:%.*]] = getelementptr inbounds i32, ptr [[ARRINIT_BEGIN]], i64 1
-// CHECK-NEXT: [[TMP_1:%.*]] = load i32, ptr [[B_ADDR]], align 4
-// CHECK-NEXT: store i32 [[TMP_1]], ptr [[ARRINIT_ELEM]], align 4
-// CHECK-NEXT: [[ARRINIT_START:%.*]] = getelementptr inbounds i32, ptr [[ARRINIT_ELEM]], i64 1
-// CHECK-NEXT: [[ARRINIT_END:%.*]] = getelementptr inbounds i32, ptr [[ARRINIT_BEGIN]], i64 4
-// CHECK-NEXT: br label [[ARRINIT_BODY:%.*]]
-// CHECK: [[ARRINIT_CUR:%.*]] = phi ptr [ [[ARRINIT_START]], %entry ], [ [[ARRINIT_NEXT:%.*]], [[ARRINIT_BODY]] ]
-// CHECK-NEXT: store i32 0, ptr [[ARRINIT_CUR]], align 4
-// CHECK-NEXT: [[ARRINIT_NEXT]] = getelementptr inbounds i32, ptr [[ARRINIT_CUR]], i64 1
-// CHECK-NEXT: [[ARRINIT_DONE:%.*]] = icmp eq ptr [[ARRINIT_NEXT]], [[ARRINIT_END:%.*]]
-// CHECK-NEXT: br i1 [[ARRINIT_DONE]], label [[ARRINIT_END1:%.*]], label [[ARRINIT_BODY]]
-// CHECK: ret void
-void foo11(int a, int b) {
- int arr2[4](a, b);
-}
-
-// CHECK: define dso_local void @{{.*foo12.*}}
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
-// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
-// CHECK-NEXT: [[ARR_3:%.*]] = alloca [2 x i32], align 4
-// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
-// CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
-// CHECK-NEXT: [[ARRINIT_BEGIN:%.*]] = getelementptr inbounds [2 x i32], ptr [[ARR_3]], i64 0, i64 0
-// CHECK-NEXT: [[TMP_0:%.*]] = load i32, ptr [[A_ADDR]], align 4
-// CHECK-NEXT: store i32 [[TMP_0]], ptr [[ARRINIT_BEGIN]], align 4
-// CHECK-NEXT: [[ARRINIT_ELEMENT:%.*]] = getelementptr inbounds i32, ptr [[ARRINIT_BEGIN]], i64 1
-// CHECK-NEXT: [[TMP_1:%.*]] = load i32, ptr [[B_ADDR]], align 4
-// CHECK-NEXT: store i32 [[TMP_1]], ptr [[ARRINIT_ELEMENT]], align 4
-// CHECK-NEXT: ret void
-void foo12(int a, int b) {
- int arr3[](a, b);
-}
-
-// CHECK: define dso_local { i8, double } @{{.*foo13.*}}
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_A]], align 8
-// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[RETVAL]], ptr align 8 [[A2]], i64 16, i1 false)
-// CHECK-NEXT: [[TMP_0:%.*]] = load { i8, double }, ptr [[RETVAL]], align 8
-// CHECK-NEXT: ret { i8, double } [[TMP_0]]
-A foo13() {
- return a2;
-}
-
-// CHECK: define dso_local noundef ptr @{{.*foo14.*}}()
-// CHECK-NEXT: entry:
-// CHECK-NEXT: ret ptr [[ARR4]]
-const int* foo14() {
- return arr4;
-}
-
-// CHECK: define dso_local noundef ptr @{{.*foo15.*}}()
-// CHECK-NEXT: entry:
-// CHECK-NEXT: ret ptr [[ARR5]]
-const int* foo15() {
- return arr5;
-}
-
-// CHECK: define dso_local void @{{.*foo16.*}}
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[ARR_6:%.*arr6.*]] = alloca ptr, align 8
-// CHECK-NEXT: [[REF_TMP:%.*]] = alloca [1 x i32], align 4
-// CHECK-NEXT: [[ARRINIT_BEGIN:%.*]] = getelementptr inbounds [1 x i32], ptr [[REF_TMP]], i64 0, i64 0
-// CHECK-NEXT: store i32 3, ptr [[ARRINIT_BEGIN]], align 4
-// CHECK-NEXT: store ptr [[REF_TMP]], ptr [[ARR_6]], align 8
-// CHECK-NEXT: ret void
-void foo16() {
- int (&&arr6)[] = static_cast<int[]>(3);
-}
-
-// CHECK: define dso_local void @{{.*foo17.*}}
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[ARR_7:%.*arr7.*]] = alloca ptr, align 8
-// CHECK-NEXT: [[REF_TMP:%.*]] = alloca [2 x i32], align 4
-// CHECK-NEXT: [[ARRINIT_BEGIN:%.*]] = getelementptr inbounds [2 x i32], ptr [[REF_TMP]], i64 0, i64 0
-// CHECK-NEXT: store i32 4, ptr [[ARRINIT_BEGIN]], align 4
-// CHECK-NEXT: [[ARRINIT_START:%.*]] = getelementptr inbounds i32, ptr [[ARRINIT_BEGIN]], i64 1
-// CHECK-NEXT: [[ARRINIT_END:%.*]] = getelementptr inbounds i32, ptr [[ARRINIT_BEGIN]], i64 2
-// CHECK-NEXT: br label [[ARRINIT_BODY]]
-// CHECK: [[ARRINIT_CUR:%.*]] = phi ptr [ [[ARRINIT_START]], %entry ], [ [[ARRINIT_NEXT:%.*]], [[ARRINIT_BODY]] ]
-// CHECK-NEXT: store i32 0, ptr [[ARRINIT_CUR]], align 4
-// CHECK-NEXT: [[ARRINIT_NEXT]] = getelementptr inbounds i32, ptr [[ARRINIT_CUR]], i64 1
-// CHECK-NEXT: [[ARRINIT_DONE:%.*]] = icmp eq ptr [[ARRINIT_NEXT]], [[ARRINIT_END:%.*]]
-// CHECK-NEXT: br i1 [[ARRINIT_DONE]], label [[ARRINIT_END1:%.*]], label [[ARRINIT_BODY]]
-// CHECK: store ptr [[REF_TMP]], ptr [[ARR_7]], align 8
-// CHECK: ret void
-void foo17() {
- int (&&arr7)[2] = static_cast<int[2]>(4);
-}
-
-// CHECK: define dso_local void @{{.*foo18.*}}
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[E:%.*e.*]] = alloca [[STRUCT_E]], align 8
-// CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds [[STRUCT_E]], ptr [[E]], i32 0, i32 0
-// CHECK-NEXT: store i32 1, ptr [[A]], align 8
-// CHECK-NEXT: [[FN:%.*fn.*]] = getelementptr inbounds [[STRUCT_E]], ptr [[E]], i32 0, i32 1
-// CHECK-NEXT: store ptr [[STR]], ptr [[FN]], align 8
-// CHECK: ret void
-void foo18() {
- E e(1);
-}
-
-// CHECK: define dso_local void @{{.*foo19.*}}
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[G:%.*g.*]] = alloca [[STRUCT_G]], align 4
-// CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds [[STRUCT_G]], ptr [[G]], i32 0, i32 0
-// CHECK-NEXT: store i32 2, ptr [[A]], align 4
-// CHECK-NEXT: [[F:%.*f.*]] = getelementptr inbounds [[STRUCT_G]], ptr [[G]], i32 0, i32 1
-// CHECk-NEXT: call void @{{.*F.*}}(ptr noundef nonnull align 1 dereferenceable(1)) [[F]], ie32 noundef 1)
-// CHECK: ret void
-void foo19() {
- G g(2);
-}
diff --git a/clang/test/Lexer/cxx-features.cpp b/clang/test/Lexer/cxx-features.cpp
index 4a2bf56450df8..67b5265d7daf0 100644
--- a/clang/test/Lexer/cxx-features.cpp
+++ b/clang/test/Lexer/cxx-features.cpp
@@ -61,7 +61,8 @@
// --- C++20 features ---
-#if check(aggregate_paren_init, 0, 0, 0, 0, 201902, 201902)
+#if check(aggregate_paren_init, 0, 0, 0, 0, 0, 0)
+// FIXME: 201902 in C++20
#error "wrong value for __cpp_aggregate_paren_init"
#endif
diff --git a/clang/test/PCH/cxx_paren_init.cpp b/clang/test/PCH/cxx_paren_init.cpp
deleted file mode 100644
index 5539b160bf7a2..0000000000000
--- a/clang/test/PCH/cxx_paren_init.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-// RUN: %clang_cc1 -x c++ -std=c++20 -triple x86_64-unknown-linux-gnu -emit-pch -o %t %S/cxx_paren_init.h
-// RUN: %clang_cc1 -x c++ -std=c++20 -triple x86_64-unknown-linux-gnu -include-pch %t %s -S -emit-llvm -o - | FileCheck %s
-
-// CHECK-DAG: [[STRUCT_S:%.*]] = type { i32, i32 }
-// CHECK-DAG: @{{.*s.*}} = {{(dso_local )?}}global [[STRUCT_S]] { i32 1, i32 2 }, align 4
-S s = foo(1, 2);
-
-// CHECK: define dso_local void @{{.*bar.*}}
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[I_ADDR:%.*]] = alloca i32, align 4
-// CHECK-NEXT: [[J_ADDR:%.*]] = alloca i32, align 4
-// CHECK-NEXT: [[ARR:%.*]] = alloca [4 x i32], align 16
-// CHECK-NEXT: store i32 [[A:%.*]], ptr [[I_ADDR]], align 4
-// CHECK-NEXT: store i32 [[B:%.*]], ptr [[J_ADDR]], align 4
-// CHECK-NEXT: [[ARRINIT_BEGIN:%.*]] = getelementptr inbounds [4 x i32], ptr [[ARR]], i64 0, i64 0
-// CHECK-NEXT: [[TMP_0:%.*]] = load i32, ptr [[I_ADDR]], align 4
-// CHECK-NEXT: store i32 [[TMP_0]], ptr [[ARRINIT_BEGIN]], align 4
-// CHECK-NEXT: [[ARRINIT_ELEM:%.*]] = getelementptr inbounds i32, ptr [[ARRINIT_BEGIN]], i64 1
-// CHECK-NEXT: [[TMP_1:%.*]] = load i32, ptr [[J_ADDR]], align 4
-// CHECK-NEXT: store i32 [[TMP_1]], ptr [[ARRINIT_ELEM]], align 4
-// CHECK-NEXT: [[ARRINIT_START:%.*]] = getelementptr inbounds i32, ptr [[ARRINIT_ELEM]], i64 1
-// CHECK-NEXT: [[ARRINIT_END:%.*]] = getelementptr inbounds i32, ptr [[ARRINIT_BEGIN]], i64 4
-// CHECK-NEXT: br label [[ARRINIT_BODY:%.*]]
-// CHECK: [[ARRINIT_CUR:%.*]] = phi ptr [ [[ARRINIT_START]], %entry ], [ [[ARRINIT_NEXT:%.*]], [[ARRINIT_BODY]] ]
-// CHECK-NEXT: store i32 0, ptr [[ARRINIT_CUR]], align 4
-// CHECK-NEXT: [[ARRINIT_NEXT]] = getelementptr inbounds i32, ptr [[ARRINIT_CUR]], i64 1
-// CHECK-NEXT: [[ARRINIT_DONE:%.*]] = icmp eq ptr [[ARRINIT_NEXT]], [[ARRINIT_END:%.*]]
-// CHECK-NEXT: br i1 [[ARRINIT_DONE]], label [[ARRINIT_END1:%.*]], label [[ARRINIT_BODY]]
-// CHECK: ret void
diff --git a/clang/test/PCH/cxx_paren_init.h b/clang/test/PCH/cxx_paren_init.h
deleted file mode 100644
index ed3cd56a5ccc2..0000000000000
--- a/clang/test/PCH/cxx_paren_init.h
+++ /dev/null
@@ -1,5 +0,0 @@
-struct S { int i, j; };
-
-constexpr S foo(int i, int j) { return S(i, j); };
-
-void bar(int i, int j) { int arr[4](i, j); };
diff --git a/clang/test/SemaCXX/cxx2a-explicit-bool.cpp b/clang/test/SemaCXX/cxx2a-explicit-bool.cpp
index 9fdc059493aac..ad2a3a1ea75e9 100644
--- a/clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ b/clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -1,5 +1,5 @@
-// 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,post20
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
template <bool b, auto val> struct enable_ifv {};
@@ -20,7 +20,7 @@ namespace special_cases
template<int a>
struct A {
-// pre20-note at -1+ {{candidate constructor}}
+// expected-note at -1+ {{candidate constructor}}
explicit(1 << a)
// expected-note at -1 {{negative shift count -1}}
// expected-error at -2 {{explicit specifier argument is not a constant expression}}
@@ -28,9 +28,8 @@ struct A {
};
A<-1> a(0);
-// pre20-error at -1 {{no matching constructor}}
-// post20-error at -2 {{excess elements in struct initializer}}
-// expected-note at -3 {{in instantiation of template class}}
+// expected-error at -1 {{no matching constructor}}
+// expected-note at -2 {{in instantiation of template class}}
template<int a>
struct B {
diff --git a/clang/test/SemaCXX/paren-list-agg-init.cpp b/clang/test/SemaCXX/paren-list-agg-init.cpp
deleted file mode 100644
index 5f42b15243b95..0000000000000
--- a/clang/test/SemaCXX/paren-list-agg-init.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-// 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 &&c; // expected-note {{reference member declared here}}
-};
-
-struct C { // expected-note 5{{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}}
-};
-
-template <typename T>
-struct G {
- T t1;
- T t2;
-};
-
-struct H {
- virtual void foo() = 0;
-};
-
-struct I : public H { // expected-note 3{{candidate constructor}}
- int i, j;
- void foo() override {}
-};
-
-struct J {
- int a;
- int b[]; // expected-note {{initialized flexible array member 'b' is here}}
-};
-
-union U {
- int a;
- char* b;
-};
-
-template <typename T, char CH>
-void bar() {
- T t = 0;
- A a(CH, 1.1); // OK; C++ paren list constructors are supported in semantic tree transformations.
- // beforecxx20-warning at -1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
-}
-
-template <class T, class... Args>
-T Construct(Args... args) {
- return T(args...); // OK; variadic arguments can be used in paren list initializers.
- // beforecxx20-warning at -1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
-}
-
-void foo() {
- A a1(1954, 9, 21);
- // expected-error at -1 {{excess elements in struct initializer}}
- A a2(2.1);
- // expected-warning at -1 {{implicit conversion from 'double' to 'char'}}
- // beforecxx20-warning at -2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
- A a3(-1.2, 9.8);
- // expected-warning at -1 {{implicit conversion from 'double' to 'char'}}
- // beforecxx20-warning at -2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
- A a4 = static_cast<A>(1.1);
- // expected-warning at -1 {{implicit conversion from 'double' to 'char'}}
- // beforecxx20-warning at -2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
- A a5 = (A)3.1;
- // expected-warning at -1 {{implicit conversion from 'double' to 'char'}}
- // beforecxx20-warning at -2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
- A a6 = A(8.7);
- // expected-warning at -1 {{implicit conversion from 'double' to 'char'}}
- // beforecxx20-warning at -2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
-
- B b1(2022, {7, 8});
- // expected-error at -1 {{no viable conversion from 'int' to 'A'}}
- B b2(A(1), {}, 1);
- // expected-error at -1 {{reference member 'c' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
- // beforecxx20-warning at -2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
- // beforecxx20-warning at -3 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
-
- C c(A(1), 1, 2, 3, 4);
- // expected-error at -1 {{array initializer must be an initializer list}}
- // beforecxx20-warning at -2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
- D d1(1);
- // expected-error at -1 {{no viable conversion from 'int' to 'C'}}
- D d2(C(1));
- // expected-error at -1 {{no matching conversion for functional-style cast from 'int' to 'C'}}
- // beforecxx20-warning at -2 {{aggregate initialization of type 'D' from a parenthesized list of values is a C++20 extension}}
- D d3(C(A(1)), 1);
- // expected-error at -1 {{no viable conversion from 'int' to 'A'}}
- // beforecxx20-warning at -2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
- // beforecxx20-warning at -3 {{aggregate initialization of type 'C' from a parenthesized list of values is a C++20 extension}}
-
- int arr1[](0, 1, 2, A(1));
- // expected-error at -1 {{no viable conversion from 'A' to 'int'}}
- // beforecxx20-warning at -2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
-
- int arr2[2](0, 1, 2);
- // expected-error at -1 {{excess elements in array initializer}}
-
- // We should not build paren list initilizations for IK_COPY.
- int arr3[1] = 1;
- // expected-error at -1 {{array initializer must be an initializer list}}
-
- U u1("abcd");
- // expected-error at -1 {{cannot initialize a member subobject of type 'int' with an lvalue of type 'const char[5]'}}
- U u2(1, "efgh");
- // expected-error at -1 {{excess elements in union initializer}}
-
- E e1(1);
- // expected-error at -1 {{no matching constructor for initialization of 'E'}}
-
- constexpr F f1(1);
- // expected-error at -1 {{constexpr variable 'f1' must be initialized by a constant expression}}
- // beforecxx20-warning at -2 {{aggregate initialization of type 'const F' from a parenthesized list of values is a C++20 extension}}
-
- constexpr F f2(1, 1); // OK: f2.b is initialized by a constant expression.
- // beforecxx20-warning at -1 {{aggregate initialization of type 'const F' from a parenthesized list of values is a C++20 extension}}
-
- bar<char, 1>();
-
- G<char> g('b', 'b');
- // beforecxx20-warning at -1 {{aggregate initialization of type 'G<char>' from a parenthesized list of values is a C++20 extension}}
-
- A a7 = Construct<A>('i', 2.2);
- // beforecxx20-note at -1 {{in instantiation of function template specialization 'Construct<A, char, double>' requested here}}
-
- int arr4[](1, 2);
- // beforecxx20-warning at -1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
-
- int arr5[2](1, 2);
- // beforecxx20-warning at -1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
-
- I i(1, 2);
- // expected-error at -1 {{no matching constructor for initialization of 'I'}}
-
- J j(1, {2, 3});
- // expected-error at -1 {{initialization of flexible array member is not allowed}}
-
- static_assert(__is_trivially_constructible(A, char, double));
- static_assert(__is_trivially_constructible(A, char, int));
- static_assert(__is_trivially_constructible(A, char));
-
- static_assert(__is_trivially_constructible(D, C, A, int));
- static_assert(__is_trivially_constructible(D, C));
-
- static_assert(__is_trivially_constructible(int[2], int, int));
- static_assert(__is_trivially_constructible(int[2], int, double));
- static_assert(__is_trivially_constructible(int[2], int));
-}
diff --git a/clang/test/SemaCXX/recovery-expr-type.cpp b/clang/test/SemaCXX/recovery-expr-type.cpp
index 479039f284799..a5ba1ae2b8222 100644
--- a/clang/test/SemaCXX/recovery-expr-type.cpp
+++ b/clang/test/SemaCXX/recovery-expr-type.cpp
@@ -1,6 +1,4 @@
-// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -o - %s -std=gnu++17 -fsyntax-only -verify
-// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -o - %s -std=gnu++20 -fsyntax-only -verify
-
+// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -frecovery-ast -frecovery-ast-type -o - %s -std=gnu++17 -fsyntax-only -verify
namespace test0 {
struct Indestructible {
@@ -173,13 +171,3 @@ void f() {
S.m(1); // no crash
}
}
-
-namespace test16 {
-// verify we do not crash on incomplete class type.
-template<typename T, typename U> struct A; // expected-note 5{{template is declared here}}
-A<int, int> foo() { // expected-error {{implicit instantiation of undefined template}}
- if (1 == 1)
- return A<int, int>{1}; // expected-error 2{{implicit instantiation of undefined template}}
- return A<int, int>(1); // expected-error 2{{implicit instantiation of undefined template}}
-}
-}
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 06fc65136e3bd..057fa594cc24e 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2139,7 +2139,6 @@ class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
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);
@@ -3007,9 +3006,6 @@ void EnqueueVisitor::VisitRequiresExpr(const RequiresExpr *E) {
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());
@@ -5591,8 +5587,6 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
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:
diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp
index d48063f105f9f..3eda1e3e38d85 100644
--- a/clang/tools/libclang/CXCursor.cpp
+++ b/clang/tools/libclang/CXCursor.cpp
@@ -643,10 +643,6 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
K = CXCursor_RequiresExpr;
break;
- case Stmt::CXXParenListInitExprClass:
- K = CXCursor_CXXParenListInitExpr;
- break;
-
case Stmt::MSDependentExistsStmtClass:
K = CXCursor_UnexposedStmt;
break;
diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html
index c9df1ed37350b..ab4eabb542f5b 100755
--- a/clang/www/cxx_status.html
+++ b/clang/www/cxx_status.html
@@ -1156,7 +1156,7 @@ <h2 id="cxx20">C++20 implementation status</h2>
<tr>
<td rowspan="2">Parenthesized initialization of aggregates</td>
<td><a href="https://wg21.link/p0960r3">P0960R3</a></td>
- <td rowspan="2" class="unreleased" align="center">Clang 16</td>
+ <td rowspan="2" class="none" align="center">No</td>
</tr>
<tr> <!-- from Belfast -->
<td><a href="https://wg21.link/p1975r0">P1975R0</a></td>
More information about the cfe-commits
mailing list