]> sourceware.org Git - libabigail.git/commitdiff
Filter top cv qualifier changes on function parameter types
authorDodji Seketeli <dodji@redhat.com>
Fri, 9 Jun 2017 08:37:59 +0000 (10:37 +0200)
committerDodji Seketeli <dodji@redhat.com>
Mon, 3 Jul 2017 15:45:47 +0000 (17:45 +0200)
When the type of a function parameter sees its top CV qualifier
change, that should never negatively affect ABI compliance.

So this patch filters out top cv qualifier changes on function
parameter types, by default.

* include/abg-comparison.h (enum diff_category): Add a new
FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY enumerator.  "Or" the
enumerator to the EVERYTHING_CATEGORY enumerator.
* src/abg-comp-filter.cc (has_fn_parm_type_cv_qual_change): Define
new static function.
(categorize_harmless_diff_node): Categorize changes to top cv
qualifiers on function parameter types into the new
FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY.
* src/abg-comparison.cc (get_default_harmless_categories_bitmap):
Add the new FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY category to the
set of harmless categories.
(operator<<(ostream&, diff_category)): Adjust to serialize
the new FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY.
* tests/data/test-diff-filter/libtest40-v0.so: New test input binary.
* tests/data/test-diff-filter/libtest40-v1.so: Likewise.
* tests/data/test-diff-filter/test40-report-0.txt: New test
reference output.
* tests/data/test-diff-filter/test40-v0.cc: Source code of the
test binary above.
* tests/data/test-diff-filter/test40-v1.cc: Likewise.
* tests/data/Makefile.am: Add the new test material above to
source distribution.
* tests/test-diff-filter.cc (in_out_specs): Add new binaries to
compare.
* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
Adjust.
* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt:
Likewise.
* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt:
Likewise.
* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-1.txt:
Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
14 files changed:
include/abg-comparison.h
src/abg-comp-filter.cc
src/abg-comparison.cc
tests/data/Makefile.am
tests/data/test-diff-filter/libtest40-v0.so [new file with mode: 0755]
tests/data/test-diff-filter/libtest40-v1.so [new file with mode: 0755]
tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt
tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt
tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt
tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-1.txt
tests/data/test-diff-filter/test40-report-0.txt [new file with mode: 0644]
tests/data/test-diff-filter/test40-v0.cc [new file with mode: 0644]
tests/data/test-diff-filter/test40-v1.cc [new file with mode: 0644]
tests/test-diff-filter.cc

index f8c836daae7e2f334d72af6425ec6f5d6af17676..46b9c32b43658601c0cb1838be48667a49a80c48 100644 (file)
@@ -368,6 +368,10 @@ enum diff_category
   /// versa.
   CLASS_DECL_ONLY_DEF_CHANGE_CATEGORY = 1 << 11,
 
+  /// A diff node in this category is a function parameter type which
+  /// top cv-qualifiers change.
+  FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY = 1 << 12,
+
   /// A special enumerator that is the logical 'or' all the
   /// enumerators above.
   ///
@@ -386,7 +390,8 @@ enum diff_category
   | VIRTUAL_MEMBER_CHANGE_CATEGORY
   | REDUNDANT_CATEGORY
   | CLASS_DECL_ONLY_DEF_CHANGE_CATEGORY
-};
+  | FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY
+}; // enum diff_category
 
 diff_category
 operator|(diff_category c1, diff_category c2);
index 164336aa96286d8ec60f8743f511222a0d48e698..aaa36d9a25741962b53297a66a945ca09eab8d73 100644 (file)
@@ -1,6 +1,6 @@
 // -*- Mode: C++ -*-
 //
-// Copyright (C) 2013-2016 Red Hat, Inc.
+// Copyright (C) 2013-2017 Red Hat, Inc.
 //
 // This file is part of the GNU Application Binary Interface Generic
 // Analysis and Instrumentation Library (libabigail).  This library is
@@ -818,6 +818,67 @@ has_harmful_enum_change(const diff* diff)
   return false;
 }
 
