===================================================================
@@ -1236,6 +1236,16 @@ fweak
C++ ObjC++ Var(flag_weak) Init(1)
Emit common-like symbols as weak symbols
+fvague-linkage-functions
+C++ Var(flag_vague_linkage_functions) Init(1)
+Option -fno-vague-linkage-functions makes comdat functions static and local
+to the module. With -fno-vague-linkage-functions, virtual comdat functions
+still use vague linkage. With -fno-vague-linkage-functions, the address of
+the comdat functions that are made local will be unique and this can cause
+unintended behavior when addresses of these comdat functions are used in
+comparisons. This option may technically break the C++ ODR and users of
+this flag should know what they are doing.
+
fwide-exec-charset=
C ObjC C++ ObjC++ Joined RejectNegative
-fwide-exec-charset=<cset> Convert all wide strings and character constants to character set <cset>
===================================================================
@@ -1702,8 +1702,22 @@ mark_vtable_entries (tree decl)
void
comdat_linkage (tree decl)
{
- if (flag_weak
- make_decl_one_only (decl, cxx_comdat_group (decl));
+ if (flag_weak
+ && (flag_vague_linkage_functions
+ || TREE_CODE (decl) != FUNCTION_DECL
+ || DECL_VIRTUAL_P (decl)))
+ {
+ make_decl_one_only (decl, cxx_comdat_group (decl));
+ /* Warn when -fno-vague-linkage-functions is used and we found virtual
+ comdat functions. Virtual comdat functions must still use vague
+ linkage. */
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_VIRTUAL_P (decl)
+ && !flag_vague_linkage_functions)
+ warning_at (DECL_SOURCE_LOCATION (decl), 0,
+ "fno-vague-linkage-functions: Comdat linkage of virtual "
+ "function %q#D preserved.", decl);
+ }
else if (TREE_CODE (decl) == FUNCTION_DECL
|| (VAR_P (decl) && DECL_ARTIFICIAL (decl)))
/* We can just emit function and compiler-generated variables
===================================================================
@@ -189,7 +189,7 @@ in the following sections.
-fno-pretty-templates @gol
-frepo -fno-rtti -fstats -ftemplate-backtrace-limit=@var{n} @gol
-ftemplate-depth=@var{n} @gol
--fno-threadsafe-statics -fuse-cxa-atexit -fno-weak -nostdinc++ @gol
+-fno-threadsafe-statics -fuse-cxa-atexit -fno-weak -fno-vague-linkage-functions -nostdinc++ @gol
-fvisibility-inlines-hidden @gol
-fvtable-verify=@var{std|preinit|none} @gol
-fvtv-counts -fvtv-debug @gol
@@ -2448,6 +2448,18 @@ option exists only for testing, and should not be
it results in inferior code and has no benefits. This option may
be removed in a future release of G++.
+@item -fno-vague-linkage-functions
+@opindex fno-vague-linkage-functions
+Do not use vague linkage for comdat non-virtual functions, even if it
+is provided by the linker. This option is useful when comdat functions
+generated in certain compilation units need to be kept local to the
+respective units and not exposed globally. This does not apply to virtual
+comdat functions as their pointers may be taken via virtual tables.
+This can cause unintended behavior if the addresses of the comdat functions
+that are made local are used in comparisons, which are not warned about.
+This option may technically break the C++ ODR and users of this flag should
+know what they are doing.
+
@item -nostdinc++
@opindex nostdinc++
Do not search for header files in the standard directories specific to
===================================================================
@@ -1037,6 +1037,7 @@ function_and_variable_visibility (bool whole_progr
}
gcc_assert ((!DECL_WEAK (node->decl)
&& !DECL_COMDAT (node->decl))
+ || !flag_vague_linkage_functions
|| TREE_PUBLIC (node->decl)
|| node->weakref
|| DECL_EXTERNAL (node->decl));
===================================================================
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-fno-vague-linkage-functions -fkeep-inline-functions -ffunction-sections" } */
+
+inline int foo () {
+ return 0;
+}
+
+/* { dg-final { scan-assembler "_Z3foov" } } */
+/* { dg-final { scan-assembler-not "_Z3foov.*comdat" } } */