Author: Douglas Deslauriers Date: 2024-03-05T15:07:54+01:00 New Revision: 4ce737bfd6fd0aafb436eb220c3e724bfc831db4
URL: https://github.com/llvm/llvm-project/commit/4ce737bfd6fd0aafb436eb220c3e724bfc831db4 DIFF: https://github.com/llvm/llvm-project/commit/4ce737bfd6fd0aafb436eb220c3e724bfc831db4.diff LOG: [clang] Sequence C++20 Parenthesized List Init (#83476) Parenthesized list intializers are sequenced operations, see C++20 [decl.init]p16.5 and [decl.init]p16.6.2.2 for more details. Fixes #83474 Added: clang/test/SemaCXX/warn-unsequenced-paren-list-init.cpp Modified: clang/lib/Sema/SemaChecking.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 0d4d57db01c93a..2cda1d08784ece 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -17624,20 +17624,8 @@ class SequenceChecker : public ConstEvaluatedExprVisitor<SequenceChecker> { return VisitExpr(CCE); // In C++11, list initializations are sequenced. - SmallVector<SequenceTree::Seq, 32> Elts; - SequenceTree::Seq Parent = Region; - for (CXXConstructExpr::const_arg_iterator I = CCE->arg_begin(), - E = CCE->arg_end(); - I != E; ++I) { - Region = Tree.allocate(Parent); - Elts.push_back(Region); - Visit(*I); - } - - // Forget that the initializers are sequenced. - Region = Parent; - for (unsigned I = 0; I < Elts.size(); ++I) - Tree.merge(Elts[I]); + SequenceExpressionsInOrder( + llvm::ArrayRef(CCE->getArgs(), CCE->getNumArgs())); } void VisitInitListExpr(const InitListExpr *ILE) { @@ -17645,10 +17633,20 @@ class SequenceChecker : public ConstEvaluatedExprVisitor<SequenceChecker> { return VisitExpr(ILE); // In C++11, list initializations are sequenced. + SequenceExpressionsInOrder(ILE->inits()); + } + + void VisitCXXParenListInitExpr(const CXXParenListInitExpr *PLIE) { + // C++20 parenthesized list initializations are sequenced. See C++20 + // [decl.init.general]p16.5 and [decl.init.general]p16.6.2.2. + SequenceExpressionsInOrder(PLIE->getInitExprs()); + } + +private: + void SequenceExpressionsInOrder(ArrayRef<const Expr *> ExpressionList) { SmallVector<SequenceTree::Seq, 32> Elts; SequenceTree::Seq Parent = Region; - for (unsigned I = 0; I < ILE->getNumInits(); ++I) { - const Expr *E = ILE->getInit(I); + for (const Expr *E : ExpressionList) { if (!E) continue; Region = Tree.allocate(Parent); diff --git a/clang/test/SemaCXX/warn-unsequenced-paren-list-init.cpp b/clang/test/SemaCXX/warn-unsequenced-paren-list-init.cpp new file mode 100644 index 00000000000000..5aeeb45f81e226 --- /dev/null +++ b/clang/test/SemaCXX/warn-unsequenced-paren-list-init.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++20 -Wno-unused -Wunsequenced -verify %s + +struct A { + int x, y; +}; + +void test() { + int a = 0; + + A agg1( a++, a++ ); // no warning + A agg2( a++ + a, a++ ); // expected-warning {{unsequenced modification and access to 'a'}} + + int arr1[]( a++, a++ ); // no warning + int arr2[]( a++ + a, a++ ); // expected-warning {{unsequenced modification and access to 'a'}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits