Skip to content

Commit a967251

Browse files
authored
[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
1 parent 1a14082 commit a967251

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ Bug Fixes to C++ Support
359359
- Fixed C++20 aggregate initialization rules being incorrectly applied in certain contexts. (#GH131320)
360360
- Clang was previously coalescing volatile writes to members of volatile base class subobjects.
361361
The issue has been addressed by propagating qualifiers during derived-to-base conversions in the AST. (#GH127824)
362+
- Correctly propagates the instantiated array type to the ``DeclRefExpr`` that refers to it. (#GH79750), (#GH113936), (#GH133047)
362363
- Fixed a Clang regression in C++20 mode where unresolved dependent call expressions were created inside non-dependent contexts (#GH122892)
363364
- Clang now emits the ``-Wunused-variable`` warning when some structured bindings are unused
364365
and the ``[[maybe_unused]]`` attribute is not applied. (#GH125810)

clang/lib/Sema/SemaExpr.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19849,6 +19849,12 @@ static void DoMarkVarDeclReferenced(
1984919849
SemaRef.InstantiateVariableDefinition(PointOfInstantiation, Var);
1985019850
});
1985119851

19852+
// The size of an incomplete array type can be updated by
19853+
// instantiating the initializer. The DeclRefExpr's type should be
19854+
// updated accordingly too, or users of it would be confused!
19855+
if (E)
19856+
SemaRef.getCompletedType(E);
19857+
1985219858
// Re-set the member to trigger a recomputation of the dependence bits
1985319859
// for the expression.
1985419860
if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E))

clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,3 +467,29 @@ namespace VexingParse {
467467
template <typename> int var; // expected-note {{declared here}}
468468
int x(var); // expected-error {{use of variable template 'var' requires template arguments}}
469469
}
470+
471+
#ifndef PRECXX11
472+
473+
namespace GH79750 {
474+
475+
enum class Values { A };
476+
477+
template<typename E>
478+
constexpr Values values[] = {E::A};
479+
480+
constexpr auto r = values<Values>[0] == Values::A;
481+
482+
}
483+
484+
namespace GH113956 {
485+
486+
template <class T, T... VALUES>
487+
struct C {
488+
static constexpr T VALUEARRAY[] = {VALUES...};
489+
};
490+
491+
static_assert(C<int, 0,1,2,3,4>::VALUEARRAY[3] == 3, "");
492+
static_assert(C<int, 0,1,2,3,4>::VALUEARRAY[0] == 0, "");
493+
494+
}
495+
#endif

0 commit comments

Comments
 (0)