re PR c++/56238 (ICE in tree check: expected record_type or union_type or qual_union_...
authorJason Merrill <jason@redhat.com>
Sat, 9 Feb 2013 20:38:33 +0000 (15:38 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 9 Feb 2013 20:38:33 +0000 (15:38 -0500)
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.

From-SVN: r195920

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/template/cast2.C [new file with mode: 0644]

index 6d29ff6..5793858 100644 (file)
@@ -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
index aa127ed..29664ea 100644 (file)
@@ -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 (file)
index 0000000..0ce55f0
--- /dev/null
@@ -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 > ());
+    }
+  };
+};