[clang] [clang] Forbid reinterpret_cast of function pointers in constexpr. (PR #150557)

Eli Friedman via cfe-commits cfe-commits at lists.llvm.org
Sat Jul 26 01:23:09 PDT 2025


================
@@ -3,8 +3,8 @@
 // RUN: %clang_cc1 -x c -fsyntax-only %s -verify=c -std=c11 -fexperimental-new-constant-interpreter
 // RUN: %clang_cc1 -x c -fsyntax-only %s -pedantic -verify=c-pedantic -std=c11 -fexperimental-new-constant-interpreter
 //
-// RUN: %clang_cc1 -x c++ -fsyntax-only %s -verify=cxx
-// RUN: %clang_cc1 -x c++ -fsyntax-only %s -pedantic -verify=cxx-pedantic
+// RUN: %clang_cc1 -x c++ -fsyntax-only %s -verify=cxx-nointerpreter
+// RUN: %clang_cc1 -x c++ -fsyntax-only %s -pedantic -verify=cxx-pedantic,cxx-nointerpreter
----------------
efriedma-quic wrote:

Your suggestion is subtly different from my patch in one way; consider:

```
#define fold(x) (__builtin_constant_p(x) ? (x) : (x))
constexpr double f() { return 1; }
typedef double (*DoubleFn)();
constexpr DoubleFn x = (DoubleFn)fold((void*)f);
```

if you write something like `constexpr fnptr x = (fnptr)fold(void*)f));`, my patch gives a warning, and yours doesn't.  I should probably add a testcase for this.  Granted, I'm not sure this matters a lot, since there's no way to get a function pointer into a void* without resorting to extensions.

----

The additional diagnostic in functions.cpp is because traditional consteval produces a diagnostic note_invalid_subexpr_in_const_expr if a pointer is called where the type of the function doesn't match the function pointer type.  CallPtr doesn't produce a diagnostic if it finds a mismatch, so we return a "stale" diagnostic.

It also has a much looser interpretation of what counts as "matching".  For example, it's happy if you call a function that returns "long" with a function pointer that returns "long long".

https://github.com/llvm/llvm-project/pull/150557


More information about the cfe-commits mailing list