[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