+/// Test if an @ref fn_parm_diff node has a top cv qualifier change on
+/// the type of the function parameter.
+///
+/// @param diff the diff node to consider.  It should be a @ref
+/// fn_parm_diff, otherwise the function returns 'false' directly.
+///
+/// @return true iff @p diff is a @ref fn_parm_diff node that has a
+/// top cv qualifier change on the type of the function parameter.
+static bool
+has_fn_parm_type_cv_qual_change(const diff* diff)
+{
+  // is diff a "function parameter diff node?
+  const fn_parm_diff* parm_diff = is_fn_parm_diff(diff);
+
+  if (!parm_diff || !parm_diff->has_changes())
+    // diff either carries no change or is not a function parameter
+    // diff node.  So bail out.
+    return false;
+
+  function_decl::parameter_sptr first_parm = parm_diff->first_parameter();
+  function_decl::parameter_sptr second_parm = parm_diff->second_parameter();
+
+  type_base_sptr first_parm_type = first_parm->get_type();
+  type_base_sptr second_parm_type = second_parm->get_type();
+
+  if (!is_qualified_type(first_parm_type)
+      && !is_qualified_type(second_parm_type))
+    // None of the parameter types is qualified.
+    return false;
+
+  qualified_type_def::CV cv_quals_1 = qualified_type_def::CV_NONE;
+  qualified_type_def::CV cv_quals_2 = qualified_type_def::CV_NONE;
+  type_base_sptr peeled_type_1 = first_parm_type;
+  type_base_sptr peeled_type_2 = second_parm_type;
+
+  if (qualified_type_def_sptr qtype1 = is_qualified_type(first_parm_type))
+    {
+      cv_quals_1 = qtype1->get_cv_quals();
+      peeled_type_1 = peel_qualified_type(qtype1);
+    }
+
+  if (qualified_type_def_sptr qtype2 = is_qualified_type(second_parm_type))
+    {
+      cv_quals_2 = qtype2->get_cv_quals();
+      peeled_type_2 = peel_qualified_type(qtype2);
+    }
+
+  if (peeled_type_1
+      && peeled_type_2
+      && get_type_name(peeled_type_1) == get_type_name(peeled_type_2)
+      && cv_quals_1 != cv_quals_2)
+    // The top-level CV qualifiers of the function type are different
+    // and the un-qualified variant (peeled) of said function types
+    // are equal.  This means the only change the function types have
+    // are about top-level CV qualifiers.
+    return true;
+
+  return false;
+
+}
+
 /// Detect if the changes carried by a given diff node are deemed
 /// harmless and do categorize the diff node accordingly.
 ///
@@ -868,6 +929,9 @@ categorize_harmless_diff_node(diff *d, bool pre)
       if (function_name_changed_but_not_symbol(d))
        category |= HARMLESS_SYMBOL_ALIAS_CHANGE_CATEORY;
 
+      if (has_fn_parm_type_cv_qual_change(d))
+       category |= FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY;
+
       if (category)
        {
          d->add_to_local_and_inherited_categories(category);
index d44dfff5b8455562ce5d4a0c13a1f7143afc8ff0..a33e7f5f06024b35c4b7baa5d272346ba5c31cdf 100644 (file)
@@ -2559,7 +2559,8 @@ get_default_harmless_categories_bitmap()
          | abigail::comparison::STATIC_DATA_MEMBER_CHANGE_CATEGORY
          | abigail::comparison::HARMLESS_ENUM_CHANGE_CATEGORY
          | abigail::comparison::HARMLESS_SYMBOL_ALIAS_CHANGE_CATEORY
-         | abigail::comparison::CLASS_DECL_ONLY_DEF_CHANGE_CATEGORY);
+         | abigail::comparison::CLASS_DECL_ONLY_DEF_CHANGE_CATEGORY
+         | abigail::comparison::FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY);
 }
 
 /// Getter of a bitmap made of the set of change categories that are
@@ -2679,6 +2680,15 @@ operator<<(ostream& o, diff_category c)
       emitted_a_category |= true;
     }
 
