Apply GCC's tainted_args attribute to library entrypoints

The implementation applies `__attribute__((tainted_args))` by
integrating it into the existing ABI macro annotations.

In the process, quite a number of APIs were discovered to be unsafe in
ways that were not immediately fixable. Often this is because they lack
arguments that enable the appropriate bounds-checking to be applied.

Redesigning them is work beyond the scope of the immediate
effort. Instead, we also introduce a new annotation,
LIBPLDM_ABI_DEPRECATED_UNSAFE, that simply lacks
`__attribute__((tainted_args))` and therefore doesn't trigger the extra
analysis.

Change-Id: Ib8994eaa3907a5432d040426ad03687cbf4c2136
Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
diff --git a/meson.build b/meson.build
index 560effb..1a594de 100644
--- a/meson.build
+++ b/meson.build
@@ -12,7 +12,7 @@
         'tests=' + (meson.is_subproject() ? 'disabled' : 'enabled'),
     ],
     version: '0.9.1',
-    meson_version: '>=1.1.1',
+    meson_version: '>=1.3.0',
 )
 
 if get_option('tests').allowed()
@@ -33,17 +33,33 @@
 endif
 
 # ABI control
-visible = '__attribute__((visibility("default")))'
+compiler.has_function_attribute('visibility:default', required: true)
+entrypoint = '__attribute__((visibility("default")))'
+
+## Compile test until meson supports it via compiler.has_function_attribute()
+have_tainted_args_test = '#if !__has_attribute(tainted_args)\n#error\n#endif'
+if compiler.compiles(
+    have_tainted_args_test,
+    args: '-E',
+    name: 'compiler supports function attribute tainted_args',
+)
+    entrypoint += ' __attribute__((tainted_args))'
+endif
+
 libpldm_deprecated_aliases = []
 if get_option('abi').contains('deprecated')
-    conf.set('LIBPLDM_ABI_DEPRECATED', visible)
+    conf.set('LIBPLDM_ABI_DEPRECATED', entrypoint)
+    conf.set(
+        'LIBPLDM_ABI_DEPRECATED_UNSAFE',
+        '__attribute((visibility("default")))',
+    )
     add_project_arguments('-DLIBPLDM_API_DEPRECATED', language: ['c', 'cpp'])
 else
     conf.set('LIBPLDM_ABI_DEPRECATED', '')
 endif
-conf.set('LIBPLDM_ABI_STABLE', visible)  # Always expose the stable symbols
+conf.set('LIBPLDM_ABI_STABLE', entrypoint)  # Always expose the stable symbols
 if get_option('abi').contains('testing')
-    conf.set('LIBPLDM_ABI_TESTING', visible)
+    conf.set('LIBPLDM_ABI_TESTING', entrypoint)
     add_project_arguments('-DLIBPLDM_API_TESTING', language: ['c', 'cpp'])
 else
     conf.set('LIBPLDM_ABI_TESTING', '')