Bug 30757 - [gdb/build] ODR violations in opcodes dir
Summary: [gdb/build] ODR violations in opcodes dir
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: build (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: 14.1
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks: 22395
  Show dependency treegraph
 
Reported: 2023-08-14 15:44 UTC by Tom de Vries
Modified: 2023-08-22 17:36 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tom de Vries 2023-08-14 15:44:53 UTC
When building gdb with -O2 -flto -Wall, I run into a cluster of odr violations in dir opcodes:
...
/labs/tdevries/gdb/src/gdb/../opcodes/mep-desc.h:250:14: warning: type 'cgen_operand_type' violates the C++ One Definition Rule [-Wodr]
 typedef enum cgen_operand_type {
              ^
/labs/tdevries/gdb/src/gdb/../opcodes/or1k-desc.h:624:14: note: an enum with different value name is defined in another translation unit
 typedef enum cgen_operand_type {
              ^
/labs/tdevries/gdb/src/gdb/../opcodes/mep-desc.h:212:14: warning: type 'cgen_hw_type' violates the C++ One Definition Rule [-Wodr]
 typedef enum cgen_hw_type {
              ^
/labs/tdevries/gdb/src/gdb/../opcodes/or1k-desc.h:433:14: note: an enum with different value name is defined in another translation unit
 typedef enum cgen_hw_type {
              ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:778:3: warning: type 'struct CGEN_OPINST' violates the C++ One Definition Rule [-Wodr]
 } CGEN_OPINST;
   ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:778:3: note: a different type is defined in another translation unit
 } CGEN_OPINST;
   ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:754:21: note: the first difference of corresponding definitions is field 'hw_type'
   enum cgen_hw_type hw_type;
                     ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:754:21: note: a field of same name but different type is defined in another translation unit
   enum cgen_hw_type hw_type;
                     ^
/labs/tdevries/gdb/src/gdb/../opcodes/mep-desc.h:212:14: note: type 'cgen_hw_type' itself violates the C++ One Definition Rule
 typedef enum cgen_hw_type {
              ^
/labs/tdevries/gdb/src/gdb/../opcodes/or1k-desc.h:433:14: note: the incompatible type is defined here
 typedef enum cgen_hw_type {
              ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:827:16: warning: type 'struct cgen_ifld' violates the C++ One Definition Rule [-Wodr]
 typedef struct cgen_ifld {
                ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:827:16: note: a type with different size is defined in another translation unit
 typedef struct cgen_ifld {
                ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:885:3: warning: type 'struct CGEN_IFMT_IFLD' violates the C++ One Definition Rule [-Wodr]
 } CGEN_IFMT_IFLD;
   ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:885:3: note: a different type is defined in another translation unit
 } CGEN_IFMT_IFLD;
   ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:883:20: note: the first difference of corresponding definitions is field 'ifld'
   const CGEN_IFLD *ifld;
                    ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:883:20: note: a field of same name but different type is defined in another translation unit
   const CGEN_IFLD *ifld;
                    ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:859:3: note: type 'const struct CGEN_IFLD' should match type 'const struct CGEN_IFLD'
 } CGEN_IFLD;
   ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:978:48: warning: type 'struct CGEN_INSN_ATTR_TYPE' violates the C++ One Definition Rule [-Wodr]
 typedef CGEN_ATTR_TYPE (CGEN_INSN_NBOOL_ATTRS) CGEN_INSN_ATTR_TYPE;
                                                ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:978:48: note: a different type is defined in another translation unit
 typedef CGEN_ATTR_TYPE (CGEN_INSN_NBOOL_ATTRS) CGEN_INSN_ATTR_TYPE;
                                                ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:978:9: note: the first difference of corresponding definitions is field 'nonbool'
 typedef CGEN_ATTR_TYPE (CGEN_INSN_NBOOL_ATTRS) CGEN_INSN_ATTR_TYPE;
         ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:978:9: note: a field of same name but different type is defined in another translation unit
 typedef CGEN_ATTR_TYPE (CGEN_INSN_NBOOL_ATTRS) CGEN_INSN_ATTR_TYPE;
         ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:978:48: note: array types have different bounds
 typedef CGEN_ATTR_TYPE (CGEN_INSN_NBOOL_ATTRS) CGEN_INSN_ATTR_TYPE;
                                                ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:1041:3: warning: type 'struct CGEN_IBASE' violates the C++ One Definition Rule [-Wodr]
 } CGEN_IBASE;
   ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:1041:3: note: a different type is defined in another translation unit
 } CGEN_IBASE;
   ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:1034:23: note: the first difference of corresponding definitions is field 'attrs'
   CGEN_INSN_ATTR_TYPE attrs;
                       ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:1034:23: note: a field of same name but different type is defined in another translation unit
   CGEN_INSN_ATTR_TYPE attrs;
                       ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:978:48: note: type 'struct CGEN_INSN_ATTR_TYPE' itself violates the C++ One Definition Rule
 typedef CGEN_ATTR_TYPE (CGEN_INSN_NBOOL_ATTRS) CGEN_INSN_ATTR_TYPE;
                                                ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:1050:8: warning: type 'struct cgen_insn' violates the C++ One Definition Rule [-Wodr]
 struct cgen_insn
        ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:1050:8: note: a different type is defined in another translation unit
 struct cgen_insn
        ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:1056:21: note: the first difference of corresponding definitions is field 'base'
   const CGEN_IBASE *base;
                     ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:1056:21: note: a field of same name but different type is defined in another translation unit
   const CGEN_IBASE *base;
                     ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:1041:3: note: type 'const struct CGEN_IBASE' should match type 'const struct CGEN_IBASE'
 } CGEN_IBASE;
   ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:1069:16: warning: type 'struct cgen_insn_list' violates the C++ One Definition Rule [-Wodr]
 typedef struct cgen_insn_list
                ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:1069:16: note: a different type is defined in another translation unit
 typedef struct cgen_insn_list
                ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:1072:20: note: the first difference of corresponding definitions is field 'insn'
   const CGEN_INSN *insn;
                    ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:1072:20: note: a field of same name but different type is defined in another translation unit
   const CGEN_INSN *insn;
                    ^
/labs/tdevries/gdb/src/gdb/../opcodes/mep-opc.h:347:8: warning: type 'struct cgen_fields' violates the C++ One Definition Rule [-Wodr]
 struct cgen_fields
        ^
/labs/tdevries/gdb/src/gdb/../opcodes/or1k-opc.h:93:8: note: a different type is defined in another translation unit
 struct cgen_fields
        ^
/labs/tdevries/gdb/src/gdb/../opcodes/mep-opc.h:352:8: note: the first difference of corresponding definitions is field 'f_major'
   long f_major;
        ^
/labs/tdevries/gdb/src/gdb/../opcodes/or1k-opc.h:98:8: note: a field with different name is defined in another translation unit
   long f_opcode;
        ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:1083:3: warning: type 'struct CGEN_INSN_TABLE' violates the C++ One Definition Rule [-Wodr]
 } CGEN_INSN_TABLE;
   ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:1083:3: note: a different type is defined in another translation unit
 } CGEN_INSN_TABLE;
   ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:1079:20: note: the first difference of corresponding definitions is field 'init_entries'
   const CGEN_INSN *init_entries;
                    ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:1079:20: note: a field of same name but different type is defined in another translation unit
   const CGEN_INSN *init_entries;
                    ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:702:3: warning: type 'struct CGEN_OPERAND' violates the C++ One Definition Rule [-Wodr]
 } CGEN_OPERAND;
   ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:702:3: note: a different type is defined in another translation unit
 } CGEN_OPERAND;
   ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:659:26: note: the first difference of corresponding definitions is field 'type'
   enum cgen_operand_type type;
                          ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:659:26: note: a field of same name but different type is defined in another translation unit
   enum cgen_operand_type type;
                          ^