+  if (c & FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY)
+    {
+      if (emitted_a_category)
+       o << "|";
+      o << "FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY";
+      emitted_a_category |= true;
+    }
+
+
   if (c & SUPPRESSED_CATEGORY)
     {
       if (emitted_a_category)
index 2dd71e13e78894bd41e12146ee28a610ddfab45e..c7e405ef9415436616c940e96d5066a5f7a54bc9 100644 (file)
@@ -620,6 +620,11 @@ test-diff-filter/test39-main.c \
 test-diff-filter/test39-v0 \
 test-diff-filter/test39-v1 \
 test-diff-filter/test39-report-0.txt \
+test-diff-filter/libtest40-v0.so \
+test-diff-filter/libtest40-v1.so \
+test-diff-filter/test40-report-0.txt \
+test-diff-filter/test40-v0.cc \
+test-diff-filter/test40-v1.cc \
 \
 test-diff-suppr/test0-type-suppr-v0.cc \
 test-diff-suppr/test0-type-suppr-v1.cc \
diff --git a/tests/data/test-diff-filter/libtest40-v0.so b/tests/data/test-diff-filter/libtest40-v0.so
new file mode 100755 (executable)
index 0000000..a8ad350
Binary files /dev/null and b/tests/data/test-diff-filter/libtest40-v0.so differ
diff --git a/tests/data/test-diff-filter/libtest40-v1.so b/tests/data/test-diff-filter/libtest40-v1.so
new file mode 100755 (executable)
index 0000000..8ac6d6d
Binary files /dev/null and b/tests/data/test-diff-filter/libtest40-v1.so differ
index b3795893b5442c48e0da9ae004310bf587ea3140..14ab1f229aeec15b37d193e3a5ed788905efa9ea 100644 (file)
@@ -1,4 +1,4 @@
-Functions changes summary: 82 Removed, 7 Changed (13 filtered out), 1081 Added functions
+Functions changes summary: 82 Removed, 5 Changed (15 filtered out), 1081 Added functions
 Variables changes summary: 47 Removed, 1 Changed, 11 Added variables
 Function symbols changes summary: 7 Removed, 76 Added function symbols not referenced by debug info
 Variable symbols changes summary: 0 Removed, 0 Added variable symbol not referenced by debug info
@@ -1172,27 +1172,7 @@ Variable symbols changes summary: 0 Removed, 0 Added variable symbol not referen
   [A] 'method void std::vector<const VarTable::Entry*, std::allocator<const VarTable::Entry*> >::vector<Iterator, void>(Iterator, Iterator, const std::vector<const VarTable::Entry*, std::allocator<const VarTable::Entry*> >::allocator_type&)'
   [A] 'method std::vector<const VarTable::Entry*, std::allocator<const VarTable::Entry*> >::~vector(int)'
 
-7 functions with some indirect sub-type change:
-
-  [C]'function int ORSLRelease(const int, const int* restrict, const ORSLBusySet* restrict, const restrict ORSLTag)' has some indirect sub-type changes:
-    parameter 2 of type 'const int* restrict' changed:
-      entity changed from 'const int* restrict' to 'const int*'
-      type size hasn't changed
-    parameter 3 of type 'const ORSLBusySet* restrict' changed:
-      entity changed from 'const ORSLBusySet* restrict' to 'const ORSLBusySet*'
-      type size hasn't changed
-    parameter 4 of type 'const restrict ORSLTag' changed:
-      'const restrict ORSLTag' changed to 'const ORSLTag'
-
-  [C]'function int ORSLReservePartial(const ORSLPartialGranularity, const int, const int* restrict, ORSLBusySet* restrict, const restrict ORSLTag)' has some indirect sub-type changes:
-    parameter 3 of type 'const int* restrict' changed:
-      entity changed from 'const int* restrict' to 'const int*'
-      type size hasn't changed
-    parameter 4 of type 'ORSLBusySet* restrict' changed:
-      entity changed from 'ORSLBusySet* restrict' to 'ORSLBusySet*'
-      type size hasn't changed
-    parameter 5 of type 'const restrict ORSLTag' changed:
-      'const restrict ORSLTag' changed to 'const ORSLTag'
+5 functions with some indirect sub-type change:
 
   [C]'method void OffloadDescriptor::report_coi_error(error_types, COIRESULT)' has some indirect sub-type changes:
     parameter 1 of type 'typedef error_types' has sub-type changes:
index 92b8a3092601a9f670c36fd03add408ef17c9cb0..5406e803ba07739fcf65bfc68dc8e351abca02a6 100644 (file)
@@ -1,4 +1,4 @@
-Functions changes summary: 82 Removed, 7 Changed (13 filtered out), 1081 Added functions
+Functions changes summary: 82 Removed, 5 Changed (15 filtered out), 1081 Added functions
 Variables changes summary: 47 Removed, 1 Changed, 11 Added variables
 Function symbols changes summary: 7 Removed, 76 Added function symbols not referenced by debug info
 Variable symbols changes summary: 0 Removed, 0 Added variable symbol not referenced by debug info
@@ -1172,27 +1172,7 @@ Variable symbols changes summary: 0 Removed, 0 Added variable symbol not referen
   [A] 'method void std::vector<const VarTable::Entry*, std::allocator<const VarTable::Entry*> >::vector<Iterator, void>(Iterator, Iterator, const std::vector<const VarTable::Entry*, std::allocator<const VarTable::Entry*> >::allocator_type&)'
   [A] 'method std::vector<const VarTable::Entry*, std::allocator<const VarTable::Entry*> >::~vector(int)'
 
-7 functions with some indirect sub-type change:
-
-  [C]'function int ORSLRelease(const int, const int* restrict, const ORSLBusySet* restrict, const restrict ORSLTag)' at orsl-lite.c:327:1 has some indirect sub-type changes:
-    parameter 2 of type 'const int* restrict' changed:
-      entity changed from 'const int* restrict' to 'const int*'
-      type size hasn't changed
-    parameter 3 of type 'const ORSLBusySet* restrict' changed:
-      entity changed from 'const ORSLBusySet* restrict' to 'const ORSLBusySet*'
-      type size hasn't changed
-    parameter 4 of type 'const restrict ORSLTag' changed:
-      'const restrict ORSLTag' changed to 'const ORSLTag'
-
-  [C]'function int ORSLReservePartial(const ORSLPartialGranularity, const int, const int* restrict, ORSLBusySet* restrict, const restrict ORSLTag)' at orsl-lite.c:290:1 has some indirect sub-type changes:
-    parameter 3 of type 'const int* restrict' changed:
-      entity changed from 'const int* restrict' to 'const int*'
-      type size hasn't changed
-    parameter 4 of type 'ORSLBusySet* restrict' changed:
-      entity changed from 'ORSLBusySet* restrict' to 'ORSLBusySet*'
-      type size hasn't changed
-    parameter 5 of type 'const restrict ORSLTag' changed:
-      'const restrict ORSLTag' changed to 'const ORSLTag'
+5 functions with some indirect sub-type change:
 
   [C]'method void OffloadDescriptor::report_coi_error(error_types, COIRESULT)' at offload_host.h:206:1 has some indirect sub-type changes:
     parameter 1 of type 'typedef error_types' has sub-type changes:
index 792e92edbf68cb8bcb862a25ecdffd12d8a844ff..a9df743c8ed3b1280280cfeedd6938c15d7c9cc1 100644 (file)
@@ -1,4 +1,4 @@
-Functions changes summary: 82 Removed, 7 Changed (13 filtered out), 0 Added functions (1081 filtered out)
+Functions changes summary: 82 Removed, 5 Changed (15 filtered out), 0 Added functions (1081 filtered out)
 Variables changes summary: 47 Removed, 1 Changed, 0 Added variables (11 filtered out)
 Function symbols changes summary: 7 Removed, 0 Added (76 filtered out) function symbols not referenced by debug info
 Variable symbols changes summary: 0 Removed, 0 Added variable symbol not referenced by debug info
@@ -88,27 +88,7 @@ Variable symbols changes summary: 0 Removed, 0 Added variable symbol not referen
   'function void std::__unguarded_linear_insert<VarList::BufEntry*, __gnu_cxx::__ops::_Val_comp_iter<bool (*)(const VarList::BufEntry&, const VarList::BufEntry&)> >(VarList::BufEntry*, __gnu_cxx::__ops::_Val_comp_iter<bool (*)(const VarList::BufEntry&, const VarList::BufEntry&)>)'
   'function void write_message(FILE*, int, __va_list_tag*)'
 
-7 functions with some indirect sub-type change:
-
-  [C]'function int ORSLRelease(const int, const int* restrict, const ORSLBusySet* restrict, const restrict ORSLTag)' has some indirect sub-type changes:
-    parameter 2 of type 'const int* restrict' changed:
-      entity changed from 'const int* restrict' to 'const int*'
-      type size hasn't changed
-    parameter 3 of type 'const ORSLBusySet* restrict' changed:
-      entity changed from 'const ORSLBusySet* restrict' to 'const ORSLBusySet*'
-      type size hasn't changed
-    parameter 4 of type 'const restrict ORSLTag' changed:
-      'const restrict ORSLTag' changed to 'const ORSLTag'
-
-  [C]'function int ORSLReservePartial(const ORSLPartialGranularity, const int, const int* restrict, ORSLBusySet* restrict, const restrict ORSLTag)' has some indirect sub-type changes:
-    parameter 3 of type 'const int* restrict' changed:
-      entity changed from 'const int* restrict' to 'const int*'
-      type size hasn't changed
-    parameter 4 of type 'ORSLBusySet* restrict' changed:
-      entity changed from 'ORSLBusySet* restrict' to 'ORSLBusySet*'
-      type size hasn't changed
-    parameter 5 of type 'const restrict ORSLTag' changed:
-      'const restrict ORSLTag' changed to 'const ORSLTag'
+5 functions with some indirect sub-type change:
 
   [C]'method void OffloadDescriptor::report_coi_error(error_types, COIRESULT)' has some indirect sub-type changes:
     parameter 1 of type 'typedef error_types' has sub-type changes:
index d1bcc756e1d816605a9fa5afb40f43460aff4273..95997590e172bf98517352d77105bfb73e2696f3 100644 (file)
@@ -1,4 +1,4 @@
-Functions changes summary: 82 Removed, 7 Changed (13 filtered out), 0 Added functions (1081 filtered out)
+Functions changes summary: 82 Removed, 5 Changed (15 filtered out), 0 Added functions (1081 filtered out)
 Variables changes summary: 0 Removed (47 filtered out), 1 Changed, 0 Added variables (11 filtered out)
 Function symbols changes summary: 7 Removed, 0 Added (76 filtered out) function symbols not referenced by debug info
 Variable symbols changes summary: 0 Removed, 0 Added variable symbol not referenced by debug info
diff --git a/tests/data/test-diff-filter/test40-report-0.txt b/tests/data/test-diff-filter/test40-report-0.txt
new file mode 100644 (file)
index 0000000..9666a8f
--- /dev/null
@@ -0,0 +1,3 @@
+Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
diff --git a/tests/data/test-diff-filter/test40-v0.cc b/tests/data/test-diff-filter/test40-v0.cc
new file mode 100644 (file)
index 0000000..039d5f5
--- /dev/null
@@ -0,0 +1,21 @@
+// compile with:
+// g++ -g -shared -fPIC -o libtest40-v0.so test40-v0.cc
+
+struct S
+{
+  int m;
+};
+
+void
+foo(const S, int c, const bool b)
+{
+  int d = c + b;
+}
+
+
+void
+bar()
+{
+  S s;
+  foo(s, 0, false);
+}
diff --git a/tests/data/test-diff-filter/test40-v1.cc b/tests/data/test-diff-filter/test40-v1.cc
new file mode 100644 (file)
index 0000000..f0c7b42
--- /dev/null
@@ -0,0 +1,20 @@
+// compile with:
+// g++ -g -shared -fPIC -o libtest40-v1.so test40-v1.cc
+
+struct S
+{
+  int m;
+};
+
+void
+foo(const S, int c, bool b)
+{
+  int d = c + b;
+}
+
+void
+bar()
+{
+  S s;
+  foo(s, 0, false);
+}
index 9bde9c10f042808c47d1a9676bfca0a3afd6614f..4254aaa2b7382a6cac376c4a9e1bc062a4d3ddcb 100644 (file)
@@ -464,6 +464,13 @@ InOutSpec in_out_specs[] =
     "data/test-diff-filter/test39/test39-report-0.txt",
     "output/test-diff-filter/test39/test39-report-0.txt",
   },
+  {
+    "data/test-diff-filter/libtest40-v0.so",
+    "data/test-diff-filter/libtest40-v1.so",
+    "--no-default-suppression --no-linkage-name",
+    "data/test-diff-filter/test40-report-0.txt",
+    "output/test-diff-filter/test40-report-0.txt",
+  },
   // This should be the last entry
   {NULL, NULL, NULL, NULL, NULL}
 };
This page took 0.051124 seconds and 5 git commands to generate.