Skip to content

Commit

Permalink
[clang][Interp] Lazily visit const-qualified static data members in C++
Browse files Browse the repository at this point in the history
  • Loading branch information
tbaederr committed Mar 17, 2024
1 parent 192be3c commit a4b39f6
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 1 deletion.
3 changes: 2 additions & 1 deletion clang/lib/AST/Interp/ByteCodeExprGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3306,7 +3306,8 @@ bool ByteCodeExprGen<Emitter>::VisitDeclRefExpr(const DeclRefExpr *E) {
if (Ctx.getLangOpts().CPlusPlus) {
if (const auto *VD = dyn_cast<VarDecl>(D)) {
// Visit local const variables like normal.
if (VD->isLocalVarDecl() && VD->getType().isConstQualified()) {
if ((VD->isLocalVarDecl() || VD->isStaticDataMember()) &&
VD->getType().isConstQualified()) {
if (!this->visitVarDecl(VD))
return false;
// Retry.
Expand Down
20 changes: 20 additions & 0 deletions clang/test/AST/Interp/records.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1244,3 +1244,23 @@ struct HasNonConstExprMemInit {
int x = f(); // both-note {{non-constexpr function}}
constexpr HasNonConstExprMemInit() {} // both-error {{never produces a constant expression}}
};

namespace {
template <class Tp, Tp v>
struct integral_constant {
static const Tp value = v;
};

template <class Tp, Tp v>
const Tp integral_constant<Tp, v>::value;

typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;

/// This might look innocent, but we get an evaluateAsInitializer call for the
/// static bool member before evaluating the first static_assert, but we do NOT
/// get such a call for the second one. So the second one needs to lazily visit
/// the data member itself.
static_assert(true_type::value, "");
static_assert(true_type::value, "");
}

0 comments on commit a4b39f6

Please sign in to comment.