September 19, 2019·5 min read·engineeringcclangtooling

Clang 9 supports the control flow in asm goto

Initial asm goto support enables an important Linux kernel configuration, while Clang also adds compilation traces and more explicit analyzer controls.

An inline assembly statement that branches to a C label needs a compiler to understand more than the instructions inside its string. The compiler must also represent the possible transfer of control. Initial support for the GNU C asm goto extension is one of the changes in Clang 9, announced on September 19 in the LLVM release message. It closes a specific compatibility gap for code that uses assembly to select a C execution path.

The Clang 9 release notes identify the Linux kernel's jump-label configuration as a principal consumer. They say the mainline x86_64 kernel is now buildable and bootable with Clang 9. That is a concrete result of implementing the extension. It connects a language frontend change with a source tree whose control-flow conventions require it.

I find this more informative than a broad claim of compiler compatibility. C code often includes platform contracts beyond ISO C, especially near an operating system. Supporting those contracts requires the optimizer to understand the intended interaction between assembly and surrounding source.

An assembly string is insufficient

Ordinary reasoning about a function depends on knowing which statements can run next. A compiler can optimize a path only within the control-flow model it has built. An assembly fragment with an exit to a C label has an effect outside the fragment, so the frontend has to communicate that edge to later compilation stages.

The release's description of asm goto places the feature at that boundary. It allows inline assembly to transfer control to labels in the surrounding function. The fact that a target assembler accepts the instruction text does not by itself provide the C compiler with the same information. Parsing a string and representing its possible exits are separate jobs.

That distinction explains the significance of jump-label support for the kernel. A codebase can use only familiar C declarations around a construct that nevertheless depends on a compiler extension. An alternative compiler must support the extension's semantics before the enclosing program can rely on it.

The notes qualify the new support as initial. They identify unsupported corner cases in the integrated assembler and IfConverter. This is narrower than a promise that every historical use of asm goto works. The release establishes useful compatibility while still naming parts of the implementation that need further work.

A filename macro with a narrower purpose

Clang 9 adds the Clang-specific __FILE_NAME__ macro across its C-family languages. The versioned language extensions manual describes it as yielding the last path component instead of the invocation-dependent full path used by __FILE__.

That is useful when a diagnostic wants a short source name. A logging helper can choose the extension when available and retain a standard fallback. This lets the same diagnostic helper compile when the Clang extension is absent:

#include <stdio.h>

#if defined(__FILE_NAME__)
#define SOURCE_NAME __FILE_NAME__
#else
#define SOURCE_NAME __FILE__
#endif

void report_start(void)
{
    fprintf(stderr, "%s entered\n", SOURCE_NAME);
}

The macro communicates a presentation choice. Two files in different directories can have the same final component, so the shorter spelling cannot always identify a unique source file. A tool that needs an unambiguous path has a different requirement from a human-oriented message intended to remain compact.

The same manual recommends feature checks instead of treating a marketing version as proof of a language feature. Vendors can use different numbering schemes. A condition that asks whether the particular macro exists states the requirement more directly than a comparison against a compiler major version.

The compiler can report where compilation time goes

The new -ftime-trace option writes hierarchical timing information to a JSON file beside the compiled object. The release notes describe both frontend activity, including file parsing, and backend work such as optimization passes. They also name compatible trace viewers.

A C translation unit can therefore obtain a compilation trace with an ordinary object build. The option adds the report to the existing compilation. The resulting report belongs to that translation unit, so a build with many source files produces separate evidence for each compilation:

clang -O2 -ftime-trace -c worker.c -o worker.o

The trace describes compiler activity. It is not a profile of the program that worker.o will help produce. That distinction matters when investigating build costs, since an expensive optimization pass and an expensive runtime function answer different questions.

Hierarchical reporting can associate work with the activity containing it. A flat total says how long the translation took, but offers little explanation of whether parsing or optimization accounted for the time. The trace provides a way to inspect those stages without changing application code merely to obtain a compiler-side measurement.

I value that visibility because C's small grammar does not make its toolchain simple. Optimization and platform support can involve substantial work that a source-level reading does not reveal. A compiler report should identify that work in terms of the stage that performed it.

Analyzer controls distinguish maturity and intent

The release adds a checker for unsafe or deprecated buffer-handling functions in C11 and newer C code. It also separates analyzer checker listings into user-facing stable checkers, in-development checkers and developer-oriented checkers. Similar categories apply when listing checker options.

That organization gives a user more context than one undifferentiated list. An experimental checker and a stable checker may both be available, but their availability does not imply the same intended use. The analyzer's interface can communicate that difference before a user enables a checker in a build.

Clang 9 also adds an analyzer option that turns analyzer warnings into errors. This is a policy control over the analyzer's result. Choosing that policy is distinct from deciding which analyses to enable, and the new listing categories help make the latter decision more explicit.

The asm goto addition remains the release's clearest C compatibility change. It lets the frontend represent a transfer of control required by an important kernel configuration. The accompanying tooling changes expose other information that source text leaves hidden, including compiler activity and the intended audience of an analysis. Each interface describes a specific fact that a build or systems programmer can use.