[clang] [clang][bytecode] Typecheck called functions pointer more thorougly (PR #159757)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 19 04:06:34 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
Fix two older FIXME items from the `functions.cpp` test.
---
Full diff: https://github.com/llvm/llvm-project/pull/159757.diff
2 Files Affected:
- (modified) clang/lib/AST/ByteCode/Interp.cpp (+10-3)
- (modified) clang/test/AST/ByteCode/functions.cpp (+8-10)
``````````diff
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index d5e75a0c90469..0f322f6ed42ac 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1750,9 +1750,8 @@ bool CallPtr(InterpState &S, CodePtr OpPC, uint32_t ArgSize,
const Pointer &Ptr = S.Stk.pop<Pointer>();
if (Ptr.isZero()) {
- const auto *E = cast<CallExpr>(S.Current->getExpr(OpPC));
- S.FFDiag(E, diag::note_constexpr_null_callee)
- << const_cast<Expr *>(E->getCallee()) << E->getSourceRange();
+ S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_null_callee)
+ << const_cast<Expr *>(CE->getCallee()) << CE->getSourceRange();
return false;
}
@@ -1778,6 +1777,14 @@ bool CallPtr(InterpState &S, CodePtr OpPC, uint32_t ArgSize,
return false;
}
+ // Can happen when casting function pointers around.
+ QualType CalleeType = CE->getCallee()->getType();
+ if (CalleeType->isPointerType() &&
+ !S.getASTContext().hasSameFunctionTypeIgnoringExceptionSpec(
+ F->getDecl()->getType(), CalleeType->getPointeeType())) {
+ return false;
+ }
+
assert(ArgSize >= F->getWrittenArgSize());
uint32_t VarArgSize = ArgSize - F->getWrittenArgSize();
diff --git a/clang/test/AST/ByteCode/functions.cpp b/clang/test/AST/ByteCode/functions.cpp
index 01bf0a55bd19a..328bd7f36c640 100644
--- a/clang/test/AST/ByteCode/functions.cpp
+++ b/clang/test/AST/ByteCode/functions.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -pedantic -verify=expected,both %s
-// RUN: %clang_cc1 -std=c++14 -fexperimental-new-constant-interpreter -pedantic -verify=expected,both %s
-// RUN: %clang_cc1 -std=c++20 -fexperimental-new-constant-interpreter -pedantic -verify=expected,both %s
-// RUN: %clang_cc1 -pedantic -verify=ref,both %s
-// RUN: %clang_cc1 -pedantic -std=c++14 -verify=ref,both %s
-// RUN: %clang_cc1 -pedantic -std=c++20 -verify=ref,both %s
+// RUN: %clang_cc1 -pedantic -verify=expected,both %s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -std=c++14 -pedantic -verify=expected,both %s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -std=c++20 -pedantic -verify=expected,both %s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -pedantic -verify=ref,both %s
+// RUN: %clang_cc1 -std=c++14 -pedantic -verify=ref,both %s
+// RUN: %clang_cc1 -std=c++20 -pedantic -verify=ref,both %s
#define fold(x) (__builtin_constant_p(0) ? (x) : (x))
@@ -672,10 +672,8 @@ namespace FunctionCast {
constexpr int test4 = fold(IntFn(DoubleFn(f)))();
constexpr int test5 = IntFn(fold(DoubleFn(f)))(); // both-error {{constant expression}} \
// both-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
- // FIXME: Interpreter is less strict here.
- constexpr int test6 = fold(IntPtrFn(f2))() == nullptr; // ref-error {{constant expression}}
- // FIXME: The following crashes interpreter
- // constexpr int test6 = fold(IntFn(f3)());
+ constexpr int test6 = fold(IntPtrFn(f2))() == nullptr; // both-error {{constant expression}}
+ constexpr int test7 = fold(IntFn(f3)()); // both-error {{must be initialized by a constant expression}}
}
#if __cplusplus >= 202002L
``````````
</details>
https://github.com/llvm/llvm-project/pull/159757
More information about the cfe-commits
mailing list