summaryrefslogtreecommitdiff
path: root/gcc/cp/search.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/search.c')
-rw-r--r--gcc/cp/search.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 42db122e98c..508e66c43bb 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -2014,8 +2014,11 @@ check_final_overrider (tree overrider, tree basefn)
return 0;
}
- /* Check for conflicting type attributes. */
- if (!comp_type_attributes (over_type, base_type))
+ /* Check for conflicting type attributes. But leave transaction_safe for
+ set_one_vmethod_tm_attributes. */
+ if (!comp_type_attributes (over_type, base_type)
+ && !tx_safe_fn_type_p (base_type)
+ && !tx_safe_fn_type_p (over_type))
{
error ("conflicting type attributes specified for %q+#D", overrider);
error (" overriding %q+#D", basefn);
@@ -2023,6 +2026,21 @@ check_final_overrider (tree overrider, tree basefn)
return 0;
}
+ /* A function declared transaction_safe_dynamic that overrides a function
+ declared transaction_safe (but not transaction_safe_dynamic) is
+ ill-formed. */
+ if (tx_safe_fn_type_p (base_type)
+ && lookup_attribute ("transaction_safe_dynamic",
+ DECL_ATTRIBUTES (overrider))
+ && !lookup_attribute ("transaction_safe_dynamic",
+ DECL_ATTRIBUTES (basefn)))
+ {
+ error_at (DECL_SOURCE_LOCATION (overrider),
+ "%qD declared %<transaction_safe_dynamic%>", overrider);
+ inform (DECL_SOURCE_LOCATION (basefn),
+ "overriding %qD declared %<transaction_safe%>", basefn);
+ }
+
if (DECL_DELETED_FN (basefn) != DECL_DELETED_FN (overrider))
{
if (DECL_DELETED_FN (overrider))