https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104016
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- I bet it is /* If both symbols may resolve to NULL, we cannot really prove them different. */ if (!memory_accessed && !nonzero_address () && !s2->nonzero_address ()) return -1; which is done before: /* If the FE tells us at least one of the decls will never be aliased nor overlapping with other vars in some other way, return 0. */ if (VAR_P (decl) && (lookup_attribute ("non overlapping", DECL_ATTRIBUTES (decl)) || lookup_attribute ("non overlapping", DECL_ATTRIBUTES (s2->decl)))) return 0; Currently "non overlapping" attribute is used solely for typeinfo and we know it doesn't have aliases etc., so for typeinfo we could fix that by moving the "non overlapping" check above the above one. But for the folding_initializer case we have later we should do something different. For addresses of extern weak vars surely they both can resolve to NULL and the above makes a lot of sense, but for e.g. two vars defined somewhere they still shouldn't overlap even if one of them could be at address zero.