Author: Younan Zhang
Date: 2025-03-27T19:40:02+08:00
New Revision: a9672515ce6b8b1bc6976ed1225f4fb4d53fa381

URL: 
https://github.com/llvm/llvm-project/commit/a9672515ce6b8b1bc6976ed1225f4fb4d53fa381
DIFF: 
https://github.com/llvm/llvm-project/commit/a9672515ce6b8b1bc6976ed1225f4fb4d53fa381.diff

LOG: [Clang] Correct the DeclRefExpr's Type after the initializer gets 
instantiated (#133212)

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.

Fixes #79750
Fixes #113936
Fixes #133047

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaExpr.cpp
    clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 04ec2cfef679c..fb94c0c183033 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -359,6 +359,7 @@ Bug Fixes to C++ Support
 - Fixed C++20 aggregate initialization rules being incorrectly applied in 
certain contexts. (#GH131320)
 - 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..0ccc19437827c 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -19849,6 +19849,12 @@ static void DoMarkVarDeclReferenced(
           SemaRef.InstantiateVariableDefinition(PointOfInstantiation, Var);
         });
 
+        // 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!
+        if (E)
+          SemaRef.getCompletedType(E);
+
         // Re-set the member to trigger a recomputation of the dependence bits
         // for the expression.
         if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E))

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


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to