/labs/tdevries/gdb/src/gdb/../opcodes/mep-desc.h:250:14: note: type 'cgen_operand_type' itself violates the C++ One Definition Rule
 typedef enum cgen_operand_type {
              ^
/labs/tdevries/gdb/src/gdb/../opcodes/or1k-desc.h:624:14: note: the incompatible type is defined here
 typedef enum cgen_operand_type {
              ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:725:3: warning: type 'struct CGEN_OPERAND_TABLE' violates the C++ One Definition Rule [-Wodr]
 } CGEN_OPERAND_TABLE;
   ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:725:3: note: a different type is defined in another translation unit
 } CGEN_OPERAND_TABLE;
   ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:715:23: note: the first difference of corresponding definitions is field 'init_entries'
   const CGEN_OPERAND *init_entries;
                       ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:715:23: note: a field of same name but different type is defined in another translation unit
   const CGEN_OPERAND *init_entries;
                       ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:702:3: note: type 'const struct CGEN_OPERAND' should match type 'const struct CGEN_OPERAND'
 } CGEN_OPERAND;
   ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:451:3: warning: type 'struct CGEN_HW_ENTRY' violates the C++ One Definition Rule [-Wodr]
 } CGEN_HW_ENTRY;
   ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:451:3: note: a different type is defined in another translation unit
 } CGEN_HW_ENTRY;
   ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:441:21: note: the first difference of corresponding definitions is field 'type'
   enum cgen_hw_type type;
                     ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:441:21: note: a field of same name but different type is defined in another translation unit
   enum cgen_hw_type type;
                     ^
