From patchwork Mon Nov 22 22:17:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 48013 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2CE093858430 for ; Mon, 22 Nov 2021 22:18:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2CE093858430 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1637619515; bh=ot3o/vA/nYN+WRC97cZ7fSt880YuRwO+RcHIP/WVXBE=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=pHsoko7mrxPBacwWP8U4I47/KqWsSjH1zZRs7ijUGzhhtA8EObiSgUCj09qXubAJ3 tvRQXvOwVpiXGvScT+vs9PL/HFmkPvQBGIARl/rm+TelIc5Nd52mWN3xlQohGAZaNv wO4LrsgtFqRnKo8PzxpgdzHjlGOXa0NAMMglCFik= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id BD5F5385841F for ; Mon, 22 Nov 2021 22:18:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BD5F5385841F Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-150-YdYC1zDpPJi3Rkjq7c5Ugw-1; Mon, 22 Nov 2021 17:18:00 -0500 X-MC-Unique: YdYC1zDpPJi3Rkjq7c5Ugw-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 72CBD1023F4D for ; Mon, 22 Nov 2021 22:17:59 +0000 (UTC) Received: from pdp-11.redhat.com (unknown [10.22.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTP id EDBDF60843; Mon, 22 Nov 2021 22:17:58 +0000 (UTC) To: GCC Patches , Jason Merrill Subject: [PATCH] c++: Fix missing NSDMI diagnostic in C++98 [PR103347] Date: Mon, 22 Nov 2021 17:17:34 -0500 Message-Id: <20211122221734.364966-1-polacek@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-56.3 required=5.0 tests=BAYES_00, DKIM_INVALID, DKIM_SIGNED, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Marek Polacek via Gcc-patches From: Marek Polacek Reply-To: Marek Polacek Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Here the problem is that we aren't detecting a NSDMI in C++98: struct A { void *x = NULL; }; because maybe_warn_cpp0x uses input_location and that happens to point to NULL which comes from a system header. Jakub suggested changing the location to the '=', thereby avoiding the system header problem. To that end, I've added a new location_t member into cp_declarator. This member is used when this declarator is part of an init-declarator. The rest of the changes is obvious. I've also taken the liberty of adding loc_or_input_loc, since I want to avoid checking for UNKNOWN_LOCATION. Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? PR c++/103347 gcc/cp/ChangeLog: * cp-tree.h (struct cp_declarator): Add a location_t member. (maybe_warn_cpp0x): Add a location_t parameter with a default argument. (loc_or_input_loc): New. * decl.c (grokdeclarator): Use loc_or_input_loc. Pass init_loc down to maybe_warn_cpp0x. * error.c (maybe_warn_cpp0x): Add a location_t parameter. Use it. * parser.c (make_declarator): Initialize init_loc. (cp_parser_member_declaration): Set init_loc. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/nsdmi-warn1.C: New test. * g++.dg/cpp0x/nsdmi-warn1.h: New file. --- gcc/cp/cp-tree.h | 16 +++++++++--- gcc/cp/decl.c | 22 +++++++++------- gcc/cp/error.c | 32 ++++++++++++------------ gcc/cp/parser.c | 2 ++ gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.C | 10 ++++++++ gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.h | 2 ++ 6 files changed, 55 insertions(+), 29 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.h base-commit: a944b5dec3adb28ed199234d2116145ca9010d6a diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3f56cb90d14..2037082b0c7 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6231,9 +6231,11 @@ struct cp_declarator { /* If this declarator is parenthesized, this the open-paren. It is UNKNOWN_LOCATION when not parenthesized. */ location_t parenthesized; - - location_t id_loc; /* Currently only set for cdk_id, cdk_decomp and - cdk_function. */ + /* Currently only set for cdk_id, cdk_decomp and cdk_function. */ + location_t id_loc; + /* If this declarator is part of an init-declarator, the location of the + initializer. */ + location_t init_loc; /* GNU Attributes that apply to this declarator. If the declarator is a pointer or a reference, these attribute apply to the type pointed to. */ @@ -6878,7 +6880,8 @@ extern const char *lang_decl_dwarf_name (tree, int, bool); extern const char *language_to_string (enum languages); extern const char *class_key_or_enum_as_string (tree); extern void maybe_warn_variadic_templates (void); -extern void maybe_warn_cpp0x (cpp0x_warn_str str); +extern void maybe_warn_cpp0x (cpp0x_warn_str str, + location_t = input_location); extern bool pedwarn_cxx98 (location_t, int, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); extern location_t location_of (tree); extern void qualified_name_lookup_error (tree, tree, tree, @@ -7996,6 +7999,11 @@ extern bool decl_in_std_namespace_p (tree); extern void require_complete_eh_spec_types (tree, tree); extern void cxx_incomplete_type_diagnostic (location_t, const_tree, const_tree, diagnostic_t); +inline location_t +loc_or_input_loc (location_t loc) +{ + return loc == UNKNOWN_LOCATION ? input_location : loc; +} inline location_t cp_expr_loc_or_loc (const_tree t, location_t or_loc) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 9f68d1a5590..ae0e0bae9cc 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -11522,14 +11522,18 @@ grokdeclarator (const cp_declarator *declarator, if (initialized == SD_DEFAULTED || initialized == SD_DELETED) funcdef_flag = true; - location_t typespec_loc = smallest_type_location (type_quals, - declspecs->locations); - if (typespec_loc == UNKNOWN_LOCATION) - typespec_loc = input_location; - - location_t id_loc = declarator ? declarator->id_loc : input_location; - if (id_loc == UNKNOWN_LOCATION) - id_loc = input_location; + location_t typespec_loc = loc_or_input_loc (smallest_type_location + (type_quals, + declspecs->locations)); + location_t id_loc; + location_t init_loc; + if (declarator) + { + id_loc = loc_or_input_loc (declarator->id_loc); + init_loc = loc_or_input_loc (declarator->init_loc); + } + else + init_loc = id_loc = input_location; /* Look inside a declarator for the name being declared and get it as a string, for an error message. */ @@ -14042,7 +14046,7 @@ grokdeclarator (const cp_declarator *declarator, { /* An attempt is being made to initialize a non-static member. This is new in C++11. */ - maybe_warn_cpp0x (CPP0X_NSDMI); + maybe_warn_cpp0x (CPP0X_NSDMI, init_loc); /* If this has been parsed with static storage class, but errors forced staticp to be cleared, ensure NSDMI is diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 872479369ab..98c1f0e4bdf 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -4428,84 +4428,84 @@ cp_printer (pretty_printer *pp, text_info *text, const char *spec, /* Warn about the use of C++0x features when appropriate. */ void -maybe_warn_cpp0x (cpp0x_warn_str str) +maybe_warn_cpp0x (cpp0x_warn_str str, location_t loc/*=input_location*/) { if (cxx_dialect == cxx98) switch (str) { case CPP0X_INITIALIZER_LISTS: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "extended initializer lists " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_EXPLICIT_CONVERSION: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "explicit conversion operators " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_VARIADIC_TEMPLATES: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "variadic templates " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_LAMBDA_EXPR: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "lambda expressions " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_AUTO: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "C++11 auto only available with %<-std=c++11%> or " "%<-std=gnu++11%>"); break; case CPP0X_SCOPED_ENUMS: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "scoped enums only available with %<-std=c++11%> or " "%<-std=gnu++11%>"); break; case CPP0X_DEFAULTED_DELETED: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "defaulted and deleted functions " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_INLINE_NAMESPACES: if (pedantic) - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "inline namespaces " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_OVERRIDE_CONTROLS: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "override controls (override/final) " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_NSDMI: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "non-static data member initializers " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_USER_DEFINED_LITERALS: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "user-defined literals " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_DELEGATING_CTORS: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "delegating constructors " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_INHERITING_CTORS: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "inheriting constructors " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_ATTRIBUTES: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "C++11 attributes " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; case CPP0X_REF_QUALIFIER: - pedwarn (input_location, OPT_Wc__11_extensions, + pedwarn (loc, OPT_Wc__11_extensions, "ref-qualifiers " "only available with %<-std=c++11%> or %<-std=gnu++11%>"); break; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index e2b5d6842fc..162aff73f91 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1542,6 +1542,7 @@ make_declarator (cp_declarator_kind kind) declarator->declarator = NULL; declarator->parameter_pack_p = false; declarator->id_loc = UNKNOWN_LOCATION; + declarator->init_loc = UNKNOWN_LOCATION; return declarator; } @@ -27143,6 +27144,7 @@ cp_parser_member_declaration (cp_parser* parser) constant-initializer. When we call `grokfield', it will perform more stringent semantics checks. */ initializer_token_start = cp_lexer_peek_token (parser->lexer); + declarator->init_loc = initializer_token_start->location; if (function_declarator_p (declarator) || (decl_specifiers.type && TREE_CODE (decl_specifiers.type) == TYPE_DECL diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.C new file mode 100644 index 00000000000..aacc8b28255 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.C @@ -0,0 +1,10 @@ +// PR c++/103347 +// { dg-do compile { target c++11_down } } + +#include "nsdmi-warn1.h" + +struct A { + void *x = NULL; // { dg-error "11:only available" "" { target c++98_only } } + void *y{NULL}; // { dg-error "only available|extended initializer" "" { target c++98_only } } + int z = 1 + 2; // { dg-error "9:only available" "" { target c++98_only } } +}; diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.h b/gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.h new file mode 100644 index 00000000000..ee5be5a2478 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-warn1.h @@ -0,0 +1,2 @@ +#pragma GCC system_header +#define NULL (void *)0