[clang] 7a93508 - [clang][Interp] Reject calling function pointers if types don't match
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 12 06:32:53 PDT 2024
Author: Timm Bäder
Date: 2024-07-12T15:32:40+02:00
New Revision: 7a935089d4593de6767901810594058904412106
URL: https://github.com/llvm/llvm-project/commit/7a935089d4593de6767901810594058904412106
DIFF: https://github.com/llvm/llvm-project/commit/7a935089d4593de6767901810594058904412106.diff
LOG: [clang][Interp] Reject calling function pointers if types don't match
Added:
Modified:
clang/lib/AST/Interp/Interp.h
clang/test/AST/Interp/functions.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 12143fbf50808..ac87901570ec1 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -2569,6 +2569,12 @@ inline bool CallPtr(InterpState &S, CodePtr OpPC, uint32_t ArgSize,
assert(F);
+ // This happens when the call expression has been cast to
+ // something else, but we don't support that.
+ if (S.Ctx.classify(F->getDecl()->getReturnType()) !=
+ S.Ctx.classify(CE->getType()))
+ return false;
+
// Check argument nullability state.
if (F->hasNonNullAttr()) {
if (!CheckNonNullArgs(S, OpPC, F, CE, ArgSize))
diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp
index f43be1d3c0403..fa29e08a30175 100644
--- a/clang/test/AST/Interp/functions.cpp
+++ b/clang/test/AST/Interp/functions.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s
-// RUN: %clang_cc1 -std=c++14 -fexperimental-new-constant-interpreter -verify=expected,both %s
-// RUN: %clang_cc1 -std=c++20 -fexperimental-new-constant-interpreter -verify=expected,both %s
-// RUN: %clang_cc1 -verify=ref,both %s
-// RUN: %clang_cc1 -std=c++14 -verify=ref,both %s
-// RUN: %clang_cc1 -std=c++20 -verify=ref,both %s
+// 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
constexpr void doNothing() {}
constexpr int gimme5() {
@@ -471,7 +471,7 @@ namespace AddressOf {
constexpr int foo() {return 1;}
static_assert(__builtin_addressof(foo) == foo, "");
- constexpr _Complex float F = {3, 4};
+ constexpr _Complex float F = {3, 4}; // both-warning {{'_Complex' is a C99 extension}}
static_assert(__builtin_addressof(F) == &F, "");
void testAddressof(int x) {
@@ -633,3 +633,14 @@ namespace {
void (&r)() = f;
void (&cond3)() = r;
}
+
+namespace FunctionCast {
+ // When folding, we allow functions to be cast to
diff erent types. Such
+ // cast functions cannot be called, even if they're constexpr.
+ constexpr int f() { return 1; }
+ typedef double (*DoubleFn)();
+ typedef int (*IntFn)();
+ int a[(int)DoubleFn(f)()]; // both-error {{variable length array}} \
+ // both-warning {{are a Clang extension}}
+ int b[(int)IntFn(f)()]; // ok
+}
More information about the cfe-commits
mailing list