Skip to content

Commit 7a93508

Browse files
committed
[clang][Interp] Reject calling function pointers if types don't match
1 parent ba29e3a commit 7a93508

File tree

2 files changed

+24
-7
lines changed

2 files changed

+24
-7
lines changed

clang/lib/AST/Interp/Interp.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2569,6 +2569,12 @@ inline bool CallPtr(InterpState &S, CodePtr OpPC, uint32_t ArgSize,
25692569

25702570
assert(F);
25712571

2572+
// This happens when the call expression has been cast to
2573+
// something else, but we don't support that.
2574+
if (S.Ctx.classify(F->getDecl()->getReturnType()) !=
2575+
S.Ctx.classify(CE->getType()))
2576+
return false;
2577+
25722578
// Check argument nullability state.
25732579
if (F->hasNonNullAttr()) {
25742580
if (!CheckNonNullArgs(S, OpPC, F, CE, ArgSize))

clang/test/AST/Interp/functions.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s
2-
// RUN: %clang_cc1 -std=c++14 -fexperimental-new-constant-interpreter -verify=expected,both %s
3-
// RUN: %clang_cc1 -std=c++20 -fexperimental-new-constant-interpreter -verify=expected,both %s
4-
// RUN: %clang_cc1 -verify=ref,both %s
5-
// RUN: %clang_cc1 -std=c++14 -verify=ref,both %s
6-
// RUN: %clang_cc1 -std=c++20 -verify=ref,both %s
1+
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -pedantic -verify=expected,both %s
2+
// RUN: %clang_cc1 -std=c++14 -fexperimental-new-constant-interpreter -pedantic -verify=expected,both %s
3+
// RUN: %clang_cc1 -std=c++20 -fexperimental-new-constant-interpreter -pedantic -verify=expected,both %s
4+
// RUN: %clang_cc1 -pedantic -verify=ref,both %s
5+
// RUN: %clang_cc1 -pedantic -std=c++14 -verify=ref,both %s
6+
// RUN: %clang_cc1 -pedantic -std=c++20 -verify=ref,both %s
77

88
constexpr void doNothing() {}
99
constexpr int gimme5() {
@@ -471,7 +471,7 @@ namespace AddressOf {
471471
constexpr int foo() {return 1;}
472472
static_assert(__builtin_addressof(foo) == foo, "");
473473

474-
constexpr _Complex float F = {3, 4};
474+
constexpr _Complex float F = {3, 4}; // both-warning {{'_Complex' is a C99 extension}}
475475
static_assert(__builtin_addressof(F) == &F, "");
476476

477477
void testAddressof(int x) {
@@ -633,3 +633,14 @@ namespace {
633633
void (&r)() = f;
634634
void (&cond3)() = r;
635635
}
636+
637+
namespace FunctionCast {
638+
// When folding, we allow functions to be cast to different types. Such
639+
// cast functions cannot be called, even if they're constexpr.
640+
constexpr int f() { return 1; }
641+
typedef double (*DoubleFn)();
642+
typedef int (*IntFn)();
643+
int a[(int)DoubleFn(f)()]; // both-error {{variable length array}} \
644+
// both-warning {{are a Clang extension}}
645+
int b[(int)IntFn(f)()]; // ok
646+
}

0 commit comments

Comments
 (0)