Skip to content

Commit aeca2aa

Browse files
authored
[clang][bytecode] Fix CallPtr return type check (#129722)
CallExpr::getType() isn't enough here in some cases, we need to use CallExpr::getCallReturnType().
1 parent 0247a75 commit aeca2aa

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1515,7 +1515,7 @@ bool CallPtr(InterpState &S, CodePtr OpPC, uint32_t ArgSize,
15151515
// This happens when the call expression has been cast to
15161516
// something else, but we don't support that.
15171517
if (S.Ctx.classify(F->getDecl()->getReturnType()) !=
1518-
S.Ctx.classify(CE->getType()))
1518+
S.Ctx.classify(CE->getCallReturnType(S.getASTContext())))
15191519
return false;
15201520

15211521
// Check argument nullability state.

clang/test/AST/ByteCode/memberpointers.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,26 @@ namespace IndirectFields {
226226
constexpr I i{12};
227227
static_assert(ReadField<I, &I::a>(i) == 12, "");
228228
}
229+
230+
namespace CallExprTypeMismatch {
231+
/// The call expression's getType() returns just S, not S&.
232+
struct S {
233+
constexpr S(int i_) : i(i_) {}
234+
constexpr const S& identity() const { return *this; }
235+
int i;
236+
};
237+
238+
template<typename T, typename U>
239+
constexpr void Call(T t, U u) {
240+
((&u)->*t)();
241+
}
242+
243+
constexpr bool test() {
244+
const S s{12};
245+
246+
Call(&S::identity, s);
247+
248+
return true;
249+
}
250+
static_assert(test(), "");
251+
}

0 commit comments

Comments
 (0)