aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/pt.c21
-rw-r--r--gcc/testsuite/g++.dg/template/cast2.C13
3 files changed, 36 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6d29ff6..5793858 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2013-02-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/56238
+ * pt.c (build_non_dependent_expr): Don't try to fold
+ instantiation-dependent expressions.
+ (instantiation_dependent_r) [TRAIT_EXPR]: Split out.
+ [BIND_EXPR]: Treat as dependent.
+
2013-02-07 Jakub Jelinek <jakub@redhat.com>
PR c++/56241
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index aa127ed..29664ea 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -19863,16 +19863,13 @@ instantiation_dependent_r (tree *tp, int *walk_subtrees,
case ALIGNOF_EXPR:
case TYPEID_EXPR:
case AT_ENCODE_EXPR:
- case TRAIT_EXPR:
{
tree op = TREE_OPERAND (*tp, 0);
if (code == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (*tp))
op = TREE_TYPE (op);
if (TYPE_P (op))
{
- if (dependent_type_p (op)
- || (code == TRAIT_EXPR
- && dependent_type_p (TREE_OPERAND (*tp, 1))))
+ if (dependent_type_p (op))
return *tp;
else
{
@@ -19883,6 +19880,13 @@ instantiation_dependent_r (tree *tp, int *walk_subtrees,
break;
}
+ case TRAIT_EXPR:
+ if (dependent_type_p (TRAIT_EXPR_TYPE1 (*tp))
+ || dependent_type_p (TRAIT_EXPR_TYPE2 (*tp)))
+ return *tp;
+ *walk_subtrees = false;
+ return NULL_TREE;
+
case COMPONENT_REF:
if (TREE_CODE (TREE_OPERAND (*tp, 1)) == IDENTIFIER_NODE)
/* In a template, finish_class_member_access_expr creates a
@@ -19898,6 +19902,10 @@ instantiation_dependent_r (tree *tp, int *walk_subtrees,
else
break;
+ /* Treat statement-expressions as dependent. */
+ case BIND_EXPR:
+ return *tp;
+
default:
break;
}
@@ -20341,9 +20349,10 @@ build_non_dependent_expr (tree expr)
tree inner_expr;
#ifdef ENABLE_CHECKING
- /* Try to get a constant value for all non-type-dependent expressions in
+ /* Try to get a constant value for all non-dependent expressions in
order to expose bugs in *_dependent_expression_p and constexpr. */
- if (cxx_dialect >= cxx0x)
+ if (cxx_dialect >= cxx0x
+ && !instantiation_dependent_expression_p (expr))
maybe_constant_value (fold_non_dependent_expr_sfinae (expr, tf_none));
#endif
diff --git a/gcc/testsuite/g++.dg/template/cast2.C b/gcc/testsuite/g++.dg/template/cast2.C
new file mode 100644
index 0000000..0ce55f0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/cast2.C
@@ -0,0 +1,13 @@
+// PR c++/56238
+
+class A
+{
+ template < typename T > T& get ();
+ template < typename T > class B
+ {
+ void RemovePoint (A& value)
+ {
+ static_cast < double >(value.get < T > ());
+ }
+ };
+};