https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97273
Patrick Palka <ppalka at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |ppalka at gcc dot gnu.org --- Comment #2 from Patrick Palka <ppalka at gcc dot gnu.org> --- It looks like the bug is that cp_tree_equal considers __alignof__(FOO) the same as alignof(FOO), but they have different semantics ever since the fix for PR69650. This manifests here because when <vector> is included before <unordered_set>, the specialization cache conflates the dependent specialization aligned_storage<sizeof(_Tp), alignof(_Tp)> used in include/bits/stl_vector.h:1726 with the later dependent specialization aligned_storage<sizeof(_Tp), __alignof__(_Tp)> used in include/ext/aligned_buffer.h:91. We later instantiate the latter type with _Tp=uint64_t as part of the implementation of unordered_set<uint64_t>, but 4 == alignof(uint64_t) != __alignof__(uint64_t) == 8 on x86 so our assumptions about the alignment of the type become incoherent. I think PR88115 reports the same issue. The following patch to cp_tree_equal seems to fix it: gcc/cp/tree.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 8b7c6798ee9..8ed9eed1ea5 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -3787,8 +3787,11 @@ cp_tree_equal (tree t1, tree t2) return true; } - case SIZEOF_EXPR: case ALIGNOF_EXPR: + if (ALIGNOF_EXPR_STD_P (t1) != ALIGNOF_EXPR_STD_P (t2)) + return false; + /* Fall through. */ + case SIZEOF_EXPR: { tree o1 = TREE_OPERAND (t1, 0); tree o2 = TREE_OPERAND (t2, 0);