https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128387
Bug ID: 128387
Summary: i386: conflicting cf_check and nocf_check attributes
on the same function accepted without warning and drop
ENDBR
Product: gcc
Version: 16.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: 220245569 at seu dot edu.cn
CC: 220255623 at seu dot edu.cn, jianhao.xu at seu dot edu.cn
Target Milestone: ---
Target: x86_64-*-* i?86-*-*
Reproducer
----------
$ cat trigger.c
__attribute__((cf_check))
int __attribute__((nocf_check))
conflicting_attrs (int x)
{
__asm__ volatile ("" : "+r" (x));
return x + 1;
}
__attribute__((cf_check))
int control_cf_check (int x)
{
__asm__ volatile ("" : "+r" (x));
return x + 2;
}
Compile flag: x86_64-linux-gnu-gcc -O2 -fcf-protection=branch -mmanual-endbr
-Wall -Wextra -S trigger.c
conflicting_attrs:
.LFB0:
.cfi_startproc
leal 1(%rdi), %eax # no warning emitted; endbr64 dropped
ret
.cfi_endproc
control_cf_check:
.LFB1:
.cfi_startproc
endbr64
leal 2(%rdi), %eax
ret
.cfi_endproc
Root cause
----------
cf_check and nocf_check have opposite meanings, but cf_check is registered on
DECL_ATTRIBUTES (decl_required = true in ix86_gnu_attributes,
gcc/config/i386/i386-options.cc:4213) while nocf_check is registered on
TYPE_ATTRIBUTES (type_required = true in c_common_attribute_table,
gcc/c-family/c-attribs.cc:634). Neither attribute handler checks the other
list, so applying both to the same function emits no -Wattributes diagnostic
and rest_of_insert_endbr_and_patchable_area (i386-features.cc:3014) drops
endbr64.
Suggested Fix
-------------
Diagnose the conflict between cf_check on DECL_ATTRIBUTES (decl) and
nocf_check on TYPE_ATTRIBUTES (TREE_TYPE (decl)) with a -Wattributes warning.