diff options
Diffstat (limited to 'gcc/cp/search.c')
-rw-r--r-- | gcc/cp/search.c | 22 |
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)) |