From patchwork Thu Apr 28 14:28:16 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 616277 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3qwdqB0N0Yz9sBc for ; Fri, 29 Apr 2016 00:04:05 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=nMVwxqAN; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; q=dns; s= default; b=DaxjJQdAPh4XFFRWTQVC/zqFXQlDafYOUs7ghdqO9h1klO4ulKG+U xepX15QdJKrj9Yfp/7iY+C2heM2vVr+/oSLzwXA9vktaR5DJ86vydtNVWO8fXDQa lgM2FABUdhUqM7K6uEHl6AkADacxYPTb1NMog5xboDeideU1eMZRhA= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; s= default; bh=jAJNNLmmMXx/QcAJI06/kC+pPFc=; b=nMVwxqANDqKyT8bX6o/O wneIlNs/Ug7VbBkkSZIbyekII05F1Me/oMJ1qkU30YxtiG3ROqt7u8fAzFwliY6n GRtkgKndWLJSn/ld22TYJEYTcR31zaAcdtk9wfZr9+dhCw1yuCpi9y5nyGWHn5I8 UaxqBZPRSrfO2PxzaR4wkYs= Received: (qmail 24901 invoked by alias); 28 Apr 2016 14:03:47 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 24842 invoked by uid 89); 28 Apr 2016 14:03:47 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.9 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=Attention, RECORD_TYPE, record_type, accurate X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Thu, 28 Apr 2016 14:03:36 +0000 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8D07581F03 for ; Thu, 28 Apr 2016 14:03:35 +0000 (UTC) Received: from c64.redhat.com (vpn-235-58.phx2.redhat.com [10.3.235.58]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u3SE3YrM002851; Thu, 28 Apr 2016 10:03:35 -0400 From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 2/4] PR c++/62314: add fixit hint for "expected '; ' after class definition" Date: Thu, 28 Apr 2016 10:28:16 -0400 Message-Id: <1461853698-43954-2-git-send-email-dmalcolm@redhat.com> In-Reply-To: <1461853698-43954-1-git-send-email-dmalcolm@redhat.com> References: <1461853698-43954-1-git-send-email-dmalcolm@redhat.com> X-IsSubscribed: yes Looking over the discussion of missing semicolons in "Quality of Implementation and Attention to Detail" within http://clang.llvm.org/diagnostics.html and comparing with https://gcc.gnu.org/wiki/ClangDiagnosticsComparison I noticed that of the cases we do handle [1], there's room for improvement; we currently emit: test.c:2:11: error: expected ';' after struct definition struct a {} ^ whereas clang reportedly emits: test.c:2:12: error: expected ';' after struct struct a {} ^ ; (note the offset of the location, and the fix-it hint) The following patch gives us the latter, more readable output. Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. OK for trunk? [1] I've also filed PR c++/68970 about a case given on the clang page that we still don't handle. gcc/cp/ChangeLog: PR c++/62314 * parser.c (cp_parser_class_specifier_1): When reporting missing semicolons, use a fixit-hint to suggest insertion of a semicolon immediately after the closing brace, offsetting the reported column accordingly. gcc/testsuite/ChangeLog: PR c++/62314 * gcc/testsuite/g++.dg/parse/error5.C: Update column number of missing semicolon error. * g++.dg/pr62314-2.C: New test case. --- gcc/cp/parser.c | 19 ++++++++++++++++--- gcc/testsuite/g++.dg/parse/error5.C | 2 +- gcc/testsuite/g++.dg/pr62314-2.C | 22 ++++++++++++++++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/pr62314-2.C diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ff16f73..e3133d0 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -21440,17 +21440,30 @@ cp_parser_class_specifier_1 (cp_parser* parser) closing brace. */ if (closing_brace && TYPE_P (type) && want_semicolon) { + /* Locate the closing brace. */ cp_token_position prev = cp_lexer_previous_token_position (parser->lexer); cp_token *prev_token = cp_lexer_token_at (parser->lexer, prev); location_t loc = prev_token->location; + /* We want to suggest insertion of a ';' immediately *after* the + closing brace, so, if we can, offset the location by 1 column. */ + location_t next_loc = loc; + if (!linemap_location_from_macro_expansion_p (line_table, loc)) + next_loc = linemap_position_for_loc_and_offset (line_table, loc, 1); + + rich_location richloc (line_table, next_loc); + richloc.add_fixit_insert (next_loc, ";"); + if (CLASSTYPE_DECLARED_CLASS (type)) - error_at (loc, "expected %<;%> after class definition"); + error_at_rich_loc (&richloc, + "expected %<;%> after class definition"); else if (TREE_CODE (type) == RECORD_TYPE) - error_at (loc, "expected %<;%> after struct definition"); + error_at_rich_loc (&richloc, + "expected %<;%> after struct definition"); else if (TREE_CODE (type) == UNION_TYPE) - error_at (loc, "expected %<;%> after union definition"); + error_at_rich_loc (&richloc, + "expected %<;%> after union definition"); else gcc_unreachable (); diff --git a/gcc/testsuite/g++.dg/parse/error5.C b/gcc/testsuite/g++.dg/parse/error5.C index eb1f9c7..d14a476 100644 --- a/gcc/testsuite/g++.dg/parse/error5.C +++ b/gcc/testsuite/g++.dg/parse/error5.C @@ -13,7 +13,7 @@ class Foo { int foo() return 0; } }; // need make cp_parser_error() report more accurate column numbers. // { dg-error "30:expected '\{' at end of input" "brace" { target *-*-* } 4 } -// { dg-error "33:expected ';' after class definition" "semicolon" {target *-*-* } 4 } +// { dg-error "34:expected ';' after class definition" "semicolon" {target *-*-* } 4 } // { dg-error "35:expected declaration before '\}' token" "declaration" {target *-*-* } 4 } diff --git a/gcc/testsuite/g++.dg/pr62314-2.C b/gcc/testsuite/g++.dg/pr62314-2.C new file mode 100644 index 0000000..deb0cb7 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr62314-2.C @@ -0,0 +1,22 @@ +// { dg-options "-fdiagnostics-show-caret" } + +template +class a {} // { dg-error "11: expected .;. after class definition" } +class temp {}; +a b; +struct b { +} // { dg-error "2: expected .;. after struct definition" } + +/* Verify that we emit fixit hints. */ + +/* { dg-begin-multiline-output "" } + class a {} + ^ + ; + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + } + ^ + ; + { dg-end-multiline-output "" } */