<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Feb 29, 2016 at 1:53 PM,  <span dir="ltr"><<a href="mailto:" target="_blank"></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">Hi all,<br>
<br>
I'd like to make a proposal to implement the new vtable ABI described in<br>
PR26723, which I'll call the relative ABI. That bug gives more details and<br>
justification for that ABI.<br>
<br>
The user interface for the new ABI would be that -fwhole-program-vtables<br>
would take an optional value indicating which aspects of the program have<br>
whole-program scope. For example, the existing implementation of whole-program<br>
vcall optimization allows external code to call into translation units<br>
compiled with -fwhole-program-vtables, but does not allow external code to<br>
derive from classes defined in such translation units, so you could request<br>
the current behaviour with "-fwhole-program-vtables=derive", which means<br>
that derived classes are not allowed from outside the program. To request<br>
the new ABI, you can specify "-fwhole-program-vtables=call,derive",<br>
which means that calls and derived classes are both not allowed from<br>
outside the program. "-fwhole-program-vtables" would be short for<br>
"-fwhole-program-vtables=call,derive,anythingelseweaddinfuture".<br></blockquote><div><br></div><div><div>Based on discussion with John McCall in PR26723, I’d like to change the user interface for -fwhole-program-vtables, and introduce an interface specifically to enable the relative ABI. That interface would be based on a whitelist rather than a blacklist, and together with -fwhole-program-vtables would enable devirtualization, virtual const prop, and virtual function stripping for those classes.</div><div><br></div><div>The new user interface is as follows:</div><div><br></div><div>We would introduce two new attributes, [[clang::unstable_abi]] and [[clang::stable_abi]], which would be attached to a class and would enable or disable the unstable ABI for that class. It is an ODR violation to use [[clang::unstable_abi]] in two translation units compiled with different versions of Clang (we may consider extending the object format to allow a linker to diagnose this). Specifically, mixing different head revisions or major releases is not allowed, but mixing different point releases is fine. The attribute __declspec(uuid()) (which is used for COM classes on Windows) would imply [[clang::stable_abi]].</div><div><br></div><div>A “dynamic-introducing” class is a class that declares new virtual member functions or virtual bases, and has no dynamic bases or virtual bases. A class that is dynamic but not dynamic-introducing would use the same ABI as its dynamic base classes. The compiler will diagnose if a class has two or more dynamic bases with different ABIs, or if the bases have a different ABI from the one explicitly specified by an attribute.</div><div><br></div><div>The ABI for a dynamic-introducing class is determined from the attribute, or if the class has no attribute, from the following flags:</div><div><br></div><div>-funstable-c++-abi or -funstable-c++-abi-classes would enable the unstable C++ ABI for all classes (the idea being that -funstable-c++-abi would also cover any unrelated ABI breaks we may want to make in future).</div><div>-funstable-c++-abi-classes=PATH would enable the unstable C++ ABI for dynamic-introducing classes specified in the file at PATH.</div><div>The -fwhole-program-vtables-blacklist flag would be removed, and I'm no longer proposing that -fwhole-program-vtables would take a value. The whole-program blacklist would be replaced by either inference based on visibility or a new [[clang::no_whole_program]] attribute.</div><div><br></div><div>It is effectively an ODR violation to define a class that uses the unstable ABI in a translation unit compiled with a different set of -funstable-c++-abi* flags. It is also a violation for a linkage unit other than the one compiled with -fwhole-program-vtables to define any of the classes that use the unstable ABI.</div><div><br></div><div>The format of the file is a series of lines ending in either * or **. Preceding that is a namespace specifier delimited by double-colons followed by “::”, or the empty string to denote the global namespace. Each entry in the list indicates that dynamic-introducing classes in that namespace, including nested classes, classes defined in enclosed anonymous namespaces, and classes defined within member functions of those classes, use the unstable ABI. If the line ends in “*” this applies to the given namespace only, while if the line ends in “**” it applies to the given namespace and any enclosed namespaces.</div><div><br></div><div>In Chromium for example, the contents of the file would look like this:</div><div><br></div><div>*</div><div>app::**</div><div>base::**</div><div>browser::**</div><div>[...]</div><div>wm::**</div><div>zip::**</div><div><br></div><div>This whitelist specifies that classes defined in the global namespace as well as app, base, browser etc. and any enclosed namespaces would use the unstable ABI. This list excludes std::**, so we can continue to use the system standard library. If Chromium did start using its own copy of the standard library, we could create another whitelist with that entry in it, or just use the -funstable-c++-abi-classes flag.</div><div><br></div><div>We would also add a new warning: -Wc++-stable-abi. This would warn for any classes defined in non-system header files that are inferred from namespaces to use the stable ABI. This warning would be intended to be used by programs that intend to use the unstable ABI for any non-system classes (such as Chromium).</div><div><br></div><div>Control flow integrity (-fsanitize=cfi*) would also only be supported for classes using the unstable ABI, and would require the -fwhole-program-vtables flag, unless the cross-DSO mode (-fsanitize-cfi-cross-dso) is enabled.</div></div><div><br></div><div>Next steps:</div><div><br></div><div>I will send out a patch that implements the semantic analysis side of this. Once that lands, follow-up patches will actually start changing the unstable ABI.</div></div>
</div></div>