re PR c++/70634 (ICE on valid code on x86_64-linux-gnu: Segmentation fault (program...
authorJason Merrill <jason@redhat.com>
Wed, 13 Apr 2016 15:02:23 +0000 (11:02 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 13 Apr 2016 15:02:23 +0000 (11:02 -0400)
PR c++/70634

* pt.c (instantiation_dependent_uneval_expression_p): Split out
from instantiation_dependent_expression_p.
(value_dependent_expression_p): Use it for unevaluated operands.
(instantiation_dependent_r): Don't check value-dependence.
(instantiation_dependent_expression_p): Check
value-dependence of the expression as a whole.
* cp-tree.h: Declare instantiation_dependent_uneval_expression_p.
* semantics.c (finish_decltype_type): Use it.

From-SVN: r234945

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/testsuite/g++.dg/template/dependent-expr10.C [new file with mode: 0644]

index 6942c8dd5d33c50fc202a4fb7de65a6a62f070dd..e7d23842c68278b2af1143d19479117ae7635f6e 100644 (file)
@@ -1,5 +1,15 @@
 2016-04-13  Jason Merrill  <jason@redhat.com>
 
+       PR c++/70634
+       * pt.c (instantiation_dependent_uneval_expression_p): Split out
+       from instantiation_dependent_expression_p.
+       (value_dependent_expression_p): Use it for unevaluated operands.
+       (instantiation_dependent_r): Don't check value-dependence.
+       (instantiation_dependent_expression_p): Check
+       value-dependence of the expression as a whole.
+       * cp-tree.h: Declare instantiation_dependent_uneval_expression_p.
+       * semantics.c (finish_decltype_type): Use it.
+
        * constexpr.c (potential_nondependent_constant_expression): New.
        (potential_nondependent_static_init_expression): New.
        (maybe_constant_value_1, fold_non_dependent_expr)
index ecf2a5d5a122b03af4aa72339d8155dc58df7896..a3cd834a1055745bc65127534ec3d308cad81ac5 100644 (file)
@@ -6127,6 +6127,7 @@ extern bool any_type_dependent_elements_p       (const_tree);
 extern bool type_dependent_expression_p_push   (tree);
 extern bool value_dependent_expression_p       (tree);
 extern bool instantiation_dependent_expression_p (tree);
+extern bool instantiation_dependent_uneval_expression_p (tree);
 extern bool any_value_dependent_elements_p      (const_tree);
 extern bool dependent_omp_for_p                        (tree, tree, tree, tree);
 extern tree resolve_typename_type              (tree, bool);
index 2871f339fffead7bd68a17f9a2f9eb2cd9931539..b75ac24e2b94fef7b2232656254814dde1805e70 100644 (file)
@@ -22720,7 +22720,7 @@ value_dependent_expression_p (tree expression)
         return true;
       else if (TYPE_P (expression))
        return dependent_type_p (expression);
-      return instantiation_dependent_expression_p (expression);
+      return instantiation_dependent_uneval_expression_p (expression);
 
     case AT_ENCODE_EXPR:
       /* An 'encode' expression is value-dependent if the operand is
@@ -22730,7 +22730,7 @@ value_dependent_expression_p (tree expression)
 
     case NOEXCEPT_EXPR:
       expression = TREE_OPERAND (expression, 0);
-      return instantiation_dependent_expression_p (expression);
+      return instantiation_dependent_uneval_expression_p (expression);
 
     case SCOPE_REF:
       /* All instantiation-dependent expressions should also be considered
@@ -23101,13 +23101,6 @@ instantiation_dependent_r (tree *tp, int *walk_subtrees,
     case TREE_VEC:
       return NULL_TREE;
 
-    case VAR_DECL:
-    case CONST_DECL:
-      /* A constant with a dependent initializer is dependent.  */
-      if (value_dependent_expression_p (*tp))
-       return *tp;
-      break;
-
     case TEMPLATE_PARM_INDEX:
       return *tp;
 
@@ -23133,12 +23126,6 @@ instantiation_dependent_r (tree *tp, int *walk_subtrees,
        break;
       }
 
-    case TRAIT_EXPR:
-      if (value_dependent_expression_p (*tp))
-       return *tp;
-      *walk_subtrees = false;
-      return NULL_TREE;
-
     case COMPONENT_REF:
       if (identifier_p (TREE_OPERAND (*tp, 1)))
        /* In a template, finish_class_member_access_expr creates a
@@ -23189,10 +23176,15 @@ instantiation_dependent_r (tree *tp, int *walk_subtrees,
 
    "An expression is instantiation-dependent if it is type-dependent
    or value-dependent, or it has a subexpression that is type-dependent
-   or value-dependent."  */
+   or value-dependent."
+
+   Except don't actually check value-dependence for unevaluated expressions,
+   because in sizeof(i) we don't care about the value of i.  Checking
+   type-dependence will in turn check value-dependence of array bounds/template
+   arguments as needed.  */
 
 bool
-instantiation_dependent_expression_p (tree expression)
+instantiation_dependent_uneval_expression_p (tree expression)
 {
   tree result;
 
@@ -23207,6 +23199,15 @@ instantiation_dependent_expression_p (tree expression)
   return result != NULL_TREE;
 }
 
+/* As above, but also check value-dependence of the expression as a whole.  */
+
+bool
+instantiation_dependent_expression_p (tree expression)
+{
+  return (instantiation_dependent_uneval_expression_p (expression)
+         || value_dependent_expression_p (expression));
+}
+
 /* Like type_dependent_expression_p, but it also works while not processing
    a template definition, i.e. during substitution or mangling.  */
 
index 1574e60199e4747e679ffc4062a9165623bf56fd..0487adf6018db461efb9cb246cce745f1e2f1dd3 100644 (file)
@@ -8740,7 +8740,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
   /* Depending on the resolution of DR 1172, we may later need to distinguish
      instantiation-dependent but not type-dependent expressions so that, say,
      A<decltype(sizeof(T))>::U doesn't require 'typename'.  */
-  if (instantiation_dependent_expression_p (expr))
+  if (instantiation_dependent_uneval_expression_p (expr))
     {
       type = cxx_make_type (DECLTYPE_TYPE);
       DECLTYPE_TYPE_EXPR (type) = expr;
diff --git a/gcc/testsuite/g++.dg/template/dependent-expr10.C b/gcc/testsuite/g++.dg/template/dependent-expr10.C
new file mode 100644 (file)
index 0000000..94d66fc
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/70634
+
+template < typename T >
+bool foo ()
+{
+  const int i = sizeof (i) > 1 ? sizeof (T) : 0;
+  return i > 0;
+}