[1/1] abidw: add --consider-enumerator-names flag

Message ID 20220111161009.3008610-2-gprocida@google.com
State New
Headers
Series Bug 28319 - abidw - regression in treatment of anonymous enums in structs |

Commit Message

Giuliano Procida Jan. 11, 2022, 4:10 p.m. UTC
  Bug 28319 - abidw - regression in treatment of anonymous enums in structs

This flag reinstates the behaviour of comparing enumerator names
during duplicate enum type resolution which was lost by default as of
commit 1cfbff1b3037d1049bdff7e86de27c3a86af23b3.

That commit addressed an issue with a certain library that contained
duplicate enum type definitions with variations in the enumerator
names but with the same enumerator values.

Many projects will be able to avoid such issues by always compiling
from fresh and consistent sources.  Using this flag then avoids the
risk of conflating unrelated anonymous enum types.

	* doc/manuals/abidw.rst: Document --consider-enumerator-names.
	* include/abg-dwarf-reader.h (get_consider_enumerator_names):
	New function.
	(set_consider_enumerator_names): Likewise.
	* src/abg-dwarf-reader.cc (read_context): Fix documentation
	typos. Add consider_enumerator_names_ member variable.
	(read_context::initialize): Set consider_enumerator_names_ to
	false.
	(read_context::consider_enumerator_names): New getter and
	setter methods.
	(compare_before_canonicalisation): Set environment flag
	use_enum_binary_only_equality according to the value of
	consider_enumerator_names_.
	(get_consider_enumerator_names): New function.
	(set_consider_enumerator_names): Likewise.
	* tools/abidw.cc (options): Add consider_enumerator_names_
	option, defaulted to false.
	(parse_command_line): Parse --consider-enumerator-names flag.
	(load_corpus_and_write_abixml): Set consider_enumerator_names
	flag in DWARF reader context.

No tests are affected. There is no change to default behaviour.

Reviewed-by: Matthias Maennich <maennich@google.com>
Signed-off-by: Giuliano Procida <gprocida@google.com>
---
 doc/manuals/abidw.rst      | 10 ++++++++
 include/abg-dwarf-reader.h |  7 ++++++
 src/abg-dwarf-reader.cc    | 47 ++++++++++++++++++++++++++++++++++++--
 tools/abidw.cc             |  5 ++++
 4 files changed, 67 insertions(+), 2 deletions(-)
  

Patch

diff --git a/doc/manuals/abidw.rst b/doc/manuals/abidw.rst
index bdd6204d..f3d8e097 100644
--- a/doc/manuals/abidw.rst
+++ b/doc/manuals/abidw.rst
@@ -182,6 +182,16 @@  Options
     ELF binary.  It thus considers functions and variables which are
     defined and exported in the ELF sense.
 
+  * ``--consider-enumerator-names``
+
+    During resolution of duplicate enum types, abidw can consider both
+    enumerator names and values, or just the set of enumerator values.
+    The default is the latter.
+
+    With this option, abidw will also take into account enumerator
+    names and will consider enums, including anonymous enums, to be
+    distinct if there any differences in their enumerators' names.
+
   * ``--check-alternate-debug-info`` <*elf-path*>
 
     If the debug info for the file *elf-path* contains a reference to
diff --git a/include/abg-dwarf-reader.h b/include/abg-dwarf-reader.h
index 4c2de779..d2f4be1f 100644
--- a/include/abg-dwarf-reader.h
+++ b/include/abg-dwarf-reader.h
@@ -142,6 +142,13 @@  void
 set_drop_undefined_syms(read_context& ctxt,
 			bool f);
 
+bool
+get_consider_enumerator_names(read_context& ctxt);
+
+void
+set_consider_enumerator_names(read_context& ctxt,
+			      bool f);
+
 void
 set_do_log(read_context& ctxt, bool f);
 
diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc
index 3f716944..bdd53b35 100644
--- a/src/abg-dwarf-reader.cc
+++ b/src/abg-dwarf-reader.cc
@@ -1897,7 +1897,7 @@  struct dwarf_expr_eval_context
 /// get some important data from it.
 ///
 /// When a new data member is added to this context, it must be
