c++: Incorrect type equivalence [PR 99496]
This bug was caused by not marking dependent template aliases correctly -- these things look like typedefs, but are not (necessarily) equivalent to the canonical type. We need to record that. PR c++/99496 gcc/cp/ * module.cc (trees_out::decl_value): Adjust typedef streaming, indicate whether it is a dependent alias. (trees_in::decl_value): Likewise. Set as dependent alias, if it is one. gcc/testsuite/ * g++.dg/modules/pr99496_a.H: New. * g++.dg/modules/pr99496_b.C: New.
This commit is contained in:
parent
3c5b6d24e6
commit
7b900dca60
@ -7719,18 +7719,35 @@ trees_out::decl_value (tree decl, depset *dep)
|
||||
}
|
||||
}
|
||||
|
||||
bool is_typedef = (!type && inner
|
||||
&& TREE_CODE (inner) == TYPE_DECL
|
||||
&& DECL_ORIGINAL_TYPE (inner)
|
||||
&& TYPE_NAME (TREE_TYPE (inner)) == inner);
|
||||
if (is_typedef)
|
||||
bool is_typedef = false;
|
||||
if (!type && inner && TREE_CODE (inner) == TYPE_DECL)
|
||||
{
|
||||
/* A typedef type. */
|
||||
int type_tag = insert (TREE_TYPE (inner));
|
||||
tree t = TREE_TYPE (inner);
|
||||
unsigned tdef_flags = 0;
|
||||
if (DECL_ORIGINAL_TYPE (inner)
|
||||
&& TYPE_NAME (TREE_TYPE (inner)) == inner)
|
||||
{
|
||||
tdef_flags |= 1;
|
||||
if (TYPE_STRUCTURAL_EQUALITY_P (t)
|
||||
&& TYPE_DEPENDENT_P_VALID (t)
|
||||
&& TYPE_DEPENDENT_P (t))
|
||||
tdef_flags |= 2;
|
||||
}
|
||||
if (streaming_p ())
|
||||
dump (dumper::TREE)
|
||||
&& dump ("Cloned:%d typedef %C:%N", type_tag,
|
||||
TREE_CODE (TREE_TYPE (inner)), TREE_TYPE (inner));
|
||||
u (tdef_flags);
|
||||
|
||||
if (tdef_flags & 1)
|
||||
{
|
||||
/* A typedef type. */
|
||||
int type_tag = insert (t);
|
||||
if (streaming_p ())
|
||||
dump (dumper::TREE)
|
||||
&& dump ("Cloned:%d %s %C:%N", type_tag,
|
||||
tdef_flags & 2 ? "depalias" : "typedef",
|
||||
TREE_CODE (t), t);
|
||||
|
||||
is_typedef = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (streaming_p () && DECL_MAYBE_IN_CHARGE_CDTOR_P (decl))
|
||||
@ -7993,12 +8010,6 @@ trees_in::decl_value ()
|
||||
|
||||
dump (dumper::TREE) && dump ("Read:%d %C:%N", tag, TREE_CODE (decl), decl);
|
||||
|
||||
/* Regular typedefs will have a NULL TREE_TYPE at this point. */
|
||||
bool is_typedef = (!type && inner
|
||||
&& TREE_CODE (inner) == TYPE_DECL
|
||||
&& DECL_ORIGINAL_TYPE (inner)
|
||||
&& !TREE_TYPE (inner));
|
||||
|
||||
existing = back_refs[~tag];
|
||||
bool installed = install_entity (existing);
|
||||
bool is_new = existing == decl;
|
||||
@ -8030,6 +8041,16 @@ trees_in::decl_value ()
|
||||
}
|
||||
}
|
||||
|
||||
/* Regular typedefs will have a NULL TREE_TYPE at this point. */
|
||||
unsigned tdef_flags = 0;
|
||||
bool is_typedef = false;
|
||||
if (!type && inner && TREE_CODE (inner) == TYPE_DECL)
|
||||
{
|
||||
tdef_flags = u ();
|
||||
if (tdef_flags & 1)
|
||||
is_typedef = true;
|
||||
}
|
||||
|
||||
if (is_new)
|
||||
{
|
||||
/* A newly discovered node. */
|
||||
@ -8076,6 +8097,14 @@ trees_in::decl_value ()
|
||||
TREE_TYPE (inner) = DECL_ORIGINAL_TYPE (inner);
|
||||
DECL_ORIGINAL_TYPE (inner) = NULL_TREE;
|
||||
set_underlying_type (inner);
|
||||
if (tdef_flags & 2)
|
||||
{
|
||||
/* Match instantiate_alias_template's handling. */
|
||||
tree type = TREE_TYPE (inner);
|
||||
TYPE_DEPENDENT_P (type) = true;
|
||||
TYPE_DEPENDENT_P_VALID (type) = true;
|
||||
SET_TYPE_STRUCTURAL_EQUALITY (type);
|
||||
}
|
||||
}
|
||||
|
||||
if (inner_tag)
|
||||
@ -10661,6 +10690,9 @@ trees_in::key_mergeable (int tag, merge_kind mk, tree decl, tree inner,
|
||||
spec.tmpl = tree_node ();
|
||||
spec.args = tree_node ();
|
||||
|
||||
if (get_overrun ())
|
||||
return error_mark_node;
|
||||
|
||||
DECL_NAME (decl) = DECL_NAME (spec.tmpl);
|
||||
DECL_CONTEXT (decl) = DECL_CONTEXT (spec.tmpl);
|
||||
DECL_NAME (inner) = DECL_NAME (decl);
|
||||
|
||||
17
gcc/testsuite/g++.dg/modules/pr99496_a.H
Normal file
17
gcc/testsuite/g++.dg/modules/pr99496_a.H
Normal file
@ -0,0 +1,17 @@
|
||||
// PR 99496 different types with same canonical
|
||||
// (requires spec hasher to be a constant, so we get collisions)
|
||||
// { dg-additional-options -fmodule-header }
|
||||
// { dg-module-cmi {} }
|
||||
|
||||
template<typename...> using __void_t = void;
|
||||
|
||||
template<typename _Tp, typename = void>
|
||||
struct __is_referenceable
|
||||
{ };
|
||||
|
||||
template<typename _Tp>
|
||||
struct __is_referenceable<_Tp, __void_t<_Tp&>>
|
||||
{ };
|
||||
|
||||
template<typename _Tp, bool = __is_referenceable<_Tp>::value>
|
||||
struct __is_copy_constructible_impl;
|
||||
3
gcc/testsuite/g++.dg/modules/pr99496_b.C
Normal file
3
gcc/testsuite/g++.dg/modules/pr99496_b.C
Normal file
@ -0,0 +1,3 @@
|
||||
// { dg-additional-options {-fmodules-ts -fno-module-lazy} }
|
||||
|
||||
import "pr99496_a.H";
|
||||
Loading…
Reference in New Issue
Block a user