commit b22dd1b1bbe2ae953493af824eb42320df241be6
Author: Jason Merrill <jason@redhat.com>
Date: Mon Jul 19 09:35:58 2010 -0400
PR c++/44969
* tree.c (cp_tree_equal): Compare type of *CAST_EXPR.
* pt.c (iterative_hash_template_arg): Hash type of *CAST_EXPR.
@@ -1566,31 +1566,43 @@ iterative_hash_template_arg (tree arg, hashval_t val)
gcc_assert (seen_error ());
return val;
+ case CAST_EXPR:
+ case STATIC_CAST_EXPR:
+ case REINTERPRET_CAST_EXPR:
+ case CONST_CAST_EXPR:
+ case DYNAMIC_CAST_EXPR:
+ case NEW_EXPR:
+ val = iterative_hash_template_arg (TREE_TYPE (arg), val);
+ /* Now hash operands as usual. */
+ break;
+
default:
- switch (tclass)
- {
- case tcc_type:
- if (TYPE_CANONICAL (arg))
- return iterative_hash_object (TYPE_HASH (TYPE_CANONICAL (arg)),
- val);
- else if (TREE_CODE (arg) == DECLTYPE_TYPE)
- return iterative_hash_template_arg (DECLTYPE_TYPE_EXPR (arg), val);
- /* Otherwise just compare the types during lookup. */
- return val;
+ break;
+ }
- case tcc_declaration:
- case tcc_constant:
- return iterative_hash_expr (arg, val);
+ switch (tclass)
+ {
+ case tcc_type:
+ if (TYPE_CANONICAL (arg))
+ return iterative_hash_object (TYPE_HASH (TYPE_CANONICAL (arg)),
+ val);
+ else if (TREE_CODE (arg) == DECLTYPE_TYPE)
+ return iterative_hash_template_arg (DECLTYPE_TYPE_EXPR (arg), val);
+ /* Otherwise just compare the types during lookup. */
+ return val;
- default:
- gcc_assert (IS_EXPR_CODE_CLASS (tclass));
- {
- unsigned n = TREE_OPERAND_LENGTH (arg);
- for (i = 0; i < n; ++i)
- val = iterative_hash_template_arg (TREE_OPERAND (arg, i), val);
- return val;
- }
- }
+ case tcc_declaration:
+ case tcc_constant:
+ return iterative_hash_expr (arg, val);
+
+ default:
+ gcc_assert (IS_EXPR_CODE_CLASS (tclass));
+ {
+ unsigned n = TREE_OPERAND_LENGTH (arg);
+ for (i = 0; i < n; ++i)
+ val = iterative_hash_template_arg (TREE_OPERAND (arg, i), val);
+ return val;
+ }
}
gcc_unreachable ();
return 0;
@@ -2191,6 +2191,17 @@ cp_tree_equal (tree t1, tree t2)
return same_type_p (TRAIT_EXPR_TYPE1 (t1), TRAIT_EXPR_TYPE1 (t2))
&& same_type_p (TRAIT_EXPR_TYPE2 (t1), TRAIT_EXPR_TYPE2 (t2));
+ case CAST_EXPR:
+ case STATIC_CAST_EXPR:
+ case REINTERPRET_CAST_EXPR:
+ case CONST_CAST_EXPR:
+ case DYNAMIC_CAST_EXPR:
+ case NEW_EXPR:
+ if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+ return false;
+ /* Now compare operands as usual. */
+ break;
+
default:
break;
}
new file mode 100644
@@ -0,0 +1,27 @@
+// PR c++/44969
+
+template<bool, typename T = void> struct enable_if { typedef T type; };
+template<typename T> struct enable_if<false, T> { };
+
+template<typename Tp, typename Arg1, typename Arg2>
+ class mini_is_constructible
+ {
+ typedef char one;
+ typedef struct { char arr[2]; } two;
+
+ template<typename Tp1, typename Arg1_, typename Arg2_>
+ static typename
+ enable_if<(sizeof(Tp1(Arg1_(), Arg2_()), 1) > 0), one>::type
+ test(int);
+
+ template<typename, typename, typename>
+ static two test(...);
+
+ public:
+ static const bool value = sizeof(test<Tp, Arg1, Arg2>(0)) == 1;
+ };
+
+class A { };
+
+int Test[mini_is_constructible<int, A, A>::value ? -1 : 1];
+