[clang] [Clang] Correct the DeclRefExpr's Type after the initializer gets instantiated (PR #133212)
Younan Zhang via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 27 02:10:01 PDT 2025
https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/133212
>From 34632d01840af89745dc79d27e06bd86aeb04c84 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Thu, 27 Mar 2025 13:58:36 +0800
Subject: [PATCH 1/3] [Clang] Correct the DeclRefExpr's Type after the
initializer gets instantiated
The instantiation of a VarDecl's initializer might be deferred until
the variable is actually used. However, we were still building the
DeclRefExpr with a type that could later be changed by the
initializer's instantiation, which is incorrect when incomplete
arrays are involved.
---
clang/docs/ReleaseNotes.rst | 1 +
clang/lib/Sema/SemaExpr.cpp | 11 +++++---
.../cxx1y-variable-templates_top_level.cpp | 26 +++++++++++++++++++
3 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8182bccdd2da8..6749369c91559 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -355,6 +355,7 @@ Bug Fixes to C++ Support
- Correctly diagnoses if unresolved using declarations shadows template paramters (#GH129411)
- Clang was previously coalescing volatile writes to members of volatile base class subobjects.
The issue has been addressed by propagating qualifiers during derived-to-base conversions in the AST. (#GH127824)
+- Correctly propagates the instantiated array type to the ``DeclRefExpr`` that refers to it. (#GH79750), (#GH113936), (#GH133047)
- Fixed a Clang regression in C++20 mode where unresolved dependent call expressions were created inside non-dependent contexts (#GH122892)
- Clang now emits the ``-Wunused-variable`` warning when some structured bindings are unused
and the ``[[maybe_unused]]`` attribute is not applied. (#GH125810)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 3af6d6c23438f..f837b047ddfb4 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -19849,11 +19849,14 @@ static void DoMarkVarDeclReferenced(
SemaRef.InstantiateVariableDefinition(PointOfInstantiation, Var);
});
- // Re-set the member to trigger a recomputation of the dependence bits
- // for the expression.
- if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E))
+ if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
+ // Re-set the member to trigger a recomputation of the dependence bits
+ // for the expression.
DRE->setDecl(DRE->getDecl());
- else if (auto *ME = dyn_cast_or_null<MemberExpr>(E))
+ if (SemaRef.Context.getAsIncompleteArrayType(DRE->getType()) &&
+ !SemaRef.Context.getAsIncompleteArrayType(Var->getType()))
+ DRE->setType(Var->getType());
+ } else if (auto *ME = dyn_cast_or_null<MemberExpr>(E))
ME->setMemberDecl(ME->getMemberDecl());
} else if (FirstInstantiation) {
SemaRef.PendingInstantiations
diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp b/clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
index da1678ec68627..6fc2032ee7fb4 100644
--- a/clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
+++ b/clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
@@ -467,3 +467,29 @@ namespace VexingParse {
template <typename> int var; // expected-note {{declared here}}
int x(var); // expected-error {{use of variable template 'var' requires template arguments}}
}
+
+#ifndef PRECXX11
+
+namespace GH79750 {
+
+enum class Values { A };
+
+template<typename E>
+constexpr Values values[] = {E::A};
+
+constexpr auto r = values<Values>[0] == Values::A;
+
+}
+
+namespace GH113956 {
+
+template <class T, T... VALUES>
+struct C {
+ static constexpr T VALUEARRAY[] = {VALUES...};
+};
+
+static_assert(C<int, 0,1,2,3,4>::VALUEARRAY[3] == 3, "");
+static_assert(C<int, 0,1,2,3,4>::VALUEARRAY[0] == 0, "");
+
+}
+#endif
>From 04e350f0a1d854345251f49dcaca5c9eaa9fe60a Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Thu, 27 Mar 2025 16:18:56 +0800
Subject: [PATCH 2/3] Add comment
---
clang/lib/Sema/SemaExpr.cpp | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index f837b047ddfb4..0e21dfb1fcc43 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -19853,6 +19853,12 @@ static void DoMarkVarDeclReferenced(
// Re-set the member to trigger a recomputation of the dependence bits
// for the expression.
DRE->setDecl(DRE->getDecl());
+ // The size of an incomplete array type can be updated by
+ // instantiating the initializer. The DeclRefExpr's type should be
+ // updated accordingly too, or users of it would be confused!
+ //
+ // FIXME: Do we need to recompute the type for all the Decls, as in
+ // BuildDeclarationNameExpr?
if (SemaRef.Context.getAsIncompleteArrayType(DRE->getType()) &&
!SemaRef.Context.getAsIncompleteArrayType(Var->getType()))
DRE->setType(Var->getType());
>From 29bc3d3df81b166f68efe23c0c93134e366fc9ec Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Thu, 27 Mar 2025 17:09:41 +0800
Subject: [PATCH 3/3] fixup! [Clang] Correct the DeclRefExpr's Type after the
initializer gets instantiated
---
clang/lib/Sema/SemaExpr.cpp | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 0e21dfb1fcc43..7ea691efeecdb 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -19856,12 +19856,7 @@ static void DoMarkVarDeclReferenced(
// The size of an incomplete array type can be updated by
// instantiating the initializer. The DeclRefExpr's type should be
// updated accordingly too, or users of it would be confused!
- //
- // FIXME: Do we need to recompute the type for all the Decls, as in
- // BuildDeclarationNameExpr?
- if (SemaRef.Context.getAsIncompleteArrayType(DRE->getType()) &&
- !SemaRef.Context.getAsIncompleteArrayType(Var->getType()))
- DRE->setType(Var->getType());
+ SemaRef.getCompletedType(DRE);
} else if (auto *ME = dyn_cast_or_null<MemberExpr>(E))
ME->setMemberDecl(ME->getMemberDecl());
} else if (FirstInstantiation) {
More information about the cfe-commits
mailing list