* [C++, committed] PR 44969 (first half)
@ 2010-07-19 10:29 Paolo Carlini
2010-07-19 14:49 ` Jason Merrill
0 siblings, 1 reply; 2+ messages in thread
From: Paolo Carlini @ 2010-07-19 10:29 UTC (permalink / raw)
To: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 117 bytes --]
Hi,
tested x86_64-linux, approved by Jason in the audit-trail, committed to
mainline.
Paolo.
////////////////////
[-- Attachment #2: CL_44969 --]
[-- Type: text/plain, Size: 538 bytes --]
/cp
2010-07-19 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/44969
* typeck.c (build_x_compound_expr_from_list): Add tsubst_flags_t
parameter.
* cp-tree.h: Adjust declaration.
* init.c (perform_member_init): Adjust caller.
* decl.c (grok_reference_init, cp_finish_decl): Likewise.
* typeck2.c (store_init_value): Likewise.
(build_functional_cast): Pass complain argument to
build_x_compound_expr_from_list.
/testsuite
2010-07-19 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/44969
* g++.dg/template/sfinae23.C: New.
[-- Attachment #3: patch_44969 --]
[-- Type: text/plain, Size: 5035 bytes --]
Index: testsuite/g++.dg/template/sfinae23.C
===================================================================
--- testsuite/g++.dg/template/sfinae23.C (revision 0)
+++ testsuite/g++.dg/template/sfinae23.C (revision 0)
@@ -0,0 +1,23 @@
+// PR c++/44969
+// { dg-options "-std=c++0x" }
+
+template<typename Tp, typename... Args>
+ class mini_is_constructible
+ {
+ typedef char one;
+ typedef struct { char arr[2]; } two;
+
+ template<typename Tp1, typename... Args1>
+ static decltype(Tp1(Args1()...), one())
+ test(int);
+
+ template<typename, typename...>
+ static two test(...);
+
+ public:
+ static const bool value = sizeof(test<Tp, Args...>(0)) == 1;
+ };
+
+class A { };
+
+int Test[mini_is_constructible<int, A, A>::value ? -1 : 1];
Index: cp/typeck.c
===================================================================
--- cp/typeck.c (revision 162298)
+++ cp/typeck.c (working copy)
@@ -5502,14 +5502,16 @@ build_x_conditional_expr (tree ifexp, tree op1, tr
that performs them all and returns the value of the last of them. */
tree
-build_x_compound_expr_from_list (tree list, expr_list_kind exp)
+build_x_compound_expr_from_list (tree list, expr_list_kind exp,
+ tsubst_flags_t complain)
{
tree expr = TREE_VALUE (list);
if (TREE_CHAIN (list))
{
- switch (exp)
- {
+ if (complain & tf_error)
+ switch (exp)
+ {
case ELK_INIT:
permerror (input_location, "expression list treated as compound "
"expression in initializer");
@@ -5524,11 +5526,11 @@ tree
break;
default:
gcc_unreachable ();
- }
+ }
for (list = TREE_CHAIN (list); list; list = TREE_CHAIN (list))
expr = build_x_compound_expr (expr, TREE_VALUE (list),
- tf_warning_or_error);
+ complain);
}
return expr;
Index: cp/init.c
===================================================================
--- cp/init.c (revision 162298)
+++ cp/init.c (working copy)
@@ -525,7 +525,8 @@ perform_member_init (tree member, tree init)
else if (TREE_CODE (init) == TREE_LIST)
/* There was an explicit member initialization. Do some work
in that case. */
- init = build_x_compound_expr_from_list (init, ELK_MEM_INIT);
+ init = build_x_compound_expr_from_list (init, ELK_MEM_INIT,
+ tf_warning_or_error);
if (init)
finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init,
Index: cp/decl.c
===================================================================
--- cp/decl.c (revision 162298)
+++ cp/decl.c (working copy)
@@ -4462,7 +4462,8 @@ grok_reference_init (tree decl, tree type, tree in
}
if (TREE_CODE (init) == TREE_LIST)
- init = build_x_compound_expr_from_list (init, ELK_INIT);
+ init = build_x_compound_expr_from_list (init, ELK_INIT,
+ tf_warning_or_error);
if (TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE
&& TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE)
@@ -5683,7 +5684,8 @@ cp_finish_decl (tree decl, tree init, bool init_co
return;
}
if (TREE_CODE (init) == TREE_LIST)
- init = build_x_compound_expr_from_list (init, ELK_INIT);
+ init = build_x_compound_expr_from_list (init, ELK_INIT,
+ tf_warning_or_error);
if (describable_type (init))
{
type = TREE_TYPE (decl) = do_auto_deduction (type, init, auto_node);
Index: cp/typeck2.c
===================================================================
--- cp/typeck2.c (revision 162298)
+++ cp/typeck2.c (working copy)
@@ -737,7 +737,8 @@ store_init_value (tree decl, tree init, int flags)
}
else
/* We get here with code like `int a (2);' */
- init = build_x_compound_expr_from_list (init, ELK_INIT);
+ init = build_x_compound_expr_from_list (init, ELK_INIT,
+ tf_warning_or_error);
}
/* End of special C++ code. */
@@ -1594,7 +1595,7 @@ build_functional_cast (tree exp, tree parms, tsubs
return cp_convert (type, integer_zero_node);
/* This must build a C cast. */
- parms = build_x_compound_expr_from_list (parms, ELK_FUNC_CAST);
+ parms = build_x_compound_expr_from_list (parms, ELK_FUNC_CAST, complain);
return cp_build_c_cast (type, parms, complain);
}
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h (revision 162298)
+++ cp/cp-tree.h (working copy)
@@ -5462,7 +5462,8 @@ extern tree cp_build_unary_op (e
extern tree unary_complex_lvalue (enum tree_code, tree);
extern tree build_x_conditional_expr (tree, tree, tree,
tsubst_flags_t);
-extern tree build_x_compound_expr_from_list (tree, expr_list_kind);
+extern tree build_x_compound_expr_from_list (tree, expr_list_kind,
+ tsubst_flags_t);
extern tree build_x_compound_expr_from_vec (VEC(tree,gc) *, const char *);
extern tree build_x_compound_expr (tree, tree, tsubst_flags_t);
extern tree build_compound_expr (location_t, tree, tree);
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [C++, committed] PR 44969 (first half)
2010-07-19 10:29 [C++, committed] PR 44969 (first half) Paolo Carlini
@ 2010-07-19 14:49 ` Jason Merrill
0 siblings, 0 replies; 2+ messages in thread
From: Jason Merrill @ 2010-07-19 14:49 UTC (permalink / raw)
To: Paolo Carlini; +Cc: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 225 bytes --]
And here's the second half: we were failing to consider the type of a
functional cast when comparing arguments, so we thought the partial
instantiation of test(int) was the same as the primary template.
Applying to trunk.
[-- Attachment #2: 44969-arg.patch --]
[-- Type: text/x-patch, Size: 3824 bytes --]
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.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 3259043..0ccd8d9 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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;
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index d62f9d7..2abd8dd 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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;
}
diff --git a/gcc/testsuite/g++.dg/template/sfinae24.C b/gcc/testsuite/g++.dg/template/sfinae24.C
new file mode 100644
index 0000000..8a50c8e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/sfinae24.C
@@ -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];
+
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2010-07-19 14:49 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-07-19 10:29 [C++, committed] PR 44969 (first half) Paolo Carlini
2010-07-19 14:49 ` Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).