/labs/tdevries/gdb/src/gdb/../opcodes/mep-desc.h:212:14: note: type 'cgen_hw_type' itself violates the C++ One Definition Rule
 typedef enum cgen_hw_type {
              ^
/labs/tdevries/gdb/src/gdb/../opcodes/or1k-desc.h:433:14: note: the incompatible type is defined here
 typedef enum cgen_hw_type {
              ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:473:3: warning: type 'struct CGEN_HW_TABLE' violates the C++ One Definition Rule [-Wodr]
 } CGEN_HW_TABLE;
   ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:473:3: note: a different type is defined in another translation unit
 } CGEN_HW_TABLE;
   ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:463:24: note: the first difference of corresponding definitions is field 'init_entries'
   const CGEN_HW_ENTRY *init_entries;
                        ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:463:24: note: a field of same name but different type is defined in another translation unit
   const CGEN_HW_ENTRY *init_entries;
                        ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:451:3: note: type 'const struct CGEN_HW_ENTRY' should match type 'const struct CGEN_HW_ENTRY'
 } CGEN_HW_ENTRY;
   ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:1199:16: warning: type 'struct cgen_cpu_desc' violates the C++ One Definition Rule [-Wodr]
 typedef struct cgen_cpu_desc
                ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:1199:16: note: a different type is defined in another translation unit
 typedef struct cgen_cpu_desc
                ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:1252:17: note: the first difference of corresponding definitions is field 'hw_table'
   CGEN_HW_TABLE hw_table;
                 ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:1252:17: note: a field of same name but different type is defined in another translation unit
   CGEN_HW_TABLE hw_table;
                 ^
/labs/tdevries/gdb/src/gdb/../include/opcode/cgen.h:473:3: note: type 'struct CGEN_HW_TABLE' itself violates the C++ One Definition Rule
 } CGEN_HW_TABLE;
   ^
...
Comment 1 Tom de Vries 2023-08-14 15:48:43 UTC
According to opcodes/MAINTAINTERS, the dir is maintained by the binutils maintainers, so I tried building with lto some non-gdb components that use the opcodes dir to reproduce this problem, such that I could file a corresponding binutils PR, but sofar that didn't trigger the same warnings.
Comment 2 Tom de Vries 2023-08-14 15:59:19 UTC
Filed binutils counterpart PR30758.
Comment 4 Sourceware Commits 2023-08-22 17:35:47 UTC
The master branch has been updated by Tom de Vries <vries@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=883d90a0ff6b1dbacf654f5a8db2350030b4df00

commit 883d90a0ff6b1dbacf654f5a8db2350030b4df00
Author: Tom de Vries <tdevries@suse.de>
Date:   Tue Aug 22 19:35:52 2023 +0200

    [gdb/build] Work around cgen odr violations
    
    When building gdb with -flto -O2, I run into:
    ...
    opcodes/mep-desc.h:250:14: warning: type 'cgen_operand_type' violates the \
      C++ One Definition Rule [-Wodr]
     typedef enum cgen_operand_type {
                  ^
    opcodes/or1k-desc.h:624:14: note: an enum with different value name is \
      defined in another translation unit
     typedef enum cgen_operand_type {
                  ^
    opcodes/mep-desc.h:212:14: warning: type 'cgen_hw_type' violates the C++ One \
      Definition Rule [-Wodr]
     typedef enum cgen_hw_type {
                  ^
    opcodes/or1k-desc.h:433:14: note: an enum with different value name is \
      defined in another translation unit
     typedef enum cgen_hw_type {
                  ^
    ...
    
    Fix this by making the conflicting type names unique, adding a target-specific
    prefix using a define before the include:
    ...
     #define cgen_operand_type <target-name>_cgen_operand_type
     #define cgen_hw_type  <target-name>_cgen_hw_type
     #include "opcodes/<target-name>-desc.h"
    ...
    and move those defines into a new file cgen-remap.h, similar to how that's
    done for yacc in yy-remap.h.
    
    Likewise for targets frv and lm32, the two other targets that include
    opcodes/<target-name>-desc.h.
    
    Likewise for more cgen symbols that I got the same warning for when using
    -flto-partition=one.
    
    A PR has been filed to take care of this in the opcodes dir instead (PR30758).
    
    Tested on x86_64-linux.
    
    Approved-By: Tom Tromey <tom@tromey.com>
    
    PR build/30757
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30757
Comment 5 Tom de Vries 2023-08-22 17:36:53 UTC
Fixed.