cp_parser_parenthesized_expression_list can leave *close_paren_loc
untouched if an error occurs; specifically when following this goto:

7402              if (expr == error_mark_node)
7403                goto skip_comma;

which can lead to cp_parser_postfix_expression attempting to
use uninitialized data for the finishing location of a
parenthesized expression.

The attached patch fixes this by having cp_parser_postfix_expression
initialize the underlying location to UNKNOWN_LOCATION, and only use
it if it's been written to.

Verified the fix manually by compiling
  g++.old-deja/g++.ns/invalid1.C
before and after under valgrind.

Successfully bootstrapped&regrtested on x86_64-pc-linux-gnu.

OK for trunk?

gcc/cp/ChangeLog:
        * parser.c (cp_parser_postfix_expression): Initialize
        close_paren_loc to UNKNOWN_LOCATION; only use it if
        it has been written to by
        cp_parser_parenthesized_expression_list.
        (cp_parser_postfix_dot_deref_expression): Likewise.
        (cp_parser_parenthesized_expression_list): Document the behavior
        with respect to the CLOSE_PAREN_LOC param.
---
 gcc/cp/parser.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index a420cf1..56dfe42 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -6664,7 +6664,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool 
address_p, bool cast_p,
            bool saved_non_integral_constant_expression_p = false;
            tsubst_flags_t complain = complain_flags (decltype_p);
            vec<tree, va_gc> *args;
-           location_t close_paren_loc;
+           location_t close_paren_loc = UNKNOWN_LOCATION;
 
             is_member_access = false;
 
@@ -6826,10 +6826,13 @@ cp_parser_postfix_expression (cp_parser *parser, bool 
address_p, bool cast_p,
                                    koenig_p,
                                    complain);
 
-           location_t combined_loc = make_location (token->location,
-                                                    start_loc,
-                                                    close_paren_loc);
-           postfix_expression.set_location (combined_loc);
+           if (close_paren_loc)
+             {
+               location_t combined_loc = make_location (token->location,
+                                                        start_loc,
+                                                        close_paren_loc);
+               postfix_expression.set_location (combined_loc);
+             }
 
            /* The POSTFIX_EXPRESSION is certainly no longer an id.  */
            idk = CP_ID_KIND_NONE;
@@ -7298,7 +7301,10 @@ cp_parser_postfix_dot_deref_expression (cp_parser 
*parser,
    plain identifier argument, normal_attr for an attribute that wants
    an expression, or non_attr if we aren't parsing an attribute list.  If
    NON_CONSTANT_P is non-NULL, *NON_CONSTANT_P indicates whether or
-   not all of the expressions in the list were constant.  */
+   not all of the expressions in the list were constant.
+   If CLOSE_PAREN_LOC is non-NULL, and no errors occur, then *CLOSE_PAREN_LOC
+   will be written to with the location of the closing parenthesis.  If
+   an error occurs, it may or may not be written to.  */
 
 static vec<tree, va_gc> *
 cp_parser_parenthesized_expression_list (cp_parser* parser,
-- 
1.8.5.3

Reply via email to