[clang][bytecode] Fix a crash in CheckConstantExpression (#129752)

The APValue we generated for a pointer with a LValueReferenceType base
had an incorrect lvalue path attached.

The attached test case is extracted from libc++'s regex.cpp.
This commit is contained in:
Timm Baeder
2025-03-05 08:21:51 +01:00
committed by GitHub
parent f1dbc45210
commit 107fe0ec6c
2 changed files with 40 additions and 1 deletions

View File

@@ -210,7 +210,8 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const {
};
bool UsePath = true;
if (getType()->isLValueReferenceType())
if (const ValueDecl *VD = getDeclDesc()->asValueDecl();
VD && VD->getType()->isLValueReferenceType())
UsePath = false;
// Build the path into the object.

View File

@@ -140,3 +140,41 @@ namespace Temporaries {
static_assert(j.a.n == 1, ""); // both-error {{not an integral constant expression}} \
// both-note {{read of temporary is not allowed in a constant expression outside the expression that created the temporary}}
}
namespace Params {
typedef __SIZE_TYPE__ size_t;
template <class _Tp, size_t _Np>
constexpr _Tp* end(_Tp (&__array)[_Np]) noexcept {
return __array + _Np;
}
struct classnames {
const char* elem_;
int a;
};
constexpr classnames ClassNames[] = {
{"a", 0},
{"b", 1},
{"b", 1},
{"b", 1},
{"b", 1},
{"b", 1},
{"b", 1},
{"b", 1},
};
constexpr bool foo() {
/// This will instantiate end() with ClassNames.
/// In Sema, we will constant-evaluate the return statement, which is
/// something like __array + 8. The APValue we return for this
/// may NOT have a LValuePath set, since it's for a parameter
/// of LValueReferenceType.
end(ClassNames);
return true;
}
static_assert(foo());
}