# Port code from GCC This chapter describes issues commonly encountered while porting to LLVM an application that was previously built only with GCC. Note For more information on GCC compatibility, see [Language compatibility](https://docs.qualcomm.com/doc/80-VB419-99/topic/language_compatibility.html#ch-language-compatibility). ## Command options LLVM supports many but not all of the GCC command options. Unsupported options are either ignored or flagged with a warning or error message; most receive warning messages. For more information, see [Section 4.3.5](https://docs.qualcomm.com/doc/80-VB419-99/topic/use_the_compilers.html#sec-warning-and-error-messages). ## Errors and warnings LLVM enforces strict conformance to the C11 language standard. As a result, you might encounter new errors and warnings when compiling GCC code. To handle these messages when porting to LLVM, consider the following steps: 1. Remove the -Werror command option if it is being used (because it converts all warnings into errors). 2. Update the code to eliminate the remaining errors and warnings. ## Function declarations LLVM enforces the C11 rules for function declarations. In particular: - A function declared with a non-void return type must return a value of that type. - A function referenced before being declared is assumed to return a value of type int. If the function is subsequently declared to return some other type, it is flagged as an error. - A function declaration with the inline attribute assumes the existence of a separate definition for the function, which does not include the inline attribute. If no such definition appears in the program, a link-time error will occur. To satisfy these restrictions when porting to LLVM, consider the following steps: 1. Use `-Wreturn-type` to generate a warning whenever a function definition does not return a value of its declared type. 2. Use `-Wimplicit-function-declaration` to generate a warning whenever a function is used before being declared. 3. Update the code to eliminate the remaining errors and warnings. For more information on inlining, go to: [clang.llvm.org/compatibility.html#inline](http://clang.llvm.org/compatibility.html#inline) For a discussion of different inlining approaches, go to: [http://www.greenend.org.uk/rjk/tech/inline.html](http://www.greenend.org.uk/rjk/tech/inline.html) ## Casting to incompatible types LLVM enforces the C11 rules for *strict aliasing*. In the C language, two pointers that reference the same memory location are said to *alias* one another. Because any store through an aliased pointer might modify the data referenced by one of its pointer aliases, pointer aliases can limit the compiler’s ability to generate optimized code. In strict aliasing, pointers to different types are prevented from being aliased with one another. The compiler flags pointer aliases with an error message. Strict aliasing has a few exceptions: - Any pointer type can be cast to char\* or void\*. - A char\* or void\* can be cast to any pointer type. - Pointers to types that differ only by whether they are signed or unsigned (for example, int versus unsigned int) can be aliased. To satisfy strict aliasing when porting to LLVM, consider the following steps: 1. Use `-Wcast-align` to generate a warning whenever a pointer alias is detected. 2. Update the code to eliminate the resulting warnings. Note Dereferencing a pointer that is cast from a less strictly aligned type has undefined behavior. ## aligned attribute LLVM does not allow the aligned attribute to appear inside the alignof operator. To satisfy this restriction when porting to LLVM, create a typedef with the aligned attribute. For example: typedef unsigned char u8; #ifdef llvm typedef u8 attribute((aligned)) aligned_u8; #endif unsigned int foo() { #ifndef llvm return alignof (u8 attribute ((aligned))); #else return alignof (aligned_u8); #endif } Copy to clipboard ## Reserved registers LLVM does not support the GCC extension to place global variables in specific registers. To satisfy this restriction when porting to LLVM, use the equivalent LLVM intrinsics whenever possible. For example: #ifndef llvm register unsigned long current_frame_pointer asm("r11"); #endif ... #ifndef llvm fp = current_frame_pointer; #else fp = (unsigned long) builtin_frame_address(0); #endif Copy to clipboard ## Inline versus extern inline LLVM conforms to the C11 language standard, which defines different semantics for the inline keyword than GCC. For example, consider the following code: inline int add(int i, int j) { return i + j; } int main() { int i = add(4, 5); return i; } Copy to clipboard In C11 the function attribute inline specifies that a function’s definition is provided only for inlining, and that another definition (without the inline attribute) is specified elsewhere in the program. This implies that this example is incomplete, because if add() is not inlined (for example, when compiling without optimization), main() will include an unresolved reference to that other function definition. This will result in the following link-time error: Undefined symbols: "_add", referenced from: _main in cc-y1jXIr.o Copy to clipboard By contrast, GCC’s default behavior follows the GNU89 dialect, which is based on the C89 language standard. C89 does not support the inline keyword; however, GCC recognizes it as a language extension, and treats it as a hint to the optimizer. There are several ways to fix this problem: - Change add() to a static inline function. This is usually the right solution if only one translation unit needs to use the function. Static inline functions are always resolved within the translation unit, so it will not be necessary to add a non-inline definition of the function elsewhere in the program. - Remove the inline keyword from this definition of add(). The inline keyword is not required for a function to be inlined, nor does it guarantee that it will be. Some compilers ignore it completely. LLVM treats it as a mild suggestion from the programmer. - Provide an external (non-inline) definition of add() somewhere else in the program. The two definitions *must* be equivalent. - Compile with the GNU89 dialect by adding -std=gnu89 to the set of LLVM options. We do not recommend this approach. Last Published: May 10, 2024 [Previous Topic Compiler security tools](https://docs.qualcomm.com/bundle/publicresource/80-VB419-99/topics/compiler_security_tools.md) [Next Topic Coding practices](https://docs.qualcomm.com/bundle/publicresource/80-VB419-99/topics/coding_practices.md)