-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang][Interp] Fix function pointer callexpr eval order #101821
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
We need to evaluate the callee before the arguments.
@llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) ChangesWe need to evaluate the callee before the arguments. Full diff: https://github.com/llvm/llvm-project/pull/101821.diff 2 Files Affected:
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 \
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/143/builds/1240 Here is the relevant piece of the build log for the reference:
|
We need to evaluate the callee before the arguments.