You copied the Doc URL to your clipboard.


-fsanitize selects the sanitizer option that is used in code generation. It is an [ALPHA] feature.


This topic describes an [ALPHA] feature. See Support level definitions.


The default is no sanitizers are selected.




option specifies the sanitizer option for code generation. The only supported option is -fsanitize=memtag.


Memory tagging stack protection (stack tagging) is available for the AArch64 state for architectures with the Memory Tagging Extension. The Memory Tagging Extension is optional in Arm®v8.5-A and later architectures. When compiling with -fsanitize=memtag, the compiler uses memory tagging instructions that are not available for architectures without the Memory Tagging Extension. The resulting code cannot execute on architectures without the Memory Tagging Extension. For more information, see the +memtag feature in -mcpu.


Use -fsanitize=memtag to enable the generation of memory tagging code for protecting the memory allocations on the stack. When you enable memory tagging, the compiler checks that expressions that evaluate to addresses of objects on the stack are within the bounds of the object. If this cannot be guaranteed, the compiler generates code to ensure that the pointer and the object are tagged. When tagged pointers are dereferenced, the processor checks the tag on the pointer with the tag on the memory location being accessed. If the tags mismatch, the processor causes an exception and therefore tries to prevent the pointer from accessing any object that is different from the object whose address was taken.

For example, if a pointer to a variable on the stack is passed to another function, then the compiler might be unable to guarantee that this pointer is only used to access the same variable. In this situation, the compiler generates memory tagging code. The memory tagging instructions apply a unique tag to the pointer and to its corresponding allocation on the stack.


  • The ability of the compiler to determine whether a pointer access is bounded might be affected by optimizations. For example, if an optimization inlines a function, and as a result, if the compiler can guarantee that the pointer access is always safe, then the compiler might not generate memory tagging stack protection code. Therefore, the conditions for generating memory tagging stack protection code might not have a direct relationship to the source code.
  • When using -fsanitize=memtag, there is a high probability that an unbounded pointer access to the stack causes a processor exception. This does not guarantee that all unbounded pointer accesses to the stack cause a processor exception.
  • The [ALPHA] implementation of stack tagging does not protect variable-length allocations on the stack.

To ensure full memory tagging stack protection, you must also link your code with the library that provides stack protection with memory tagging. For more information, see --library_security=protection.

armlink automatically selects the library with memory tagging stack protection if at least one object file is compiled with -fsanitize=memtag and at least one object file is compiled with pointer authentication, using -mbranch-protection. You can override the selected library by using the armlink --library_security option to specify the library that you want to use.


  • Use of -fsanitize=memtag to protect the stack increases the amount of memory that is allocated on the stack. This is because, the compiler has to allocate a separate 16-byte aligned block of memory on the stack for each variable whose stack allocation is protected by memory tagging.
  • Code that is compiled with stack tagging can be safely linked together with code that is compiled without stack tagging. However, if any object file is compiled with -fsanitize=memtag, and if setjmp, longjmp, or C++ exceptions are present anywhere in the image, then you must use the v8.5a library to avoid stack tagging related memory fault at runtime.
  • The -fsanitize=memtag option and the -fstack-protector options are independent and provide complementary stack protection. These options can be used together or in isolation.


The following example demonstrates the effect of the -fsanitize=memtag option.

Source file foo.c contains the following code:

extern void func2 (int* a);

void func1(void)
  int x=10;
  int y=20;


Compile foo.c, without memory tagging stack protection, using the following command line:

armclang --target=aarch64-arm-none-eabi -march=armv8.5-a+memtag -S -O1 foo.c -o mem_no_protect.s

The generated assembly file mem_no_protect.s contains the following code:

func1:                                  // @func1
// %bb.0:                               // %entry
        str     x30, [sp, #-16]!        // 8-byte Folded Spill
        mov     w8, #10
        mov     w9, #20
        add     x0, sp, #12             // =12
        stp     w9, w8, [sp, #8]
        bl      func2
        add     x0, sp, #8              // =8
        bl      func2
        ldr     x30, [sp], #16          // 8-byte Folded Reload

Compile foo.c, with memory tagging stack protection, using the following command line:

armclang --target=aarch64-arm-none-eabi -march=armv8.5-a+memtag -S -O1 foo.c -fsanitize=memtag -o mem_with_protect.s

The generated assembly file mem_with_protect.s contains the following code:

func1:                                  // @func1
// %bb.0:                               // %entry
        stp     x19, x30, [sp, #-16]!   // 16-byte Folded Spill
        sub     sp, sp, #32             // =32
        irg     x0, sp
        mov     w8, #10
        mov     w9, #20
        addg    x19, x0, #16, #1
        stg     x0, [x0]
        str     w8, [sp]
        stg     x19, [x19]
        str     w9, [sp, #16]
        bl      func2
        mov     x0, x19
        bl      func2
        add     x8, sp, xzr
        st2g    x8, [sp], #32
        ldp     x19, x30, [sp], #16     // 16-byte Folded Reload

When using the -fsanitize=memtag option: