https://github.com/rnk created https://github.com/llvm/llvm-project/pull/80519
This code was correct as written prior to C++17, which allowed bases to appear in the initializer list. Clang currently requires compound literal initializers at file scope to be constants, which is how I tested this behavior change, but I am open to other testing ideas. This fixes at least one part of issue #80510 . >From 6ab5ba3f970eaaea542fbed09cae17d3666df6b3 Mon Sep 17 00:00:00 2001 From: Reid Kleckner <r...@google.com> Date: Sat, 3 Feb 2024 00:18:42 +0000 Subject: [PATCH] wip --- clang/lib/AST/Expr.cpp | 12 ++++++++++++ clang/test/SemaCXX/compound-literal.cpp | 20 ++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index d665a08deb47e..8852fadf79b9a 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -3342,6 +3342,18 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef, if (ILE->getType()->isRecordType()) { unsigned ElementNo = 0; RecordDecl *RD = ILE->getType()->castAs<RecordType>()->getDecl(); + + // Check bases for C++17 aggregate initializers. + if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { + for (unsigned i = 0, e = CXXRD->getNumBases(); i < e; i++) { + if (ElementNo < ILE->getNumInits()) { + const Expr *Elt = ILE->getInit(ElementNo++); + if (!Elt->isConstantInitializer(Ctx, false, Culprit)) + return false; + } + } + } + for (const auto *Field : RD->fields()) { // If this is a union, skip all the fields that aren't being initialized. if (RD->isUnion() && ILE->getInitializedFieldInUnion() != Field) diff --git a/clang/test/SemaCXX/compound-literal.cpp b/clang/test/SemaCXX/compound-literal.cpp index 5957099de53af..81f8b41ff0313 100644 --- a/clang/test/SemaCXX/compound-literal.cpp +++ b/clang/test/SemaCXX/compound-literal.cpp @@ -3,6 +3,7 @@ // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify -ast-dump %s > %t-11 // RUN: FileCheck --input-file=%t-11 %s // RUN: FileCheck --input-file=%t-11 %s --check-prefix=CHECK-CXX11 +// RUN: %clang_cc1 -verify -std=c++17 %s // http://llvm.org/PR7905 namespace PR7905 { @@ -108,3 +109,22 @@ int computed_with_lambda = [] { return result; }(); #endif + +#if __cplusplus >= 201703L +namespace DynamicFileScopeLiteral { +// This covers the case where we have a file-scope compound literal with a +// non-constant initializer in C++. Previously, we had a bug where Clang forgot +// to consider initializer list elements for bases. +struct Empty {}; +struct Foo : Empty { + int x; + int y; +}; +int f(); +Foo o = (Foo){ + {}, + 1, + f() // expected-error {{initializer element is not a compile-time constant}} +}; +} +#endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits