c++: Fix erroneous parm comparison logic [PR 98372]
authorNathan Sidwell <nathan@acm.org>
Thu, 14 Jan 2021 13:15:33 +0000 (05:15 -0800)
committerNathan Sidwell <nathan@acm.org>
Thu, 14 Jan 2021 13:31:07 +0000 (05:31 -0800)
I flubbed an application of De Morgan's law.  Let's just express the
logic directly and let the compiler figure it out.  This bug made it
look like pr52830 was fixed, but it is not.

PR c++/98372
gcc/cp/
* tree.c (cp_tree_equal): Correct map_context logic.
gcc/testsuite/
* g++.dg/cpp0x/constexpr-52830.C: Restore dg-ice
* g++.dg/template/pr98372.C: New.

gcc/cp/tree.c
gcc/testsuite/g++.dg/cpp0x/constexpr-52830.C
gcc/testsuite/g++.dg/template/pr98372.C [new file with mode: 0644]

index d339036e88e766db81b6cc5f419c5b5e83cc6be2..3a9a86de34a05c1708275df2d8a40f48e4cac1a8 100644 (file)
@@ -3841,8 +3841,8 @@ cp_tree_equal (tree t1, tree t2)
          /* Module duplicate checking can have t1 = new, t2 =
             existing, and they should be considered matching at this
             point.  */
-         && (DECL_CONTEXT (t1) != map_context_from
-             && DECL_CONTEXT (t2) != map_context_to))
+         && !(DECL_CONTEXT (t1) == map_context_from
+              && DECL_CONTEXT (t2) == map_context_to))
        /* When comparing hash table entries, only an exact match is
           good enough; we don't want to replace 'this' with the
           version from another function.  But be more flexible
index 04f039fac4313c54a0a0e8027d16faa5aa2a2fb0..2c9d2f9b329eafb5c2f8f0ca51a2f3d903c6a05c 100644 (file)
@@ -1,5 +1,6 @@
 // PR c++/52830
 // { dg-do compile { target c++11 } }
+// { dg-ice "comptypes" }
 
 template<bool b> struct eif { typedef void type; };
 template<>       struct eif<false> {};
diff --git a/gcc/testsuite/g++.dg/template/pr98372.C b/gcc/testsuite/g++.dg/template/pr98372.C
new file mode 100644 (file)
index 0000000..f1e8b0f
--- /dev/null
@@ -0,0 +1,28 @@
+// PR 98372 ICE due to incorrect type compare
+// { dg-do compile { target c++11 } }
+
+template <typename _Tp> using remove_pointer_t = typename _Tp ::type;
+template <bool> struct enable_if;
+template <bool _Cond, typename>
+using enable_if_t = typename enable_if<_Cond>::type;
+template <typename> bool is_convertible_v;
+template <typename, unsigned long = 0> class Span;
+template <typename T, unsigned long> class Span {
+  using element_type = T;
+  template <unsigned long N>
+  Span(element_type (&arr)[N],
+       enable_if_t<is_convertible_v<remove_pointer_t<decltype(data(arr))>>,
+                   decltype(nullptr)>);
+};
+template <typename T> class Span<T> {
+  using element_type = T;
+  template <unsigned long N>
+  Span(element_type (&arr)[N],
+       enable_if_t<is_convertible_v<remove_pointer_t<decltype(data(arr))>>,
+                   decltype(nullptr)>);
+};
+
+struct aaa
+{
+  Span<char> data0;
+};