]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/cp/parser.c
re PR c++/19894 (pointer-to-void member not rejected in template)
[thirdparty/gcc.git] / gcc / cp / parser.c
index b0dee735c4867986bd20cfb2310c6ca0fba20cc0..cb389d24afe9a6112c27b8535da8d85ba8ad108d 100644 (file)
@@ -4121,10 +4121,34 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p)
          /* postfix-expression ( expression-list [opt] ) */
          {
            bool koenig_p;
-           tree args = (cp_parser_parenthesized_expression_list
-                        (parser, false, 
-                         /*cast_p=*/false,
-                         /*non_constant_p=*/NULL));
+           bool is_builtin_constant_p;
+           bool saved_integral_constant_expression_p = false;
+           bool saved_non_integral_constant_expression_p = false;
+           tree args;
+
+           is_builtin_constant_p 
+             = DECL_IS_BUILTIN_CONSTANT_P (postfix_expression);
+           if (is_builtin_constant_p)
+             {
+               /* The whole point of __builtin_constant_p is to allow
+                  non-constant expressions to appear as arguments.  */
+               saved_integral_constant_expression_p
+                 = parser->integral_constant_expression_p;
+               saved_non_integral_constant_expression_p
+                 = parser->non_integral_constant_expression_p;
+               parser->integral_constant_expression_p = false;
+             }
+           args = (cp_parser_parenthesized_expression_list
+                   (parser, /*is_attribute_list=*/false, 
+                    /*cast_p=*/false,
+                    /*non_constant_p=*/NULL));
+           if (is_builtin_constant_p)
+             {
+               parser->integral_constant_expression_p
+                 = saved_integral_constant_expression_p;
+               parser->non_integral_constant_expression_p
+                 = saved_non_integral_constant_expression_p;
+             }
 
            if (args == error_mark_node)
              {
@@ -4873,7 +4897,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p)
          non_constant_p = (unary_operator == PREINCREMENT_EXPR
                            ? "`++'" : "`--'");
          /* Fall through.  */
-       case CONVERT_EXPR:
+       case UNARY_PLUS_EXPR:
        case NEGATE_EXPR:
        case TRUTH_NOT_EXPR:
          expression = finish_unary_op_expr (unary_operator, cast_expression);
@@ -4909,7 +4933,7 @@ cp_parser_unary_operator (cp_token* token)
       return ADDR_EXPR;
 
     case CPP_PLUS:
-      return CONVERT_EXPR;
+      return UNARY_PLUS_EXPR;
 
     case CPP_MINUS:
       return NEGATE_EXPR;
@@ -10024,7 +10048,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
 
          /* Warn about attributes. They are ignored.  */
          if (attributes)
-           warning (0, "type attributes are honored only at type definition");
+           warning (OPT_Wattributes,
+                    "type attributes are honored only at type definition");
 
          type = xref_tag (tag_type, identifier, ts,
                           parser->num_template_parameter_lists);
@@ -10869,7 +10894,8 @@ cp_parser_init_declarator (cp_parser* parser,
      attributes -- but ignores them.  */
   if (cp_parser_allow_gnu_extensions_p (parser) && is_parenthesized_init)
     if (cp_parser_attributes_opt (parser))
-      warning (0, "attributes after parenthesized initializer ignored");
+      warning (OPT_Wattributes,
+              "attributes after parenthesized initializer ignored");
 
   /* For an in-class declaration, use `grokfield' to create the
      declaration.  */
@@ -12119,7 +12145,8 @@ cp_parser_parameter_declaration (cp_parser *parser,
              argument.  */
          default_argument = make_node (DEFAULT_ARG);
          DEFARG_TOKENS (default_argument)
-           = cp_token_cache_new (first_token, token);  
+           = cp_token_cache_new (first_token, token);
+         DEFARG_INSTANTIATIONS (default_argument) = NULL;
        }
       /* Outside of a class definition, we can just parse the
          assignment-expression.  */
@@ -14365,7 +14392,10 @@ cp_parser_label_declaration (cp_parser* parser)
 
       /* Look for an identifier.  */
       identifier = cp_parser_identifier (parser);
-      /* Declare it as a lobel.  */
+      /* If we failed, stop.  */
+      if (identifier == error_mark_node)
+       break;
+      /* Declare it as a label.  */
       finish_label_decl (identifier);
       /* If the next token is a `;', stop.  */
       if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
@@ -15484,6 +15514,7 @@ cp_parser_late_parsing_for_member (cp_parser* parser, tree member_function)
       if (function_scope)
        push_function_context_to (function_scope);
 
+      
       /* Push the body of the function onto the lexer stack.  */
       cp_parser_push_lexer_for_tokens (parser, tokens);
 
@@ -15492,10 +15523,17 @@ cp_parser_late_parsing_for_member (cp_parser* parser, tree member_function)
       start_preparsed_function (member_function, NULL_TREE,
                                SF_PRE_PARSED | SF_INCLASS_INLINE);
 
+      /* Don't do access checking if it is a templated function.  */
+      if (processing_template_decl)
+       push_deferring_access_checks (dk_no_check);
+      
       /* Now, parse the body of the function.  */
       cp_parser_function_definition_after_declarator (parser,
                                                      /*inline_p=*/true);
 
+      if (processing_template_decl)
+       pop_deferring_access_checks ();
+      
       /* Leave the scope of the containing function.  */
       if (function_scope)
        pop_function_context_from (function_scope);
@@ -15559,19 +15597,34 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
        parm = TREE_CHAIN (parm))
     {
       cp_token_cache *tokens;
+      tree default_arg = TREE_PURPOSE (parm);
+      tree parsed_arg;
+      VEC(tree,gc) *insts;
+      tree copy;
+      unsigned ix;
+      
+      if (!default_arg)
+       continue;
 
-      if (!TREE_PURPOSE (parm)
-         || TREE_CODE (TREE_PURPOSE (parm)) != DEFAULT_ARG)
+      if (TREE_CODE (default_arg) != DEFAULT_ARG)
+       /* This can happen for a friend declaration for a function
+          already declared with default arguments.  */
        continue;
 
        /* Push the saved tokens for the default argument onto the parser's
          lexer stack.  */
-      tokens = DEFARG_TOKENS (TREE_PURPOSE (parm));
+      tokens = DEFARG_TOKENS (default_arg);
       cp_parser_push_lexer_for_tokens (parser, tokens);
 
       /* Parse the assignment-expression.  */
-      TREE_PURPOSE (parm) = cp_parser_assignment_expression (parser,
-                                                            /*cast_p=*/false);
+      parsed_arg = cp_parser_assignment_expression (parser, /*cast_p=*/false);
+
+      TREE_PURPOSE (parm) = parsed_arg;
+
+      /* Update any instantiations we've already created.  */
+      for (insts = DEFARG_INSTANTIATIONS (default_arg), ix = 0;
+          VEC_iterate (tree, insts, ix, copy); ix++)
+       TREE_PURPOSE (copy) = parsed_arg;
 
       /* If the token stream has not been completely used up, then
         there was extra junk after the end of the default
@@ -16258,8 +16311,8 @@ cp_parser_objc_message_expression (cp_parser* parser)
 /* Parse an objc-message-receiver.
 
    objc-message-receiver:
-     type-name
      expression
+     simple-type-specifier
 
   Returns a representation of the type or expression.  */
 
@@ -16267,7 +16320,6 @@ static tree
 cp_parser_objc_message_receiver (cp_parser* parser)
 {
   tree rcv;
-  bool class_scope_p, template_p;
 
   /* An Objective-C message receiver may be either (1) a type
      or (2) an expression.  */
@@ -16277,24 +16329,9 @@ cp_parser_objc_message_receiver (cp_parser* parser)
   if (cp_parser_parse_definitely (parser))
     return rcv;
 
-  /* Look for the optional `::' operator.  */
-  cp_parser_global_scope_opt (parser, false);
-  /* Look for the nested-name-specifier.  */
-  cp_parser_nested_name_specifier_opt (parser,
-                                      /*typename_keyword_p=*/true,
-                                      /*check_dependency_p=*/true,
-                                      /*type_p=*/true,
-                                      /*is_declaration=*/true);
-  class_scope_p = (parser->scope && TYPE_P (parser->scope));
-  template_p = class_scope_p && cp_parser_optional_template_keyword (parser);
-  /* Finally, look for the class-name.  */
-  rcv = cp_parser_class_name (parser,
-                              class_scope_p,
-                              template_p,
-                              /*type_p=*/true,
-                              /*check_dependency_p=*/true,
-                              /*class_head_p=*/false,
-                              /*is_declaration=*/true);
+  rcv = cp_parser_simple_type_specifier (parser,
+                                        /*decl_specs=*/NULL,
+                                        CP_PARSER_FLAGS_NONE);
 
   return objc_get_class_reference (rcv);
 }