<div dir="ltr">[Moving from llvmdev to cfe-dev]<br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, May 6, 2014 at 6:39 AM, <a href="mailto:coles.david@gmail.com">coles.david@gmail.com</a> <span dir="ltr"><<a href="mailto:coles.david@gmail.com" target="_blank">coles.david@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr">Hi,<br><br>I've been trying to implement some basic compile time checks such as using "__builtin_object_size" to verify certain preconditions (such as ensuring a function that is passed a byte array contains a minimum number of bytes). This turned out to be a little tricker than expected as "_Static_assert" and similar mechanisms can't be used since "__builtin_object_size" can't be used as a integral constant expression.<br>
</div></blockquote><div><br></div><div>__builtin_object_size can be used as a constant expression in some cases (essentially, when its operand is a constant expression).</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div dir="ltr">Most GCC code I've looked at uses the "__warning__" or "__error__" attributes to declare trap functions that if not eliminated via dead-code elimination will generate a compiler warning or error (big improvement over just a runtime abort). For example:<br>

<br>    size_t d_len = __builtin_object_size(d, 0);<br>    if (__builtin_constant_p(copy_amount) && (copy_amount > d_len)) {<div>         // declared with __attribute__((__error__("memcpy called with size bigger than destination")));<br>

        __memcpy_dest_size_error();<br>    }<br><br>Sadly neither of these attributes are currently supported in Clang. Is this a reasonable feature request or does Clang have some better mechanism? (Perhaps the Static Analyzer?)<br>

<br>I notice that Clang supports both the "deprecated" and "unavailable" attributes, but these serve a slightly different purpose of warning or preventing a user from calling certain functions.<br><br>

Probably the most promising option appears to be Clang 3.5's new "enable_if" function attribute that could be used to make the function unavailable if it violates certain preconditions.</div></div></blockquote>
<div><br></div><div>enable_if should do the job here; it's designed for exactly this sort of check. Something like:</div><div><br></div><div>void *memcpy(void *dest, const void *src, size_t n)</div><div>  __attribute__((enable_if(__builtin_object_size(dest, 0) < n, "selected if dest is too small"),</div>
<div>                 unavailable("dest of memcpy is smaller than size of buffer to copy"),</div><div>                 overloadable));</div><div><div>void *memcpy(void *dest, const void *src, size_t n)</div><div>
  __attribute__((enable_if(__builtin_object_size(src, 0) < n, "selected if src is too small"),</div><div>                 unavailable("src of memcpy is smaller than size of buffer to copy"),</div><div>
                 overloadable));</div></div><div><div>void *memcpy(void *dest, const void *src, size_t n) asm("memcpy")</div></div><div>  __attribute__((overloadable));</div><div><br></div><div>... should work.</div>
</div></div></div>