On Tue, 22 Jul 2014, Alexander Monakov wrote:
> I'd like to push this topic forward a bit.  I've bootstrapped and regtested a
> version of the patch based on the initial proposal to check DECL_WEAK.  The
> approach with decl_replaceable_p looks not that easy; I'll expand in a
> followup email.

The problem with the patch below using decl_replaceable_p is that it regresses
the following C++ testcase:

struct z {
  static const int aaa = 1;
};

//const int z::aaa;

int foo(int x)
{
  return x ? z::aaa : x;
}

Here decl_replaceable_p is 'true' for z::aaa.  With the patch the reference to
z::aaa is not folded, but its definition is not emitted either, so a undefined
reference error is produced at link time.  But naturally
varpool_ctor_useable_for_folding_p for z::aaa must stay true in the first place.

In a way z::aaa is "replaceable" in the sense that the compiler is not going
to emit a definition, so if anything references z::aaa in the current
translation unit (if the address is taken), the definition must come from
another TU.  Nevertheless, references to the value can be folded.  I'm
unsure what the correct test would look like.  Any advice?

Thanks.
Alexander

diff --git a/gcc/varpool.c b/gcc/varpool.c
index b98fc1b..addbe6d 100644
--- a/gcc/varpool.c
+++ b/gcc/varpool.c
@@ -329,11 +329,13 @@ varpool_ctor_useable_for_folding_p (varpool_node *node)
   if (!TREE_READONLY (node->decl) && !TREE_READONLY (real_node->decl))
     return false;
 
-  /* Variables declared 'const' without an initializer
-     have zero as the initializer if they may not be
-     overridden at link or run time.  */
-  if (!DECL_INITIAL (real_node->decl)
-      && (DECL_EXTERNAL (node->decl) || decl_replaceable_p (node->decl)))
+  /* Accept variables declared 'const' without an initializer (so they have
+     zero as the initializer), unless they may be overridden at link time.  */
+  if (!DECL_INITIAL (real_node->decl) && DECL_EXTERNAL (node->decl))
+    return false;
+
+  /* Reject initializers that can be overridden at link or run time.  */
+  if (decl_replaceable_p (node->decl))
     return false;
 
   /* Variables declared `const' with an initializer are considered

Reply via email to