Skip to content

Commit 107fe0e

Browse files
authored
[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.
1 parent f1dbc45 commit 107fe0e

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

clang/lib/AST/ByteCode/Pointer.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,8 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const {
210210
};
211211

212212
bool UsePath = true;
213-
if (getType()->isLValueReferenceType())
213+
if (const ValueDecl *VD = getDeclDesc()->asValueDecl();
214+
VD && VD->getType()->isLValueReferenceType())
214215
UsePath = false;
215216

216217
// Build the path into the object.

clang/test/AST/ByteCode/references.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,41 @@ namespace Temporaries {
140140
static_assert(j.a.n == 1, ""); // both-error {{not an integral constant expression}} \
141141
// both-note {{read of temporary is not allowed in a constant expression outside the expression that created the temporary}}
142142
}
143+
144+
namespace Params {
145+
typedef __SIZE_TYPE__ size_t;
146+
147+
template <class _Tp, size_t _Np>
148+
constexpr _Tp* end(_Tp (&__array)[_Np]) noexcept {
149+
return __array + _Np;
150+
}
151+
152+
153+
struct classnames {
154+
const char* elem_;
155+
int a;
156+
};
157+
158+
constexpr classnames ClassNames[] = {
159+
{"a", 0},
160+
{"b", 1},
161+
{"b", 1},
162+
{"b", 1},
163+
{"b", 1},
164+
{"b", 1},
165+
{"b", 1},
166+
{"b", 1},
167+
};
168+
169+
constexpr bool foo() {
170+
/// This will instantiate end() with ClassNames.
171+
/// In Sema, we will constant-evaluate the return statement, which is
172+
/// something like __array + 8. The APValue we return for this
173+
/// may NOT have a LValuePath set, since it's for a parameter
174+
/// of LValueReferenceType.
175+
end(ClassNames);
176+
return true;
177+
}
178+
179+
static_assert(foo());
180+
}

0 commit comments

Comments
 (0)