title: Warn for function argument that is NOT a compile time constant
body: <p>Suppose I am maintaining a library function that takes two arguments, both pointers.  The second argument exists only for backward compatibility; callers should always pass a NULL. I would like to put something into my header file that makes the compiler issue warnings if the second argument is not a compile-time constant NULL.  I thought I would be able to do this using GCC's <code>__builtin_constant_p</code> and <code>__attribute__((warning))</code> extensions:</p>
  
  <pre><code>extern void thefun_called_with_nonnull_arg (void)
      __attribute__((__warning__(
          "'thefun' called with second argument not NULL")));
  
  extern int real_thefun (void *, void *);
  
  static inline int
  thefun (void *a, void *b)
  {
     if (!__builtin_constant_p(b) || b != 0)
         thefun_called_with_nonnull_arg();
     return real_thefun(a, b);
  }
  
  int warning_expected (void *a, void *b)
  {
      return thefun(a, b);
  }
  int warning_not_expected (void *a)
  {
      return thefun(a, 0);
  }
  </code></pre>
  
  <p>But this doesn't work with any version of GCC I have tested.  I get warnings for <em>both</em> calls to <code>thefun</code>.  (<a href="https://godbolt.org/z/V-FHtZ" rel="nofollow noreferrer">Compiler Explorer demo</a>.)</p>
  
  <p>Can anyone suggest an alternative construct that will produce a warning for <code>warning_expected</code>, and not for <code>warning_not_expected</code> ?</p>
  
  <p>Notes:</p>
  
  <ul>
  <li>Curiously, the above <a href="https://godbolt.org/z/rcpAug" rel="nofollow noreferrer"><em>does</em> work</a> if <code>b</code> is an <code>int</code>.</li>
  <li>The above uses GCC-specific extensions, however a solution that works on a broader variety of compilers would be welcome.  (In particular, clang does not implement <code>attribute((warning))</code> and I haven't had any luck finding an alternative.)</li>
  <li>A solution that still works when optimization is turned off would be preferable to one that doesn't.  (The above does not work with optimization turned off, even if <code>b</code> is an <code>int</code> and <code>thefun</code> is marked always-inline.)</li>
  <li>A solution that doesn't involve defining <code>thefun</code> as a macro would be preferable to one that does.</li>
  <li>The header has to work when included from C programs and from C++ programs.  A modest amount of ifdeffage is acceptable.</li>
  <li>It must be a warning, not a hard error, unless <code>-Werror</code> or equivalent is active.</li>
  </ul>
  
  <hr>
  
  <p><strong>EDIT:</strong> Based on <a href="https://stackoverflow.com/a/57665148">Kamil Cuk's discovery</a> that the unwanted warning can be suppressed by casting the pointer to an integer <em>of a different size</em>, I have determined that this is an oversight in the implementation of <code>__builtin_constant_p</code> and <a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91554" rel="nofollow noreferrer">filed GCC bug report #91554</a>.  I'd still be interested in answers that provide ways to do this with clang, icc, or any other compiler that's commonly used together with GNU libc.</p>