OSDN Git Service

PR c++/13243
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 15 Dec 2003 16:59:56 +0000 (16:59 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 15 Dec 2003 16:59:56 +0000 (16:59 +0000)
PR c++/12573
* parser.c (cp_parser_postfix_expression): Tighten handling of
integral constant expressions.
(cp_parser_unary_expression): Likewise.
* pt.c (value_dependent_expression_p): Remove handling for
COMPONENT_REFs.

PR c++/13243
PR c++/12573
* g++.dg/template/crash14.C: New test.
* g++.dg/template/dependent-expr3.C: Add dg-error markers.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@74637 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/crash14.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/dependent-expr3.C

index 93a3719..5e4e824 100644 (file)
@@ -1,3 +1,13 @@
+2003-12-15  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/13243
+       PR c++/12573
+       * parser.c (cp_parser_postfix_expression): Tighten handling of
+       integral constant expressions.
+       (cp_parser_unary_expression): Likewise.
+       * pt.c (value_dependent_expression_p): Remove handling for
+       COMPONENT_REFs.
+
 2003-12-15  Nathan Sidwell  <nathan@codesourcery.com>
 
        * class.c (add_method): Disallow destructor for java classes.
index 4709ccb..a74e33a 100644 (file)
@@ -3637,6 +3637,15 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
            postfix_expression 
              = grok_array_decl (postfix_expression, index);
            idk = CP_ID_KIND_NONE;
+           /* Array references are not permitted in
+              constant-expressions.  */
+           if (parser->constant_expression_p)
+             {
+               if (!parser->allow_non_constant_expression_p)
+                 postfix_expression 
+                   = cp_parser_non_constant_expression ("an array reference");
+               parser->non_constant_expression_p = true;
+             }
          }
          break;
 
@@ -3658,7 +3667,11 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
            if (parser->constant_expression_p)
              {
                if (!parser->allow_non_constant_expression_p)
-                 return cp_parser_non_constant_expression ("a function call");
+                 {
+                   postfix_expression 
+                     = cp_parser_non_constant_expression ("a function call");
+                   break;
+                 }
                parser->non_constant_expression_p = true;
              }
 
@@ -3737,6 +3750,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
            bool dependent_p;
            bool template_p;
            tree scope = NULL_TREE;
+           enum cpp_ttype token_type = token->type;
 
            /* If this is a `->' operator, dereference the pointer.  */
            if (token->type == CPP_DEREF)
@@ -3839,6 +3853,15 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
               object on the left-hand side of the `.' or `->'
               operator.  */
            parser->context->object_type = NULL_TREE;
+           /* These operators may not appear in constant-expressions.  */
+           if (parser->constant_expression_p)
+             {
+               if (!parser->allow_non_constant_expression_p)
+                 postfix_expression 
+                   = (cp_parser_non_constant_expression 
+                      (token_type == CPP_DEREF ? "'->'" : "`.'"));
+               parser->non_constant_expression_p = true;
+             }
          }
          break;
 
@@ -3846,17 +3869,18 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
          /* postfix-expression ++  */
          /* Consume the `++' token.  */
          cp_lexer_consume_token (parser->lexer);
+         /* Generate a representation for the complete expression.  */
+         postfix_expression 
+           = finish_increment_expr (postfix_expression, 
+                                    POSTINCREMENT_EXPR);
          /* Increments may not appear in constant-expressions.  */
          if (parser->constant_expression_p)
            {
              if (!parser->allow_non_constant_expression_p)
-               return cp_parser_non_constant_expression ("an increment");
+               postfix_expression 
+                 = cp_parser_non_constant_expression ("an increment");
              parser->non_constant_expression_p = true;
            }
-         /* Generate a representation for the complete expression.  */
-         postfix_expression 
-           = finish_increment_expr (postfix_expression, 
-                                    POSTINCREMENT_EXPR);
          idk = CP_ID_KIND_NONE;
          break;
 
@@ -3864,17 +3888,18 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
          /* postfix-expression -- */
          /* Consume the `--' token.  */
          cp_lexer_consume_token (parser->lexer);
+         /* Generate a representation for the complete expression.  */
+         postfix_expression 
+           = finish_increment_expr (postfix_expression, 
+                                    POSTDECREMENT_EXPR);
          /* Decrements may not appear in constant-expressions.  */
          if (parser->constant_expression_p)
            {
              if (!parser->allow_non_constant_expression_p)
-               return cp_parser_non_constant_expression ("a decrement");
+               postfix_expression 
+                 = cp_parser_non_constant_expression ("a decrement");
              parser->non_constant_expression_p = true;
            }
