Tested x86_64-pc-linux-gnu, applying to trunk.
-- 8< --
Since r16-6477 we allow a gnu_inline to be a key method, because it is only
emitted in one place. It occurs to me that we should make the same
adjustment to other places that check DECL_DECLARED_INLINE_P to decide if a
function has inline/vague/comdat linkage.
PR libstdc++/123326
gcc/cp/ChangeLog:
* cp-tree.h (DECL_NONGNU_INLINE_P): New.
* decl.cc (duplicate_decls, start_decl): Check it.
* decl2.cc (vague_linkage_p, import_export_class): Likewise.
(vtables_uniquely_emitted, import_export_decl): Likewise.
* class.cc (determine_key_method): Check it instead of
lookup_attribute.
---
gcc/cp/cp-tree.h | 6 ++++++
gcc/cp/class.cc | 11 +++++------
gcc/cp/decl.cc | 4 ++--
gcc/cp/decl2.cc | 8 ++++----
4 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b8470fc256c..1a58ea0562a 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3848,6 +3848,12 @@ struct GTY(()) lang_decl {
#define DECL_PENDING_INLINE_INFO(NODE) \
(LANG_DECL_FN_CHECK (NODE)->u.pending_inline_info)
+/* True if NODE is a non-gnu_inline inline function; gnu_inline overrides the
+ usual vague linkage effects of inline. */
+#define DECL_NONGNU_INLINE_P(NODE) \
+ (DECL_DECLARED_INLINE_P (NODE) \
+ && !lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (NODE)))
+
/* Nonzero for TYPE_DECL means that it was written 'using name = type'. */
#define TYPE_DECL_ALIAS_P(NODE) \
DECL_LANG_FLAG_6 (TYPE_DECL_CHECK (NODE))
diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index a6a7c88c3dd..adffd35123c 100644
--- a/gcc/cp/class.cc
+++ b/gcc/cp/class.cc
@@ -7472,12 +7472,11 @@ determine_key_method (tree type)
for (method = TYPE_FIELDS (type); method; method = DECL_CHAIN (method))
if (TREE_CODE (method) == FUNCTION_DECL
&& DECL_VINDEX (method) != NULL_TREE
- && (! DECL_DECLARED_INLINE_P (method)
- /* [[gnu::gnu_inline]] virtual inline/constexpr methods will
- have out of line bodies emitted in some other TU and so
- those can be key methods and vtable emitted in the TU with
- the actual out of line definition. */
- || lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (method)))
+ /* [[gnu::gnu_inline]] virtual inline/constexpr methods will
+ have out of line bodies emitted in some other TU and so
+ those can be key methods and vtable emitted in the TU with
+ the actual out of line definition. */
+ && ! DECL_NONGNU_INLINE_P (method)
&& ! DECL_PURE_VIRTUAL_P (method))
{
SET_CLASSTYPE_KEY_METHOD (type, method);
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index a2a14c4c008..567aa7abe42 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -3087,7 +3087,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding,
bool was_hidden)
SET_DECL_TEMPLATE_SPECIALIZATION (olddecl);
DECL_COMDAT (newdecl) = (TREE_PUBLIC (newdecl)
- && DECL_DECLARED_INLINE_P (newdecl));
+ && DECL_NONGNU_INLINE_P (newdecl));
/* Don't propagate visibility from the template to the
specialization here. We'll do that in determine_visibility if
@@ -6636,7 +6636,7 @@ start_decl (const cp_declarator *declarator,
SET_DECL_TEMPLATE_SPECIALIZATION (decl);
if (TREE_CODE (decl) == FUNCTION_DECL)
DECL_COMDAT (decl) = (TREE_PUBLIC (decl)
- && DECL_DECLARED_INLINE_P (decl));
+ && DECL_NONGNU_INLINE_P (decl));
else
DECL_COMDAT (decl) = false;
diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index e807eab1b8a..af2b921268d 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -2511,7 +2511,7 @@ vague_linkage_p (tree decl)
DECL_COMDAT. */
if (DECL_COMDAT (decl)
|| (TREE_CODE (decl) == FUNCTION_DECL
- && DECL_DECLARED_INLINE_P (decl))
+ && DECL_NONGNU_INLINE_P (decl))
|| (DECL_LANG_SPECIFIC (decl)
&& DECL_TEMPLOID_INSTANTIATION (decl))
|| (VAR_P (decl) && DECL_INLINE_VAR_P (decl)))
@@ -2581,7 +2581,7 @@ import_export_class (tree ctype)
translation units. If we were to emit the vtable in each
translation unit containing a definition, we would get
multiple definition errors at link-time. */
- if (method && (flag_weak || ! DECL_DECLARED_INLINE_P (method)))
+ if (method && (flag_weak || ! DECL_NONGNU_INLINE_P (method)))
import_export = (DECL_REALLY_EXTERN (method) ? -1 : 1);
}
}
@@ -3532,7 +3532,7 @@ vtables_uniquely_emitted (tree ctype)
object for the TU containing the definition of the key function. This is
unique if the key function is not inline. */
tree key_method = CLASSTYPE_KEY_METHOD (ctype);
- if (key_method && !DECL_DECLARED_INLINE_P (key_method))
+ if (key_method && !DECL_NONGNU_INLINE_P (key_method))
return true;
/* Otherwise, the tables are emitted in every object that references
@@ -3730,7 +3730,7 @@ import_export_decl (tree decl)
}
else if (TREE_CODE (decl) == FUNCTION_DECL && DECL_FUNCTION_MEMBER_P (decl))
{
- if (!DECL_DECLARED_INLINE_P (decl))
+ if (!DECL_NONGNU_INLINE_P (decl))
{
tree ctype = DECL_CONTEXT (decl);
import_export_class (ctype);
base-commit: 0c775dcf3e78148204b78022dfd3de4a0833f496
--
2.52.0