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);

Reply via email to