fix --- gdb/defs.h | 3 +++ gdb/dwarf2/read.h | 22 ++++++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/gdb/defs.h b/gdb/defs.h index 19f379d6588..c129bf633a1 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -235,6 +235,9 @@ gdb_static_assert (nr_languages <= (1 << LANGUAGE_BITS)); /* The number of bytes needed to represent all languages. */ #define LANGUAGE_BYTES ((LANGUAGE_BITS + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT) +#define LANGUAGE_CONTAINER unsigned char +gdb_static_assert (sizeof (LANGUAGE_CONTAINER) >= LANGUAGE_BYTES); + enum precision_type { single_precision, diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h index f98d8b27649..f4362fe3ede 100644 --- a/gdb/dwarf2/read.h +++ b/gdb/dwarf2/read.h @@ -108,6 +108,7 @@ struct dwarf2_per_cu_data m_header_read_in (false), mark (false), files_read (false), + m_lang (language_unknown), scanned (false) { } @@ -180,7 +181,7 @@ struct dwarf2_per_cu_data packed m_unit_type = (dwarf_unit_type) 0; /* The language of this CU. */ - packed m_lang = language_unknown; + std::atomic m_lang; public: /* True if this CU has been scanned by the indexer; false if @@ -326,17 +327,22 @@ struct dwarf2_per_cu_data enum language lang () const { - gdb_assert (m_lang != language_unknown); - return m_lang; + LANGUAGE_CONTAINER lc = m_lang; + enum language l = (enum language)lc; + gdb_assert (l != language_unknown); + return l; } void set_lang (enum language lang) { - /* We'd like to be more strict here, similar to what is done in - set_unit_type, but currently a partial unit can go from unknown to - minimal to ada to c. */ - if (m_lang != lang) - m_lang = lang; + LANGUAGE_CONTAINER lc = (LANGUAGE_CONTAINER)lang; + LANGUAGE_CONTAINER nope = (LANGUAGE_CONTAINER)language_unknown; + if (m_lang.compare_exchange_strong (nope, lc)) + return; + nope = lang; + if (m_lang.compare_exchange_strong (nope, lc)) + return; + gdb_assert_not_reached (); } /* Free any cached file names. */