handle potentially throwing functions in no_cfi_icall

Define templates for potentially throwing functions at C++17
when noexcept becomes part of a function's type.

Change-Id: Ib174672a98fac9cd3f88fc3aef1b6cadd0bcccf6
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2454835
Reviewed-by: Eric Astor <epastor@google.com>
GitOrigin-RevId: 5368dc63890174d8a602636211a9cfcab9690dd5
diff --git a/util/misc/no_cfi_icall.h b/util/misc/no_cfi_icall.h
index dcd0b9b..25535b4 100644
--- a/util/misc/no_cfi_icall.h
+++ b/util/misc/no_cfi_icall.h
@@ -76,6 +76,28 @@
 };
 #endif  // OS_WIN && ARCH_CPU_X86
 
+#if __cplusplus >= 201703L
+// These specializations match functions which are not explicitly declared
+// noexcept. They must only be present at C++17 when noexcept is part of a
+// function's type. If they are present earlier, they redefine the
+// specializations above.
+template <typename R, typename... Args>
+struct FunctorTraits<R (*)(Args...)> {
+  template <typename Function, typename... RunArgs>
+  DISABLE_CFI_ICALL static R Invoke(Function&& function, RunArgs&&... args) {
+    return std::forward<Function>(function)(std::forward<RunArgs>(args)...);
+  }
+};
+
+template <typename R, typename... Args>
+struct FunctorTraits<R (*)(Args..., ...)> {
+  template <typename Function, typename... RunArgs>
+  DISABLE_CFI_ICALL static R Invoke(Function&& function, RunArgs&&... args) {
+    return std::forward<Function>(function)(std::forward<RunArgs>(args)...);
+  }
+};
+#endif
+
 }  // namespace
 
 //! \brief Disables cfi-icall for calls made through a function pointer.