-         /* Generate a representation for the complete expression.  */
-         postfix_expression 
-           = finish_increment_expr (postfix_expression, 
-                                    POSTDECREMENT_EXPR);
          idk = CP_ID_KIND_NONE;
          break;
 
@@ -4217,6 +4242,8 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p)
   if (unary_operator != ERROR_MARK)
     {
       tree cast_expression;
+      tree expression = error_mark_node;
+      const char *non_constant_p = NULL;
 
       /* Consume the operator token.  */
       token = cp_lexer_consume_token (parser->lexer);
@@ -4227,32 +4254,40 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p)
       switch (unary_operator)
        {
        case INDIRECT_REF:
-         return build_x_indirect_ref (cast_expression, "unary *");
-         
+         non_constant_p = "`*'";
+         expression = build_x_indirect_ref (cast_expression, "unary *");
+         break;
+
        case ADDR_EXPR:
+         non_constant_p = "`&'";
+         /* Fall through.  */
        case BIT_NOT_EXPR:
-         return build_x_unary_op (unary_operator, cast_expression);
-         
+         expression = build_x_unary_op (unary_operator, cast_expression);
+         break;
+
        case PREINCREMENT_EXPR:
        case PREDECREMENT_EXPR:
-         if (parser->constant_expression_p)
-           {
-             if (!parser->allow_non_constant_expression_p)
-               return cp_parser_non_constant_expression (PREINCREMENT_EXPR
-                                                         ? "an increment"
-                                                         : "a decrement");
-             parser->non_constant_expression_p = true;
-           }
+         non_constant_p = (unary_operator == PREINCREMENT_EXPR
+                           ? "`++'" : "`--'");
          /* Fall through.  */
        case CONVERT_EXPR:
        case NEGATE_EXPR:
        case TRUTH_NOT_EXPR:
-         return finish_unary_op_expr (unary_operator, cast_expression);
+         expression = finish_unary_op_expr (unary_operator, cast_expression);
+         break;
 
        default:
          abort ();
-         return error_mark_node;
        }
+
+      if (non_constant_p && parser->constant_expression_p)
+       {
+         if (!parser->allow_non_constant_expression_p)
+           return cp_parser_non_constant_expression (non_constant_p);
+         parser->non_constant_expression_p = true;
+       }
+
+      return expression;
     }
 
   return cp_parser_postfix_expression (parser, address_p);
index 2d31c4d..553d4f7 100644 (file)
@@ -11714,9 +11714,6 @@ value_dependent_expression_p (tree expression)
     }
   if (TREE_CODE (expression) == SCOPE_REF)
     return dependent_scope_ref_p (expression, value_dependent_expression_p);
-  if (TREE_CODE (expression) == COMPONENT_REF)
-    return (value_dependent_expression_p (TREE_OPERAND (expression, 0))
-           || value_dependent_expression_p (TREE_OPERAND (expression, 1)));
   /* A constant expression is value-dependent if any subexpression is
      value-dependent.  */
   if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expression))))
index 675122e..dd5e215 100644 (file)
@@ -1,3 +1,10 @@
+2003-12-15  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/13243
+       PR c++/12573
+       * g++.dg/template/crash14.C: New test.
+       * g++.dg/template/dependent-expr3.C: Add dg-error markers.
+
 2003-12-15  Nathan Sidwell  <nathan@codesourcery.com>
 
        * g++.dg/other/java1.C: New test.
diff --git a/gcc/testsuite/g++.dg/template/crash14.C b/gcc/testsuite/g++.dg/template/crash14.C
new file mode 100644 (file)
index 0000000..7b3af04
--- /dev/null
@@ -0,0 +1,3 @@
+template <int T> class foo { public: foo() { } class Z { };};
+template <int I[2]> void dep7(foo<I[0]> *) { } // { dg-error "" }
+
index 50673c8..2e8b805 100644 (file)
@@ -9,6 +9,6 @@ template <typename K> struct Y : K {
 };
 
 template <class T> struct Z {
-  S< (bool)(&static_cast<Y<T> *>(0)->x == 0) >
-    s;
+  S< (bool)(&static_cast<Y<T> *>(0)->x == 0) > // { dg-error "" }
+  s; // { dg-error "" }
 };