-/// initiliazed by the read_context::initiliaze() function.  So please
+/// initialized by the read_context::initialize() function.  So please
 /// do not forget.
 class read_context
 {
@@ -2116,6 +2116,7 @@  public:
   corpus::exported_decls_builder* exported_decls_builder_;
   options_type			options_;
   bool				drop_undefined_syms_;
+  bool				consider_enumerator_names_;
   read_context();
 
 private:
@@ -2259,6 +2260,7 @@  public:
     options_.load_in_linux_kernel_mode = linux_kernel_mode;
     options_.load_all_types = load_all_types;
     drop_undefined_syms_ = false;
+    consider_enumerator_names_ = false;
     load_in_linux_kernel_mode(linux_kernel_mode);
   }
 
@@ -2346,6 +2348,23 @@  public:
   drop_undefined_syms(bool f)
   {drop_undefined_syms_ = f;}
 
+  /// Getter for the flag that tells if we should consider enumerator
+  /// names during duplicate enum type resolution.
+  ///
+  /// @return true iff we should consider enumerator names during
+  /// duplicate enum type resolution.
+  bool
+  consider_enumerator_names() const
+  {return consider_enumerator_names_;}
+
+  /// Setter for the flag that tells if we should consider enumerator
+  /// names during duplicate enum type resolution.
+  ///
+  /// @param f the new value of the flag.
+  void
+  consider_enumerator_names(bool f)
+  {consider_enumerator_names_ = f;}
+
   /// Getter of the suppression specifications to be used during
   /// ELF/DWARF parsing.
   ///
@@ -4151,7 +4170,7 @@  public:
     bool s0 = e->decl_only_class_equals_definition();
     bool s1 = e->use_enum_binary_only_equality();
     e->decl_only_class_equals_definition(true);
-    e->use_enum_binary_only_equality(true);
+    e->use_enum_binary_only_equality(!consider_enumerator_names_);
     bool equal = l == r;
     e->decl_only_class_equals_definition(s0);
     e->use_enum_binary_only_equality(s1);
@@ -6221,6 +6240,30 @@  void
 set_drop_undefined_syms(read_context& ctxt, bool f)
 {ctxt.drop_undefined_syms(f);}
 
+/// Getter of the "consider_enumerator_names" flag.
+///
+/// This flag tells if we should consider enumerator names during
+/// duplicate enum type resolution.
+///
+/// @param ctx the read context to consider for this flag.
+///
+/// @return the value of the flag.
+bool
+get_consider_enumerator_names(read_context& ctxt)
+{return ctxt.consider_enumerator_names();}
+
+/// Setter of the "consider_enumerator_names" flag.
+///
+/// This flag tells if we should consider enumerator names during
+/// duplicate enum type resolution.
+///
+/// @param ctxt the read context to consider for this flag.
+///
+/// @param f the value of the flag.
+void
+set_consider_enumerator_names(read_context& ctxt, bool f)
+{ctxt.consider_enumerator_names(f);}
+
 /// Setter of the "do_log" flag.
 ///
 /// This flag tells if we should emit verbose logs for various
diff --git a/tools/abidw.cc b/tools/abidw.cc
index f7a8937d..34d0f1a2 100644
--- a/tools/abidw.cc
+++ b/tools/abidw.cc
@@ -95,6 +95,7 @@  struct options
   bool			default_sizes;
   bool			load_all_types;
   bool			linux_kernel_mode;
+  bool			consider_enumerator_names;
   bool			corpus_group_for_linux;
   bool			show_stats;
   bool			noout;
@@ -132,6 +133,7 @@  struct options
       default_sizes(true),
       load_all_types(),
       linux_kernel_mode(true),
+      consider_enumerator_names(false),
       corpus_group_for_linux(false),
       show_stats(),
       noout(),
@@ -367,6 +369,8 @@  parse_command_line(int argc, char* argv[], options& opts)
 	opts.drop_undefined_syms = true;
       else if (!strcmp(argv[i], "--no-linux-kernel-mode"))
 	opts.linux_kernel_mode = false;
+      else if (!strcmp(argv[i], "--consider-enumerator-names"))
+	opts.consider_enumerator_names = true;
       else if (!strcmp(argv[i], "--abidiff"))
 	opts.abidiff = true;
 #ifdef WITH_DEBUG_SELF_COMPARISON
@@ -562,6 +566,7 @@  load_corpus_and_write_abixml(char* argv[],
                                                      opts.linux_kernel_mode);
       dwarf_reader::read_context& ctxt = *c;
       set_drop_undefined_syms(ctxt, opts.drop_undefined_syms);
+      set_consider_enumerator_names(ctxt, opts.consider_enumerator_names);
       set_show_stats(ctxt, opts.show_stats);
       set_suppressions(ctxt, opts);
       abigail::dwarf_reader::set_do_log(ctxt, opts.do_log);