/* Don't inherit this tag multiple times. */
IDENTIFIER_MARKED (id) = true;
+ ABI_TAG_INHERITED (p->tags) = true;
if (TYPE_P (p->t))
{
/* Tags inherited from type template arguments are only used
to avoid warnings. */
- ABI_TAG_IMPLICIT (p->tags) = true;
+ ABI_TAG_NOT_MANGLED (p->tags) = true;
return;
}
/* For functions and variables we want to warn, too. */
TARGET_EXPR_IMPLICIT_P (in TARGET_EXPR)
TEMPLATE_PARM_PARAMETER_PACK (in TEMPLATE_PARM_INDEX)
ATTR_IS_DEPENDENT (in the TREE_LIST for an attribute)
- ABI_TAG_IMPLICIT (in the TREE_LIST for the argument of abi_tag)
+ ABI_TAG_NOT_MANGLED (in the TREE_LIST for the argument of abi_tag)
LAMBDA_CAPTURE_EXPLICIT_P (in a TREE_LIST in LAMBDA_EXPR_CAPTURE_LIST)
PARENTHESIZED_LIST_P (in the TREE_LIST for a parameter-declaration-list)
CONSTRUCTOR_IS_DIRECT_INIT (in CONSTRUCTOR)
BASELINK_FUNCTIONS_MAYBE_INCOMPLETE_P (in BASELINK)
BIND_EXPR_VEC_DTOR (in BIND_EXPR)
ATOMIC_CONSTR_EXPR_FROM_CONCEPT_P (in ATOMIC_CONSTR)
+ ABI_TAG_INHERITED (in the TREE_LIST for the argument of abi_tag)
STATIC_INIT_DECOMP_BASE_P (in the TREE_LIST for {static,tls}_aggregates)
MUST_NOT_THROW_THROW_P (in MUST_NOT_THROW_EXPR)
LAMBDA_EXPR_CONST_QUAL_P (in LAMBDA_EXPR)
#define ATTR_IS_DEPENDENT(NODE) TREE_LANG_FLAG_0 (TREE_LIST_CHECK (NODE))
/* In a TREE_LIST in the argument of attribute abi_tag, indicates that the tag
- was inherited from a template parameter, not explicitly indicated. */
-#define ABI_TAG_IMPLICIT(NODE) TREE_LANG_FLAG_0 (TREE_LIST_CHECK (NODE))
+ was inherited from a template parameter, not explicitly indicated.
+ These are not mangled because they're already represented in the mangling
+ of the template argument. */
+#define ABI_TAG_NOT_MANGLED(NODE) TREE_LANG_FLAG_0 (TREE_LIST_CHECK (NODE))
+
+/* In a TREE_LIST in the argument of attribute abi_tag, indicates that the tag
+ * was added by check_abi_tags, not explicitly specified. */
+#define ABI_TAG_INHERITED(NODE) TREE_LANG_FLAG_1 (TREE_LIST_CHECK (NODE))
/* In a TREE_LIST for a parameter-declaration-list, indicates that all the
parameters in the list have declarators enclosed in (). */
extern int mangle_module_component (tree id, bool partition);
extern tree mangle_module_global_init (int);
extern unsigned HOST_WIDE_INT range_expr_nelts (tree);
-extern bool equal_abi_tags (tree, tree);
+extern bool equal_abi_tags (tree, tree, bool);
/* in dump.cc */
extern bool cp_dump_tree (void *, tree);
if (!G.need_abi_warning
&& abi_warn_or_compat_version_crosses (11)
- && !equal_abi_tags (dtags, mtags))
+ && !equal_abi_tags (dtags, mtags, /*ignore_inherited_p=*/false))
G.need_abi_warning = 1;
if (!abi_version_at_least (10))
/* Return the TREE_LIST of TAGS as a sorted VEC. */
static vec<tree, va_gc> *
-sorted_abi_tags (tree tags)
+sorted_abi_tags (tree tags, bool ignore_inherited_p)
{
vec<tree, va_gc> * vec = make_tree_vector();
for (tree t = tags; t; t = TREE_CHAIN (t))
{
- if (ABI_TAG_IMPLICIT (t))
+ if (ABI_TAG_NOT_MANGLED (t)
+ || (ignore_inherited_p && ABI_TAG_INHERITED (t)))
continue;
tree str = TREE_VALUE (t);
vec_safe_push (vec, str);
if (tags == NULL_TREE)
return;
- vec<tree, va_gc> * vec = sorted_abi_tags (tags);
+ vec<tree, va_gc> * vec = sorted_abi_tags (tags, /*ignore_inherited_p=*/false);
unsigned i; tree str;
FOR_EACH_VEC_ELT (*vec, i, str)
/* True iff the TREE_LISTS T1 and T2 of ABI tags are equivalent. */
bool
-equal_abi_tags (tree t1, tree t2)
+equal_abi_tags (tree t1, tree t2, bool ignore_inherited_p)
{
- releasing_vec v1 = sorted_abi_tags (t1);
- releasing_vec v2 = sorted_abi_tags (t2);
+ releasing_vec v1 = sorted_abi_tags (t1, ignore_inherited_p);
+ releasing_vec v2 = sorted_abi_tags (t2, ignore_inherited_p);
unsigned len1 = v1->length();
if (len1 != v2->length())
if (dtags)
dtags = TREE_VALUE (dtags);
- /* We only error if mangling wouldn't consider the tags equivalent. */
- if (!equal_abi_tags (etags, dtags))
+ /* We only error if mangling wouldn't consider the tags equivalent.
+ Since tags might have been inherited during mangling, ignore
+ inherited tags if there's a mangled-ness mismatch. */
+ bool ignore_inherited_p
+ = (DECL_ASSEMBLER_NAME_SET_P (STRIP_TEMPLATE (existing))
+ != DECL_ASSEMBLER_NAME_SET_P (STRIP_TEMPLATE (decl)));
+ if (!equal_abi_tags (etags, dtags, ignore_inherited_p))
{
auto_diagnostic_group d;
if (dtags)
--- /dev/null
+// PR c++/124957
+// { dg-do compile { target c++17 } }
+// { dg-additional-options "-fmodules" }
+
+export module mod:partition;
+
+int dummy;
+struct [[gnu::abi_tag("cxx11")]] A { int m; };
+export inline int A::*x = &A::m;
+// x does not get mangled in this TU => cxx11 abi_tag not propagated to x
--- /dev/null
+// PR c++/124957
+// { dg-do compile { target c++17 } }
+// { dg-additional-options "-fmodules" }
+
+export module mod; // { dg-module-cmi "mod" }
+export import :partition;
+
+// x gets mangled in this TU => cxx11 abi_tag propagated to x
--- /dev/null
+// PR c++/124957
+// { dg-do compile { target c++17 } }
+// { dg-additional-options "-fmodules -fno-module-lazy" }
+
+module mod;
+import :partition;
+
+// OK, no bogus abi_tag mismatch error for the imported x's