[clang] f78d288 - [clang][Interp] Fix function pointer callexpr eval order (#101821)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Aug 3 07:56:42 PDT 2024
Author: Timm Baeder
Date: 2024-08-03T16:56:37+02:00
New Revision: f78d288d9d77c66f8b3036c62bb55160f19ba9cd
URL: https://github.com/llvm/llvm-project/commit/f78d288d9d77c66f8b3036c62bb55160f19ba9cd
DIFF: https://github.com/llvm/llvm-project/commit/f78d288d9d77c66f8b3036c62bb55160f19ba9cd.diff
LOG: [clang][Interp] Fix function pointer callexpr eval order (#101821)
We need to evaluate the callee before the arguments.
Added:
Modified:
clang/lib/AST/Interp/Compiler.cpp
clang/test/AST/Interp/eval-order.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/Compiler.cpp b/clang/lib/AST/Interp/Compiler.cpp
index e1fa0eb1eacb3..ada22b569b2b0 100644
--- a/clang/lib/AST/Interp/Compiler.cpp
+++ b/clang/lib/AST/Interp/Compiler.cpp
@@ -4003,6 +4003,13 @@ bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
} else if (!this->visit(MC->getImplicitObjectArgument())) {
return false;
}
+ } else if (!FuncDecl) {
+ const Expr *Callee = E->getCallee();
+ CalleeOffset = this->allocateLocalPrimitive(Callee, PT_FnPtr, true, false);
+ if (!this->visit(Callee))
+ return false;
+ if (!this->emitSetLocal(PT_FnPtr, *CalleeOffset, E))
+ return false;
}
llvm::BitVector NonNullArgs = collectNonNullArgs(FuncDecl, Args);
@@ -4071,22 +4078,19 @@ bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
ArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr)));
- // Get the callee, either from a member pointer saved in CalleeOffset,
- // or by just visiting the Callee expr.
- if (CalleeOffset) {
+ // Get the callee, either from a member pointer or function pointer saved in
+ // CalleeOffset.
+ if (isa<CXXMemberCallExpr>(E) && CalleeOffset) {
if (!this->emitGetLocal(PT_MemberPtr, *CalleeOffset, E))
return false;
if (!this->emitGetMemberPtrDecl(E))
return false;
- if (!this->emitCallPtr(ArgSize, E, E))
- return false;
} else {
- if (!this->visit(E->getCallee()))
- return false;
-
- if (!this->emitCallPtr(ArgSize, E, E))
+ if (!this->emitGetLocal(PT_FnPtr, *CalleeOffset, E))
return false;
}
+ if (!this->emitCallPtr(ArgSize, E, E))
+ return false;
}
// Cleanup for discarded return values.
diff --git a/clang/test/AST/Interp/eval-order.cpp b/clang/test/AST/Interp/eval-order.cpp
index 77f50831f4f47..d9cfd0b4642fa 100644
--- a/clang/test/AST/Interp/eval-order.cpp
+++ b/clang/test/AST/Interp/eval-order.cpp
@@ -45,7 +45,7 @@ namespace EvalOrder {
}
template <typename T> constexpr T &&b(T &&v) {
if (!done_a)
- throw "wrong"; // expected-note 5{{not valid}}
+ throw "wrong"; // expected-note 4{{not valid}}
done_b = true;
return (T &&)v;
}
@@ -75,8 +75,7 @@ namespace EvalOrder {
SEQ(A(&ud)->*B(&UserDefined::n));
// Rule 4: a(b1, b2, b3)
- SEQ(A(f)(B(1), B(2), B(3))); // expected-error {{not an integral constant expression}} FIXME \
- // expected-note 2{{in call to}}
+ SEQ(A(f)(B(1), B(2), B(3)));
// Rule 5: b = a, b @= a
SEQ(B(lvalue<int>().get()) = A(0)); // expected-error {{not an integral constant expression}} FIXME \
More information about the cfe-commits
mailing list