[clang] [Clang] Correctly initialize placeholder fields from their initializers (PR #114196)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 5 13:04:17 PST 2024
https://github.com/cor3ntin updated https://github.com/llvm/llvm-project/pull/114196
>From e96815e2aa85188e49bbaa20be1d196308a41354 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Tue, 5 Nov 2024 16:02:20 -0500
Subject: [PATCH] [SystemZ][XRay] Enable XRay for SystemZ in clang (#113254)
With the support for xray for SystemZ in place, the option can now be
enabled in clang.
---
clang/docs/ReleaseNotes.rst | 1 +
clang/include/clang/AST/ASTContext.h | 2 +-
clang/lib/AST/ASTContext.cpp | 9 +++--
clang/lib/Driver/XRayArgs.cpp | 1 +
clang/lib/Sema/SemaExpr.cpp | 29 ++++++++++-----
.../lib/Sema/SemaTemplateInstantiateDecl.cpp | 2 +-
clang/lib/Serialization/ASTReaderDecl.cpp | 3 +-
clang/lib/Serialization/ASTWriterDecl.cpp | 2 +-
clang/test/Driver/XRay/xray-mode-flags.cpp | 2 ++
clang/test/SemaCXX/cxx2c-placeholder-vars.cpp | 36 ++++++++++++++++++-
10 files changed, 70 insertions(+), 17 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b2231bb4584aae..6304a6c3260fdb 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -591,6 +591,7 @@ Bug Fixes to C++ Support
- Clang now correctly ignores previous partial specializations of member templates explicitly specialized for
an implicitly instantiated class template specialization. (#GH51051)
- Fixed an assertion failure caused by invalid enum forward declarations. (#GH112208)
+- Name independent data members were not correctly initialized from default member initializers. (#GH114069)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 1e8101f60b03fb..dfd5bd8add01a3 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1041,7 +1041,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
void setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst,
UsingShadowDecl *Pattern);
- FieldDecl *getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field);
+ FieldDecl *getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field) const;
void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl);
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 91a7d4bb5a89dd..68ddbc5d09dc59 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1592,14 +1592,17 @@ ASTContext::setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst,
InstantiatedFromUsingShadowDecl[Inst] = Pattern;
}
-FieldDecl *ASTContext::getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field) {
+FieldDecl *
+ASTContext::getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field) const {
return InstantiatedFromUnnamedFieldDecl.lookup(Field);
}
void ASTContext::setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst,
FieldDecl *Tmpl) {
- assert(!Inst->getDeclName() && "Instantiated field decl is not unnamed");
- assert(!Tmpl->getDeclName() && "Template field decl is not unnamed");
+ assert((!Inst->getDeclName() || Inst->isPlaceholderVar(getLangOpts())) &&
+ "Instantiated field decl is not unnamed");
+ assert((!Inst->getDeclName() || Inst->isPlaceholderVar(getLangOpts())) &&
+ "Template field decl is not unnamed");
assert(!InstantiatedFromUnnamedFieldDecl[Inst] &&
"Already noted what unnamed field was instantiated from");
diff --git a/clang/lib/Driver/XRayArgs.cpp b/clang/lib/Driver/XRayArgs.cpp
index d0bb5d4887c184..1cf31d10530a59 100644
--- a/clang/lib/Driver/XRayArgs.cpp
+++ b/clang/lib/Driver/XRayArgs.cpp
@@ -53,6 +53,7 @@ XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) {
case llvm::Triple::mipsel:
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
+ case llvm::Triple::systemz:
break;
default:
D.Diag(diag::err_drv_unsupported_opt_for_target)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 7f3cff1054aeed..49fdb5b5ab43da 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -5560,6 +5560,24 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
Init, InitializationContext->Context);
}
+static FieldDecl *FindFieldDeclInstantiationPattern(const ASTContext &Ctx,
+ FieldDecl *Field) {
+ if (FieldDecl *Pattern = Ctx.getInstantiatedFromUnnamedFieldDecl(Field))
+ return Pattern;
+ auto *ParentRD = cast<CXXRecordDecl>(Field->getParent());
+ CXXRecordDecl *ClassPattern = ParentRD->getTemplateInstantiationPattern();
+ DeclContext::lookup_result Lookup =
+ ClassPattern->lookup(Field->getDeclName());
+ auto Rng = llvm::make_filter_range(
+ Lookup, [](auto &&L) { return isa<FieldDecl>(*L); });
+ if (Rng.empty())
+ return nullptr;
+ // FIXME: this breaks clang/test/Modules/pr28812.cpp
+ // assert(std::distance(Rng.begin(), Rng.end()) <= 1
+ // && "Duplicated instantiation pattern for field decl");
+ return cast<FieldDecl>(*Rng.begin());
+}
+
ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) {
assert(Field->hasInClassInitializer());
@@ -5588,15 +5606,8 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) {
// Maybe we haven't instantiated the in-class initializer. Go check the
// pattern FieldDecl to see if it has one.
if (isTemplateInstantiation(ParentRD->getTemplateSpecializationKind())) {
- CXXRecordDecl *ClassPattern = ParentRD->getTemplateInstantiationPattern();
- DeclContext::lookup_result Lookup =
- ClassPattern->lookup(Field->getDeclName());
-
- FieldDecl *Pattern = nullptr;
- for (auto *L : Lookup) {
- if ((Pattern = dyn_cast<FieldDecl>(L)))
- break;
- }
+ FieldDecl *Pattern =
+ FindFieldDeclInstantiationPattern(getASTContext(), Field);
assert(Pattern && "We must have set the Pattern!");
if (!Pattern->hasInClassInitializer() ||
InstantiateInClassInitializer(Loc, Field, Pattern,
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index ec3c3ce6057264..1f4b0570708456 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1352,7 +1352,7 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
if (Invalid)
Field->setInvalidDecl();
- if (!Field->getDeclName()) {
+ if (!Field->getDeclName() || Field->isPlaceholderVar(SemaRef.getLangOpts())) {
// Keep track of where this decl came from.
SemaRef.Context.setInstantiatedFromUnnamedFieldDecl(Field, D);
}
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 20edd53598e5bd..98a2070eda726b 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -1547,7 +1547,8 @@ void ASTDeclReader::VisitFieldDecl(FieldDecl *FD) {
else if (Bits & 1)
FD->setBitWidth(Record.readExpr());
- if (!FD->getDeclName()) {
+ if (!FD->getDeclName() ||
+ FD->isPlaceholderVar(Reader.getContext().getLangOpts())) {
if (auto *Tmpl = readDeclAs<FieldDecl>())
Reader.getContext().setInstantiatedFromUnnamedFieldDecl(FD, Tmpl);
}
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index b5fe16bf6e787b..14db0c082c937f 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -1038,7 +1038,7 @@ void ASTDeclWriter::VisitFieldDecl(FieldDecl *D) {
else if (D->BitField)
Record.AddStmt(D->getBitWidth());
- if (!D->getDeclName())
+ if (!D->getDeclName() || D->isPlaceholderVar(Writer.getLangOpts()))
Record.AddDeclRef(Context.getInstantiatedFromUnnamedFieldDecl(D));
if (D->getDeclContext() == D->getLexicalDeclContext() &&
diff --git a/clang/test/Driver/XRay/xray-mode-flags.cpp b/clang/test/Driver/XRay/xray-mode-flags.cpp
index cfcf42f30e6271..d5f5ad248e2a15 100644
--- a/clang/test/Driver/XRay/xray-mode-flags.cpp
+++ b/clang/test/Driver/XRay/xray-mode-flags.cpp
@@ -4,6 +4,8 @@
// RUN: | FileCheck --check-prefix=BASIC %s
// RUN: %clang -### --target=aarch64-linux-gnu -fxray-instrument %s 2>&1 \
// RUN: | FileCheck --check-prefixes=FDR,BASIC %s
+// RUN: %clang -### --target=s390x-linux-gnu -fxray-instrument -fxray-modes=xray-basic %s 2>&1 \
+// RUN: | FileCheck --check-prefix=BASIC %s
// RUN: %clang -### --target=x86_64-linux-gnu -fxray-instrument -fxray-modes=all %s 2>&1 \
// RUN: | FileCheck --check-prefixes=FDR,BASIC %s
// RUN: %clang -### --target=x86_64-linux-gnu -fxray-instrument -fxray-modes=xray-fdr,xray-basic %s 2>&1 \
diff --git a/clang/test/SemaCXX/cxx2c-placeholder-vars.cpp b/clang/test/SemaCXX/cxx2c-placeholder-vars.cpp
index 29ca3b5ef3df72..8e428c0ef04279 100644
--- a/clang/test/SemaCXX/cxx2c-placeholder-vars.cpp
+++ b/clang/test/SemaCXX/cxx2c-placeholder-vars.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang -cc1 -fsyntax-only -verify -std=c++2c -Wunused-parameter -Wunused -Wpre-c++26-compat %s
+// RUN: %clang_cc1 -fsyntax-only -verify -ast-dump -std=c++2c -Wunused-parameter -Wunused -Wpre-c++26-compat %s | FileCheck %s
void static_var() {
static int _; // expected-note {{previous definition is here}} \
@@ -254,3 +254,37 @@ namespace Bases {
}
};
}
+
+namespace GH114069 {
+
+template <class T>
+struct A {
+ T _ = 1;
+ T _ = 2;
+ T : 1;
+ T a = 3;
+ T _ = 4;
+};
+
+void f() {
+ [[maybe_unused]] A<int> a;
+}
+
+// CHECK: NamespaceDecl {{.*}} GH114069
+// CHECK: ClassTemplateSpecializationDecl {{.*}} struct A definition
+// CHECK: CXXConstructorDecl {{.*}} implicit used constexpr A 'void () noexcept'
+// CHECK-NEXT: CXXCtorInitializer Field {{.*}} '_' 'int'
+// CHECK-NEXT: CXXDefaultInitExpr {{.*}} 'int' has rewritten init
+// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1
+// CHECK-NEXT: CXXCtorInitializer Field {{.*}} '_' 'int'
+// CHECK-NEXT: CXXDefaultInitExpr {{.*}} 'int' has rewritten init
+// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 2
+// CHECK-NEXT: CXXCtorInitializer Field {{.*}} 'a' 'int'
+// CHECK-NEXT: CXXDefaultInitExpr {{.*}} 'int' has rewritten init
+// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 3
+// CHECK-NEXT: CXXCtorInitializer Field {{.*}} '_' 'int'
+// CHECK-NEXT: CXXDefaultInitExpr {{.*}} 'int' has rewritten init
+// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 4
+// CHECK-NEXT: CompoundStmt {{.*}}
+
+}
More information about the cfe-commits
mailing list