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 <zyn7...@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 <zyn7...@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 <zyn7...@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) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits