https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25814

--- Comment #19 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Marek Polacek <mpola...@gcc.gnu.org>:

https://gcc.gnu.org/g:5b2003105b35f8fe8e074c055a718c8f484d9d32

commit r11-4756-g5b2003105b35f8fe8e074c055a718c8f484d9d32
Author: Marek Polacek <pola...@redhat.com>
Date:   Fri Oct 2 09:46:30 2020 -0400

    c++: Implement -Wvexing-parse [PR25814]

    This patch implements the -Wvexing-parse warning to warn about the
    sneaky most vexing parse rule in C++: the cases when a declaration
    looks like a variable definition, but the C++ language requires it
    to be interpreted as a function declaration.  This warning is on by
    default (like clang++).  From the docs:

      void f(double a) {
        int i();        // extern int i (void);
        int n(int(a));  // extern int n (int);
      }

      Another example:

      struct S { S(int); };
      void f(double a) {
        S x(int(a));   // extern struct S x (int);
        S y(int());    // extern struct S y (int (*) (void));
        S z();         // extern struct S z (void);
      }

    You can find more on this in [dcl.ambig.res].

    I spent a fair amount of time on fix-it hints so that GCC can recommend
    various ways to resolve such an ambiguity.  Sometimes that's tricky.
    E.g., suggesting default-initialization when the class doesn't have
    a default constructor would not be optimal.  Suggesting {}-init is also
    not trivial because it can use an initializer-list constructor if no
    default constructor is available (which ()-init wouldn't do).  And of
    course, pre-C++11, we shouldn't be recommending {}-init at all.

    I also uncovered a bug in cp_parser_declarator, where we were setting
    *parenthesized_p to true despite the comment saying the exact opposite.

    gcc/c-family/ChangeLog:

            PR c++/25814
            * c.opt (Wvexing-parse): New option.

    gcc/cp/ChangeLog:

            PR c++/25814
            * cp-tree.h (enum cp_tree_index): Add CPTI_EXPLICIT_VOID_LIST.
            (explicit_void_list_node): Define.
            (PARENTHESIZED_LIST_P): New macro.
            (struct cp_declarator): Add function::parens_loc.
            * decl.c (cxx_init_decl_processing): Initialize
explicit_void_list_node.
            (grokparms): Also break when explicit_void_list_node.
            * parser.c (make_call_declarator): New location_t parameter.  Use
it
            to set declarator->u.function.parens_loc.
            (cp_parser_lambda_declarator_opt): Pass UNKNOWN_LOCATION to
            make_call_declarator.
            (warn_about_ambiguous_parse): New function.
            (cp_parser_init_declarator): Call warn_about_ambiguous_parse.
            (cp_parser_declarator): Set *parenthesized_p to false rather than
to
            true.
            (cp_parser_direct_declarator): Create a location for the function's
            parentheses and pass it to make_call_declarator.
            (cp_parser_parameter_declaration_clause): Return
explicit_void_list_node
            for (void).
            (cp_parser_parameter_declaration_list): Set PARENTHESIZED_LIST_P
            in the parameters tree.

    gcc/ChangeLog:

            PR c++/25814
            * doc/invoke.texi: Document -Wvexing-parse.

    gcc/testsuite/ChangeLog:

            PR c++/25814
            * g++.dg/cpp2a/fn-template16.C: Add a dg-warning.
            * g++.dg/cpp2a/fn-template7.C: Likewise.
            * g++.dg/lookup/pr80891-5.C: Likewise.
            * g++.dg/lto/pr79050_0.C: Add extern.
            * g++.dg/lto/pr84805_0.C: Likewise.
            * g++.dg/parse/pr58898.C: Add a dg-warning.
            * g++.dg/template/scope5.C: Likewise.
            * g++.old-deja/g++.brendan/recurse.C: Likewise.
            * g++.old-deja/g++.jason/template4.C: Likewise.
            * g++.old-deja/g++.law/arm4.C: Likewise.
            * g++.old-deja/g++.mike/for2.C: Likewise.
            * g++.old-deja/g++.other/local4.C: Likewise.
            * g++.old-deja/g++.pt/crash3.C: Likewise.
            * g++.dg/warn/Wvexing-parse.C: New test.
            * g++.dg/warn/Wvexing-parse2.C: New test.
            * g++.dg/warn/Wvexing-parse3.C: New test.
            * g++.dg/warn/Wvexing-parse4.C: New test.
            * g++.dg/warn/Wvexing-parse5.C: New test.
            * g++.dg/warn/Wvexing-parse6.C: New test.
            * g++.dg/warn/Wvexing-parse7.C: New test.

    libstdc++-v3/ChangeLog:

            PR c++/25814
            * testsuite/20_util/reference_wrapper/lwg2993.cc: Add a dg-warning.
            * testsuite/25_algorithms/generate_n/87982_neg.cc: Likewise.

Reply via email to