diff options
author | Timm Bäder <tbaeder@redhat.com> | 2024-04-15 14:17:31 +0200 |
---|---|---|
committer | Timm Bäder <tbaeder@redhat.com> | 2024-04-16 12:09:49 +0200 |
commit | a831c54357c2bb7b8b457ccea22836c23e8b8625 (patch) | |
tree | 292b0a8f102c2e45f127e14bee0d8afddb2b8dc7 | |
parent | 31424be3aef4290dd84065b9371fcd0c5014e097 (diff) |
[clang][Interp] Avoid calling invalid functions
Check if the non-null function pointer is even valid before calling
the function.
-rw-r--r-- | clang/lib/AST/Interp/FunctionPointer.h | 1 | ||||
-rw-r--r-- | clang/lib/AST/Interp/Interp.h | 4 | ||||
-rw-r--r-- | clang/test/AST/Interp/functions.cpp | 15 |
3 files changed, 18 insertions, 2 deletions
diff --git a/clang/lib/AST/Interp/FunctionPointer.h b/clang/lib/AST/Interp/FunctionPointer.h index c2ea295b82bd..fc3d7a4214a7 100644 --- a/clang/lib/AST/Interp/FunctionPointer.h +++ b/clang/lib/AST/Interp/FunctionPointer.h @@ -32,6 +32,7 @@ public: const Function *getFunction() const { return Func; } bool isZero() const { return !Func; } + bool isValid() const { return Valid; } bool isWeak() const { if (!Func || !Valid) return false; diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 4182254357eb..dd0bacd73acb 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -2236,6 +2236,10 @@ inline bool CallPtr(InterpState &S, CodePtr OpPC, uint32_t ArgSize, << const_cast<Expr *>(E) << E->getSourceRange(); return false; } + + if (!FuncPtr.isValid()) + return false; + assert(F); // Check argument nullability state. diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp index 4fb3c816000a..f9bb5d53634e 100644 --- a/clang/test/AST/Interp/functions.cpp +++ b/clang/test/AST/Interp/functions.cpp @@ -584,9 +584,20 @@ namespace VariadicOperator { namespace WeakCompare { [[gnu::weak]]void weak_method(); static_assert(weak_method != nullptr, ""); // both-error {{not an integral constant expression}} \ - // both-note {{comparison against address of weak declaration '&weak_method' can only be performed at runtim}} + // both-note {{comparison against address of weak declaration '&weak_method' can only be performed at runtim}} constexpr auto A = &weak_method; static_assert(A != nullptr, ""); // both-error {{not an integral constant expression}} \ - // both-note {{comparison against address of weak declaration '&weak_method' can only be performed at runtim}} + // both-note {{comparison against address of weak declaration '&weak_method' can only be performed at runtim}} +} + +namespace FromIntegral { +#if __cplusplus >= 202002L + typedef double (*DoubleFn)(); + int a[(int)DoubleFn((void*)-1)()]; // both-error {{not allowed at file scope}} \ + // both-warning {{variable length arrays}} + int b[(int)DoubleFn((void*)(-1 + 1))()]; // both-error {{not allowed at file scope}} \ + // expected-note {{evaluates to a null function pointer}} \ + // both-warning {{variable length arrays}} +#endif } |