Bug 55434 - const array with elements initialized by constructor marked non-const in debug info
Summary: const array with elements initialized by constructor marked non-const in debu...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.7.3
: P3 minor
Target Milestone: 5.0
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-debug
Depends on:
Blocks:
 
Reported: 2012-11-22 00:33 UTC by Louis Krupp
Modified: 2016-06-05 07:56 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-08-07 00:00:00


Attachments
C++ source file (108 bytes, text/x-c++src)
2012-11-22 00:33 UTC, Louis Krupp
Details
Proposed patch (759 bytes, patch)
2012-11-22 00:37 UTC, Louis Krupp
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Louis Krupp 2012-11-22 00:33:00 UTC
Created attachment 28758 [details]
C++ source file

In this code:

struct s
{
    int i1, i2;
};

const s c1 = { 1, 2 };
const s ca1[] = { { 1, 2} };
const s c2 = c1;
const s ca2[] = { c1 };

int main(void)
{
    return 0;
}


gdb sees all variables as const except for ca2:

(gdb) ptype ca1
type = const struct s {
    int i1;
    int i2;
} [1]
(gdb) ptype ca2
type = struct s {
    int i1;
    int i2;
} [1]

The problem seems to be in split_nonconstant_init() in cp/typeck2.c;  when TREE_READONLY (dest) is set to zero, the information that it was ever read-only is lost before the DWARF record is written.

The following patch seems to fix the problem.  I would not be surprised if there were a more elegant way of doing this.

(You might be wondering:  How did I find this, and why do I care?  I've been working on something to read object files and then flag variables that raise thread-safety issues because they are (1) global or static and (2) not const.  Reading DWARF records works really well, except for this particular problem.)

Index: gcc/cp/typeck2.c
===================================================================
--- gcc/cp/typeck2.c	(revision 193640)
+++ gcc/cp/typeck2.c	(working copy)
@@ -633,6 +633,7 @@
 	init = NULL_TREE;
       code = pop_stmt_list (code);
       DECL_INITIAL (dest) = init;
+      TREE_WASREADONLY (dest) = TREE_READONLY (dest);
       TREE_READONLY (dest) = 0;
     }
   else
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	(revision 193640)
+++ gcc/dwarf2out.c	(working copy)
@@ -18031,7 +18031,9 @@
       if (decl_by_reference_p (decl_or_origin))
 	add_type_attribute (var_die, TREE_TYPE (type), 0, 0, context_die);
       else
-	add_type_attribute (var_die, type, TREE_READONLY (decl_or_origin),
+	add_type_attribute (var_die, type,
+                        TREE_READONLY (decl_or_origin) ||
+                        TREE_WASREADONLY (decl_or_origin),
 			    TREE_THIS_VOLATILE (decl_or_origin), context_die);
     }
 
Index: gcc/tree.h
===================================================================
--- gcc/tree.h	(revision 193640)
+++ gcc/tree.h	(working copy)
@@ -464,8 +464,9 @@
   unsigned packed_flag : 1;
   unsigned user_align : 1;
   unsigned nameless_flag : 1;
+  unsigned wasreadonly_flag : 1;
 
-  unsigned spare : 12;
+  unsigned spare : 11;
 
   /* This field is only used with type nodes; the only reason it is present
      in tree_base instead of tree_type is to save space.  The size of the
@@ -1344,6 +1345,7 @@
    Nonzero in a FUNCTION_DECL means this function should be treated
    as "const" function (can only read its arguments).  */
 #define TREE_READONLY(NODE) (NON_TYPE_CHECK (NODE)->base.readonly_flag)
+#define TREE_WASREADONLY(NODE) (NON_TYPE_CHECK (NODE)->base.wasreadonly_flag)
 
 /* Value of expression is constant.  Always on in all ..._CST nodes.  May
    also appear in an expression or decl where the value is constant.  */
Comment 1 Louis Krupp 2012-11-22 00:37:04 UTC
Created attachment 28759 [details]
Proposed patch

I wouldn't describe this as elegant, but it seems to work.
Comment 2 Louis Krupp 2012-11-22 00:40:49 UTC
g++ -v output from a version known to have this problem:

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.7.2/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --disable-build-with-cxx --disable-build-poststage1-with-cxx --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.7.2 20120921 (Red Hat 4.7.2-2) (GCC)
Comment 3 Paolo Carlini 2012-11-22 09:57:02 UTC
Note that in any case patches should be posted to gcc-patches.
Comment 4 Paolo Carlini 2013-08-07 23:57:17 UTC
With C++11 constexpr things are fine. I think this is an indication that before fiddling with dwarf2out we should make sure const is handled like constexpr, in C++98 mode too, for this testcase, thus ca2 is "r". ICC, for example, does that.
Comment 5 Paolo Carlini 2016-06-05 07:56:29 UTC
Fixed in 5.1.0.