https://github.com/yronglin updated 
https://github.com/llvm/llvm-project/pull/219952

>From dac444c62ab46acea74331b31a1fdc4e1756959f Mon Sep 17 00:00:00 2001
From: yronglin <[email protected]>
Date: Mon, 31 Aug 2026 04:41:14 -0700
Subject: [PATCH 1/2] [clang][bytecode] Give a discarded composite prvalue a
 result object

Signed-off-by: yronglin <[email protected]>
---
 clang/lib/AST/ByteCode/Compiler.cpp | 62 ++++++++++++++++++++++++++++-
 clang/lib/AST/ByteCode/Compiler.h   |  6 +++
 clang/test/AST/ByteCode/records.cpp | 29 +++++++++++++-
 3 files changed, 93 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index c182639ea07f8..cf4945a3f2ff6 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -50,6 +50,22 @@ static bool isSideEffectFree(const Expr *E) {
   return false;
 }
 
+static bool containsDefaultInitExpr(const Expr *E) {
+  class Finder final : public ConstDynamicRecursiveASTVisitor {
+  public:
+    Finder() { ShouldVisitImplicitCode = true; }
+
+    bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *) override {
+      Found = true;
+      return true;
+    }
+
+    bool Found = false;
+  } F;
+  F.TraverseStmt(E);
+  return F.Found;
+}
+
 /// Scope chain managing the variable lifetimes.
 template <class Emitter> class VariableScope {
 public:
@@ -265,7 +281,9 @@ template <class Emitter> class InitStackScope final {
 public:
   InitStackScope(Compiler<Emitter> *Ctx, bool Active)
       : Ctx(Ctx), OldValue(Ctx->InitStackActive), Active(Active) {
-    Ctx->InitStackActive = Active;
+    // An explicit initializer nested in a default member initializer still
+    // needs the surrounding default initializer's `this` reconstruction.
+    Ctx->InitStackActive = OldValue || Active;
     if (Active)
       Ctx->InitStack.push_back(InitLink::DIE());
   }
@@ -3475,6 +3493,9 @@ bool Compiler<Emitter>::VisitExprWithCleanups(const 
ExprWithCleanups *E) {
   LocalScope<Emitter> ES(this, ScopeKind::FullExpression);
   const Expr *SubExpr = E->getSubExpr();
 
+  if (DiscardResult && this->discardNeedsResultObject(SubExpr))
+    return this->discardIntoResultObject(SubExpr) && ES.destroyLocals(E);
+
   return this->delegate(SubExpr) && ES.destroyLocals(E);
 }
 
@@ -3541,8 +3562,12 @@ bool Compiler<Emitter>::VisitMaterializeTemporaryExpr(
     // Non-primitive values.
     if (!this->emitGetPtrGlobal(*GlobalIndex, E))
       return false;
+    if (!this->emitStartInit(E))
+      return false;
     if (!this->visitInitializer(Inner))
       return false;
+    if (!this->emitEndInit(E))
+      return false;
     if (IsStatic) {
       assert(TempDecl);
       return this->emitInitGlobalTempComp(TempDecl, E);
@@ -3585,7 +3610,11 @@ bool Compiler<Emitter>::VisitMaterializeTemporaryExpr(
 
     if (!this->emitGetPtrLocal(*LocalIndex, E))
       return false;
-    return this->visitInitializer(Inner);
+    if (!this->emitStartInit(E))
+      return false;
+    if (!this->visitInitializer(Inner))
+      return false;
+    return this->emitEndInit(E);
   }
   return false;
 }
@@ -4887,7 +4916,30 @@ bool Compiler<Emitter>::VisitStmtExpr(const StmtExpr *E) 
{
   return BS.destroyLocals();
 }
 
+template <class Emitter>
+bool Compiler<Emitter>::discardNeedsResultObject(const Expr *E) const {
+  return !E->isGLValue() && !canClassify(E->getType()) &&
+         containsDefaultInitExpr(E);
+}
+
+template <class Emitter>
+bool Compiler<Emitter>::discardIntoResultObject(const Expr *E) {
+  UnsignedOrNone LocalIndex =
+      allocateLocal(E, QualType(), ScopeKind::FullExpression);
+  if (!LocalIndex)
+    return false;
+  InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalIndex));
+  if (!this->emitGetPtrLocal(*LocalIndex, E))
+    return false;
+  return this->visitInitializerPop(E);
+}
+
 template <class Emitter> bool Compiler<Emitter>::discard(const Expr *E) {
+  // Let an ExprWithCleanups establish its full-expression scope first; it
+  // allocates the result object itself.
+  if (!isa<ExprWithCleanups>(E) && this->discardNeedsResultObject(E))
+    return this->discardIntoResultObject(E);
+
   OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true,
                              /*NewInitializing=*/false, /*ToLValue=*/false);
   return this->Visit(E);
@@ -5451,8 +5503,14 @@ bool Compiler<Emitter>::visitExpr(const Expr *E, bool 
DestroyToplevelScope) {
     if (!this->emitGetPtrLocal(*LocalOffset, E))
       return false;
 
+    // A const-qualified result object is writable while it is being
+    // initialized, just like an object evaluated through visitVarDecl().
+    if (!this->emitStartInit(E))
+      return false;
     if (!visitInitializer(E))
       return false;
+    if (!this->emitEndInit(E))
+      return false;
     // We are destroying the locals AFTER the Ret op.
     // The Ret op needs to copy the (alive) values, but the
     // destructors may still turn the entire expression invalid.
diff --git a/clang/lib/AST/ByteCode/Compiler.h 
b/clang/lib/AST/ByteCode/Compiler.h
index f34809cd0f14c..6e22f57749e43 100644
--- a/clang/lib/AST/ByteCode/Compiler.h
+++ b/clang/lib/AST/ByteCode/Compiler.h
@@ -321,6 +321,12 @@ class Compiler : public 
ConstStmtVisitor<Compiler<Emitter>, bool>,
   bool visitAsLValue(const Expr *E);
   /// Evaluates an expression for side effects and discards the result.
   bool discard(const Expr *E);
+  /// Whether discarding \p E still requires a result object: a composite
+  /// prvalue whose default member initializer may refer to previously
+  /// initialized subobjects, so that `this` has something to denote.
+  bool discardNeedsResultObject(const Expr *E) const;
+  /// Allocate that result object and initialize \p E into it.
+  bool discardIntoResultObject(const Expr *E);
   /// Just pass evaluation on to \p E. This leaves all the parsing flags
   /// intact.
   bool delegate(const Expr *E);
diff --git a/clang/test/AST/ByteCode/records.cpp 
b/clang/test/AST/ByteCode/records.cpp
index 36b5cb62fe95f..e522072802308 100644
--- a/clang/test/AST/ByteCode/records.cpp
+++ b/clang/test/AST/ByteCode/records.cpp
@@ -1302,11 +1302,36 @@ namespace {
   };
   constexpr int a() {
     int x = 1;
-    int f = B{x}.x;
+    {
+      B b{x};
+    }
+    return x;
+  }
+  static_assert(a() == 0);
+
+  constexpr int discarded() {
+    int x = 1;
     B{x}; // both-warning {{expression result unused}}
+    return x;
+  }
 
-    return 1;
+  /// Before the result object was allocated, this could not be evaluated at
+  /// all. The temporary 'B' is not destroyed until the end of the enclosing
+  /// full-expression, so 'x' still reads 1 here, matching legacy evaluator.
+  ///
+  /// FIXME: See https://github.com/llvm/llvm-project/issues/85601.
+  static_assert(discarded() == 1);
+
+  /// A const-qualified composite result is writable while under construction.
+  constexpr int decrement(int &x) {
+    return --x;
   }
+  struct DMIConstComposite {
+    int a;
+    int b = decrement(a);
+  };
+  constexpr DMIConstComposite c{1};
+  static_assert(c.a == 0);
 }
 #endif
 

>From abd057526afcd71378113032c5984736c864c8a3 Mon Sep 17 00:00:00 2001
From: yronglin <[email protected]>
Date: Mon, 31 Aug 2026 06:09:34 -0700
Subject: [PATCH 2/2] [clang] Add a flag to init-list node to specifiy whether
 it's initializes an object weith default-mem-init

Signed-off-by: yronglin <[email protected]>
---
 clang/include/clang/AST/Expr.h            | 24 ++++++++++
 clang/include/clang/AST/ExprCXX.h         |  8 ++++
 clang/include/clang/AST/Stmt.h            |  5 ++
 clang/lib/AST/ByteCode/Compiler.cpp       | 57 ++++++-----------------
 clang/lib/AST/ByteCode/Compiler.h         |  6 ---
 clang/lib/AST/Expr.cpp                    |  9 ++++
 clang/lib/Sema/SemaInit.cpp               |  7 +++
 clang/lib/Serialization/ASTReaderStmt.cpp |  3 ++
 clang/lib/Serialization/ASTWriterStmt.cpp |  2 +
 9 files changed, 73 insertions(+), 48 deletions(-)

diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 535086a6c2aa3..2699a08d6ef18 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -479,6 +479,24 @@ class Expr : public ValueStmt {
   /// an aspect of the value-kind type system.
   bool refersToBitField() const { return getObjectKind() == OK_BitField; }
 
+  /// Whether this is a list-initialization (an \c InitListExpr or a
+  /// \c CXXParenListInitExpr) that initializes an object using a default
+  /// member initializer, that is, one of whose initializers is a
+  /// \c CXXDefaultInitExpr.
+  ///
+  /// Within such an initializer, \c this denotes the object that this
+  /// list-initialization initializes, not the instance pointer of the
+  /// enclosing member function:
+  ///
+  /// \code
+  ///   struct S { int x; int y = this->x; };
+  ///   int foo() { return S{10}.y; }  // `this` denotes the `S{10}` object
+  /// \endcode
+  ///
+  /// Sema sets this when it fills the list in, so that consumers do not each
+  /// have to re-derive which list-initializations establish such an object.
+  bool initializesObjectWithDefaultMemberInit() const;
+
   /// If this expression refers to a bit-field, retrieve the
   /// declaration of that bit-field.
   ///
@@ -5380,6 +5398,7 @@ class InitListExpr : public Expr {
   explicit InitListExpr(EmptyShell Empty)
       : Expr(InitListExprClass, Empty), AltForm(nullptr, true) {
     InitListExprBits.IsExplicit = false;
+    InitListExprBits.InitializesObjectWithDefaultMemberInit = false;
   }
 
   unsigned getNumInits() const { return InitExprs.size(); }
@@ -5494,6 +5513,11 @@ class InitListExpr : public Expr {
   // locations). Implicit InitListExpr's are created by the semantic analyzer.
   bool isExplicit() const { return InitListExprBits.IsExplicit; }
 
+  /// See Expr::initializesObjectWithDefaultMemberInit().
+  void setInitializesObjectWithDefaultMemberInit(bool V = true) {
+    InitListExprBits.InitializesObjectWithDefaultMemberInit = V;
+  }
+
   /// Is this an initializer for an array of characters, initialized by a 
string
   /// literal or an @encode?
   bool isStringLiteralInit() const;
diff --git a/clang/include/clang/AST/ExprCXX.h 
b/clang/include/clang/AST/ExprCXX.h
index bb790b1100e7f..9e6956a9d703d 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -5193,9 +5193,12 @@ class CXXParenListInitExpr final
   friend class TrailingObjects;
   friend class ASTStmtReader;
   friend class ASTStmtWriter;
+  friend class Expr;
 
   unsigned NumExprs;
   unsigned NumUserSpecifiedExprs;
+  /// See Expr::initializesObjectWithDefaultMemberInit().
+  bool InitializesObjectWithDefaultMemberInit = false;
   SourceLocation InitLoc, LParenLoc, RParenLoc;
   llvm::PointerUnion<Expr *, FieldDecl *> ArrayFillerOrUnionFieldInit;
 
@@ -5229,6 +5232,11 @@ class CXXParenListInitExpr final
 
   void updateDependence() { setDependence(computeDependence(this)); }
 
+  /// See Expr::initializesObjectWithDefaultMemberInit().
+  void setInitializesObjectWithDefaultMemberInit(bool V = true) {
+    InitializesObjectWithDefaultMemberInit = V;
+  }
+
   MutableArrayRef<Expr *> getInitExprs() {
     return getTrailingObjects(NumExprs);
   }
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 5d27ded64082d..8f8ee9ec2350c 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -670,6 +670,7 @@ class alignas(void *) Stmt {
 
   class InitListExprBitfields {
     friend class ASTStmtReader;
+    friend class Expr;
     friend class InitListExpr;
 
     LLVM_PREFERRED_TYPE(ExprBitfields)
@@ -682,6 +683,10 @@ class alignas(void *) Stmt {
     // Whether this list is explicitly written in the source (with braces).
     LLVM_PREFERRED_TYPE(bool)
     unsigned IsExplicit : 1;
+    /// Whether this list initializes an object using a default member
+    /// initializer. See Expr::initializesObjectWithDefaultMemberInit().
+    LLVM_PREFERRED_TYPE(bool)
+    unsigned InitializesObjectWithDefaultMemberInit : 1;
   };
 
   class ParenListExprBitfields {
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index cf4945a3f2ff6..ab0b0ea590539 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -50,22 +50,6 @@ static bool isSideEffectFree(const Expr *E) {
   return false;
 }
 
-static bool containsDefaultInitExpr(const Expr *E) {
-  class Finder final : public ConstDynamicRecursiveASTVisitor {
-  public:
-    Finder() { ShouldVisitImplicitCode = true; }
-
-    bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *) override {
-      Found = true;
-      return true;
-    }
-
-    bool Found = false;
-  } F;
-  F.TraverseStmt(E);
-  return F.Found;
-}
-
 /// Scope chain managing the variable lifetimes.
 template <class Emitter> class VariableScope {
 public:
@@ -2328,6 +2312,21 @@ bool Compiler<Emitter>::visitInitList(ArrayRef<const 
Expr *> Inits,
 
   // Handle discarding first.
   if (DiscardResult) {
+    // A default member initializer may read subobjects initialized earlier in
+    // this same list, so `this` has to denote something and those subobjects
+    // have to actually be written. Materialize a result object and initialize
+    // into it instead of discarding each initializer on its own.
+    if (E->initializesObjectWithDefaultMemberInit()) {
+      UnsignedOrNone LocalIndex =
+          allocateLocal(E, QualType(), ScopeKind::FullExpression);
+      if (!LocalIndex)
+        return false;
+      InitLinkScope<Emitter> ResultScope(this, InitLink::Temp(*LocalIndex));
+      if (!this->emitGetPtrLocal(*LocalIndex, E))
+        return false;
+      return this->visitInitializerPop(E);
+    }
+
     for (const Expr *Init : Inits) {
       if (!this->discard(Init))
         return false;
@@ -3493,9 +3492,6 @@ bool Compiler<Emitter>::VisitExprWithCleanups(const 
ExprWithCleanups *E) {
   LocalScope<Emitter> ES(this, ScopeKind::FullExpression);
   const Expr *SubExpr = E->getSubExpr();
 
-  if (DiscardResult && this->discardNeedsResultObject(SubExpr))
-    return this->discardIntoResultObject(SubExpr) && ES.destroyLocals(E);
-
   return this->delegate(SubExpr) && ES.destroyLocals(E);
 }
 
@@ -4916,30 +4912,7 @@ bool Compiler<Emitter>::VisitStmtExpr(const StmtExpr *E) 
{
   return BS.destroyLocals();
 }
 
-template <class Emitter>
-bool Compiler<Emitter>::discardNeedsResultObject(const Expr *E) const {
-  return !E->isGLValue() && !canClassify(E->getType()) &&
-         containsDefaultInitExpr(E);
-}
-
-template <class Emitter>
-bool Compiler<Emitter>::discardIntoResultObject(const Expr *E) {
-  UnsignedOrNone LocalIndex =
-      allocateLocal(E, QualType(), ScopeKind::FullExpression);
-  if (!LocalIndex)
-    return false;
-  InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalIndex));
-  if (!this->emitGetPtrLocal(*LocalIndex, E))
-    return false;
-  return this->visitInitializerPop(E);
-}
-
 template <class Emitter> bool Compiler<Emitter>::discard(const Expr *E) {
-  // Let an ExprWithCleanups establish its full-expression scope first; it
-  // allocates the result object itself.
-  if (!isa<ExprWithCleanups>(E) && this->discardNeedsResultObject(E))
-    return this->discardIntoResultObject(E);
-
   OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true,
                              /*NewInitializing=*/false, /*ToLValue=*/false);
   return this->Visit(E);
diff --git a/clang/lib/AST/ByteCode/Compiler.h 
b/clang/lib/AST/ByteCode/Compiler.h
index 6e22f57749e43..f34809cd0f14c 100644
--- a/clang/lib/AST/ByteCode/Compiler.h
+++ b/clang/lib/AST/ByteCode/Compiler.h
@@ -321,12 +321,6 @@ class Compiler : public 
ConstStmtVisitor<Compiler<Emitter>, bool>,
   bool visitAsLValue(const Expr *E);
   /// Evaluates an expression for side effects and discards the result.
   bool discard(const Expr *E);
-  /// Whether discarding \p E still requires a result object: a composite
-  /// prvalue whose default member initializer may refer to previously
-  /// initialized subobjects, so that `this` has something to denote.
-  bool discardNeedsResultObject(const Expr *E) const;
-  /// Allocate that result object and initialize \p E into it.
-  bool discardIntoResultObject(const Expr *E);
   /// Just pass evaluation on to \p E. This leaves all the parsing flags
   /// intact.
   bool delegate(const Expr *E);
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 6ce0a29aa3bd7..a1720596ea315 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -2443,6 +2443,7 @@ InitListExpr::InitListExpr(const ASTContext &C, 
SourceLocation lbraceloc,
   sawArrayRangeDesignator(false);
   InitExprs.insert(C, InitExprs.end(), initExprs.begin(), initExprs.end());
   InitListExprBits.IsExplicit = isExplicit;
+  InitListExprBits.InitializesObjectWithDefaultMemberInit = false;
 
   setDependence(computeDependence(this));
 }
@@ -2595,6 +2596,14 @@ static bool IsDecompositionDeclRefExpr(const Expr *E) {
   return isa_and_nonnull<DecompositionDecl>(Ref->getDecl());
 }
 
+bool Expr::initializesObjectWithDefaultMemberInit() const {
+  if (const auto *ILE = dyn_cast<InitListExpr>(this))
+    return ILE->InitListExprBits.InitializesObjectWithDefaultMemberInit;
+  if (const auto *PLIE = dyn_cast<CXXParenListInitExpr>(this))
+    return PLIE->InitializesObjectWithDefaultMemberInit;
+  return false;
+}
+
 bool Expr::isReadIfDiscardedInCPlusPlus11() const {
   // In C++11, discarded-value expressions of a certain form are special,
   // according to [expr]p10:
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 48ce51863c2c0..db52b77d9989a 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -835,6 +835,9 @@ void InitListChecker::FillInEmptyInitForField(unsigned 
Init, FieldDecl *Field,
         return;
       }
       SemaRef.checkInitializerLifetime(MemberEntity, DIE.get());
+      // Record that `this` within the default member initializer denotes the
+      // object this list initializes.
+      ILE->setInitializesObjectWithDefaultMemberInit();
       if (Init < NumInits)
         ILE->setInit(Init, DIE.get());
       else {
@@ -5967,6 +5970,7 @@ static void TryOrBuildParenListInitialization(
   QualType ResultType;
   Expr *ArrayFiller = nullptr;
   FieldDecl *InitializedFieldInUnion = nullptr;
+  bool UsesDefaultMemberInit = false;
 
   auto HandleInitializedEntity = [&](const InitializedEntity &SubEntity,
                                      const InitializationKind &SubKind,
@@ -6158,6 +6162,7 @@ static void TryOrBuildParenListInitialization(
               return;
             S.checkInitializerLifetime(SubEntity, DIE.get());
             InitExprs.push_back(DIE.get());
+            UsesDefaultMemberInit = true;
           }
         } else {
           // C++ [dcl.init]p17.6.2.2
@@ -6211,6 +6216,8 @@ static void TryOrBuildParenListInitialization(
       CPLIE->setArrayFiller(ArrayFiller);
     if (InitializedFieldInUnion)
       CPLIE->setInitializedFieldInUnion(InitializedFieldInUnion);
+    if (UsesDefaultMemberInit)
+      CPLIE->setInitializesObjectWithDefaultMemberInit();
     *Result = CPLIE;
     S.Diag(Kind.getLocation(),
            diag::warn_cxx17_compat_aggregate_init_paren_list)
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp 
b/clang/lib/Serialization/ASTReaderStmt.cpp
index 92c555dc427b3..a60de794596ee 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -1281,6 +1281,8 @@ void ASTStmtReader::VisitInitListExpr(InitListExpr *E) {
       E->updateInit(Record.getContext(), I, Record.readSubExpr());
   }
   E->InitListExprBits.IsExplicit = Record.readBool();
+  E->InitListExprBits.InitializesObjectWithDefaultMemberInit =
+      Record.readBool();
 }
 
 void ASTStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
@@ -2402,6 +2404,7 @@ void 
ASTStmtReader::VisitCXXParenListInitExpr(CXXParenListInitExpr *E) {
       E->setInitializedFieldInUnion(readDeclAs<FieldDecl>());
     }
   }
+  E->InitializesObjectWithDefaultMemberInit = Record.readBool();
   E->updateDependence();
 }
 
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp 
b/clang/lib/Serialization/ASTWriterStmt.cpp
index 513c832c38ffd..0d5bd86fb70d6 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -1289,6 +1289,7 @@ void ASTStmtWriter::VisitInitListExpr(InitListExpr *E) {
       Record.AddStmt(E->getInit(I));
   }
   Record.writeBool(E->isExplicit());
+  Record.writeBool(E->initializesObjectWithDefaultMemberInit());
   Code = serialization::EXPR_INIT_LIST;
 }
 
@@ -2474,6 +2475,7 @@ void 
ASTStmtWriter::VisitCXXParenListInitExpr(CXXParenListInitExpr *E) {
     else
       Record.AddDeclRef(UnionField);
   }
+  Record.writeBool(E->initializesObjectWithDefaultMemberInit());
   Code = serialization::EXPR_CXX_PAREN_LIST_INIT;
 }
 

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to