https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96984
Bug ID: 96984 Summary: bogus -Warray-bounds with -fsanitize due to FRE substituting subobjects at the same address Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- The following test case (originally reported in https://bugzilla.redhat.com/show_bug.cgi?id=1876801) shows another false positive warning due to FRE indiscriminately substituting subobjects at the same address for one another. $ cat rhbz1876801.c && gcc -O2 -S -Wall -Warray-bounds=2 -fsanitize=undefined -fdump-tree-fre3=/dev/stdout rhbz1876801.c typedef enum { GNUTLS_PK_UNKNOWN = 0, } gnutls_pk_algorithm_t; typedef enum { GNUTLS_DIG_UNKNOWN = 0, } gnutls_digest_algorithm_t; typedef struct gnutls_x509_spki_st { gnutls_pk_algorithm_t pk; gnutls_digest_algorithm_t rsa_pss_dig; unsigned int salt_size; unsigned int legacy; gnutls_digest_algorithm_t dsa_dig; } gnutls_x509_spki_st; typedef struct gnutls_x509_spki_st *gnutls_x509_spki_t; typedef struct { gnutls_x509_spki_st spki; } gnutls_pk_params_st; typedef struct gnutls_x509_privkey_int { gnutls_pk_params_st params; } *gnutls_x509_privkey_t; typedef struct gnutls_privkey_st { gnutls_x509_privkey_t x509; } *gnutls_privkey_t; int gnutls_privkey_get_spki(gnutls_privkey_t privkey, gnutls_x509_spki_t spki, unsigned int flags) { if (privkey->x509->params.spki.pk == GNUTLS_PK_UNKNOWN) return -1; __builtin_memcpy(spki, &privkey->x509->params.spki, sizeof(gnutls_x509_spki_st)); return 0; } ;; Function gnutls_privkey_get_spki (gnutls_privkey_get_spki, funcdef_no=0, decl_uid=2315, cgraph_uid=1, symbol_order=0) ;; 1 loops found ;; ;; Loop 0 ;; header 0, latch 1 ;; depth 0, outer -1 ;; nodes: 0 1 2 3 4 5 6 7 8 ;; 2 succs { 8 3 } ;; 3 succs { 5 4 } ;; 4 succs { 5 } ;; 5 succs { 7 6 } ;; 6 succs { 7 } ;; 7 succs { 8 } ;; 8 succs { 1 } gnutls_privkey_get_spki (struct gnutls_privkey_st * privkey, struct gnutls_x509_spki_st * spki, unsigned int flags) { struct gnutls_x509_privkey_int * _1; <unnamed type> _2; int _4; long unsigned int _10; struct gnutls_x509_privkey_int * * _11; long unsigned int _12; gnutls_pk_algorithm_t * _13; <bb 2> [local count: 1073741824]: .UBSAN_NULL (privkey_7(D), 3B, 8); _10 = __builtin_object_size (privkey_7(D), 0); _11 = &privkey_7(D)->x509; GIMPLE_NOP _1 = privkey_7(D)->x509; .UBSAN_NULL (_1, 3B, 4); _12 = __builtin_object_size (_1, 0); _13 = &_1->params.spki.pk; GIMPLE_NOP _2 = _1->params.spki.pk; if (_2 == 0) goto <bb 8>; [1.04%] else goto <bb 3>; [98.96%] <bb 3> [local count: 1062574913]: .UBSAN_NULL (privkey_7(D), 3B, 8); GIMPLE_NOP .UBSAN_NULL (_1, 3B, 4); if (spki_8(D) == 0B) goto <bb 4>; [0.00%] else goto <bb 5>; [100.00%] <bb 4> [count: 0]: __builtin___ubsan_handle_nonnull_arg (&*.Lubsan_data0); <bb 5> [local count: 1062574913]: if (_13 == 0B) goto <bb 6>; [0.00%] else goto <bb 7>; [100.00%] <bb 6> [count: 0]: __builtin___ubsan_handle_nonnull_arg (&*.Lubsan_data1); <bb 7> [local count: 1062574913]: __builtin_memcpy (spki_8(D), _13, 20); <bb 8> [local count: 1073741824]: # _4 = PHI <-1(2), 0(7)> return _4; } rhbz1876801.c: In function ‘gnutls_privkey_get_spki’: rhbz1876801.c:37:2: warning: ‘__builtin_memcpy’ offset [4, 19] from the object at ‘<unknown>’ is out of the bounds of referenced subobject ‘pk’ with type ‘enum <anonymous>’ at offset 0 [-Warray-bounds] 37 | __builtin_memcpy(spki, &privkey->x509->params.spki, sizeof(gnutls_x509_spki_st)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ rhbz1876801.c:10:24: note: subobject ‘pk’ declared here 10 | gnutls_pk_algorithm_t pk; | ^~