From patchwork Wed Sep 18 16:11:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 1986895 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=H+KZE1pF; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4X83ZR0tkQz1y1t for ; Thu, 19 Sep 2024 02:12:14 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A73C3385840F for ; Wed, 18 Sep 2024 16:12:12 +0000 (GMT) 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 ESMTP id 671BC3858D29 for ; Wed, 18 Sep 2024 16:11:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 671BC3858D29 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 671BC3858D29 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1726675910; cv=none; b=wyvvDCXOQWgDkzezNXUVuJEfsdNz7o01zMvKDR8fQN9Xnmh6B40LTzL1Il+Yrpe/IwZ3GckvVgOfHZy0am+gkCQ/iUbKYvBhNRh6ved6DQ9oB58NJgvHbhKXu2GQMuwA8Wja2ZP+lYoxk+el8zGQHtzhBZhdAchu3iKfXBmM/6w= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1726675910; c=relaxed/simple; bh=Dzft4ng0S/Am+tq5YapMA0U/o6OIXYECe5R88wXWBQo=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=cj1n3bVp/ZG9fRTpLrHV7F3Fm3bFSiV6ZhDcY/5iWpHMY+UonMWr0czLDigwDRB0wtyurJc5LpiwsILUo3FnVBLXcVl2B3MDKRB75lA9z9N/z5KVCBRk8lcIkFKTGqvyenB6hfp4CSbD30ixAjp7rIXezh38xYAMKMBHwVWVvu0= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1726675908; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type; bh=eajTFvMcfYiPiMlRvyMMxJfgw0qJ+zwRDoAugyZGKGk=; b=H+KZE1pFAF3dsYWfnZtPX3djN/qf5/vnT/l6NVj79BdqUbowSETohdgImawMLvYtMN+IWf TrwL+/MyPKahzebjYvA5h/bso/3SqDVmlciVuis8P02B7AUyPvn6VRHLUGAO7n0OOHfjGX AjtqOCk2Xqr9uPzZ7BjDB6hhx+rgyyw= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-556-KK-8bMKvNeijUtdDgLtwLw-1; Wed, 18 Sep 2024 12:11:46 -0400 X-MC-Unique: KK-8bMKvNeijUtdDgLtwLw-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 7E6C119560B8 for ; Wed, 18 Sep 2024 16:11:45 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.45.224.61]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 407E419560A3; Wed, 18 Sep 2024 16:11:44 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 48IGBfOR2859378 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Wed, 18 Sep 2024 18:11:41 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 48IGBffq2859377; Wed, 18 Sep 2024 18:11:41 +0200 Date: Wed, 18 Sep 2024 18:11:40 +0200 From: Jakub Jelinek To: "Joseph S. Myers" , Marek Polacek , Jason Merrill Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] libcpp: Add -Wtrailing-blanks warning Message-ID: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-14.5 required=5.0 tests=BAYES_00, DKIM_INVALID, DKIM_SIGNED, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Jakub Jelinek Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org Hi! Trailing blanks is something even git diff diagnoses; while it is a coding style issue, if it is so common that git diff diagnoses it, I think it could be useful to various projects to check that at compile time. Dunno if it should be included in -Wextra, currently it isn't, and due to tons of trailing whitespace in our sources, haven't enabled it for when building gcc itself either. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? Note, git diff also diagnoses indentation with tab following space, wonder if we couldn't have trivial warning options where one would simply ask for checking of indentation with no tabs, just spaces vs. indentation with tabs followed by spaces (but never tab width or more spaces in the indentation). I think that would be easy to do also on the libcpp side. Checking how much something should be exactly indented requires syntax analysis (at least some limited one) and can consider columns of first token on line, but what the exact indentation blanks were is something only libcpp knows. 2024-09-18 Jakub Jelinek libcpp/ * include/cpplib.h (struct cpp_options): Add cpp_warn_trailing_blanks member. (enum cpp_warning_reason): Add CPP_W_TRAILING_BLANKS. * internal.h (struct _cpp_line_note): Document 'B' line note. * lex.cc (_cpp_clean_line): Add 'B' line note for trailing blanks except for trailing whitespace after backslash. Formatting fix. (_cpp_process_line_notes): Emit -Wtrailing-blanks diagnostics. Formatting fixes. (lex_raw_string): Clear type on 'B' notes. gcc/ * doc/invoke.texi (Wtrailing-blanks): Document. gcc/c-family/ * c.opt (Wtrailing-blanks): New option. gcc/testsuite/ * c-c++-common/cpp/Wtrailing-blanks.c: New test. Jakub --- libcpp/include/cpplib.h.jj 2024-09-13 16:09:32.690455174 +0200 +++ libcpp/include/cpplib.h 2024-09-18 13:01:26.289338279 +0200 @@ -594,6 +594,9 @@ struct cpp_options /* True if -finput-charset= option has been used explicitly. */ bool cpp_input_charset_explicit; + /* True if -Wtrailing-blanks. */ + bool cpp_warn_trailing_blanks; + /* Dependency generation. */ struct { @@ -709,7 +712,8 @@ enum cpp_warning_reason { CPP_W_EXPANSION_TO_DEFINED, CPP_W_BIDIRECTIONAL, CPP_W_INVALID_UTF8, - CPP_W_UNICODE + CPP_W_UNICODE, + CPP_W_TRAILING_BLANKS }; /* Callback for header lookup for HEADER, which is the name of a --- libcpp/internal.h.jj 2024-09-18 09:45:36.832570227 +0200 +++ libcpp/internal.h 2024-09-18 12:36:04.386099371 +0200 @@ -318,8 +318,8 @@ struct _cpp_line_note /* Type of note. The 9 'from' trigraph characters represent those trigraphs, '\\' an escaped newline, ' ' an escaped newline with - intervening space, 0 represents a note that has already been handled, - and anything else is invalid. */ + intervening space, 'B' trailing blanks, 0 represents a note that + has already been handled, and anything else is invalid. */ unsigned int type; }; --- libcpp/lex.cc.jj 2024-09-13 16:09:32.720454758 +0200 +++ libcpp/lex.cc 2024-09-18 14:00:46.344062046 +0200 @@ -928,7 +928,7 @@ _cpp_clean_line (cpp_reader *pfile) if (p == buffer->next_line || p[-1] != '\\') break; - add_line_note (buffer, p - 1, p != d ? ' ': '\\'); + add_line_note (buffer, p - 1, p != d ? ' ' : '\\'); d = p - 2; buffer->next_line = p - 1; } @@ -943,6 +943,11 @@ _cpp_clean_line (cpp_reader *pfile) } } } + done: + if (d > buffer->next_line + && ISBLANK (d[-1]) + && CPP_OPTION (pfile, cpp_warn_trailing_blanks)) + add_line_note (buffer, d - 1, 'B'); } else { @@ -955,7 +960,6 @@ _cpp_clean_line (cpp_reader *pfile) s++; } - done: *d = '\n'; /* A sentinel note that should never be processed. */ add_line_note (buffer, d + 1, '\n'); @@ -1013,13 +1017,23 @@ _cpp_process_line_notes (cpp_reader *pfi if (note->type == '\\' || note->type == ' ') { - if (note->type == ' ' && !in_comment) - cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col, - "backslash and newline separated by space"); + if (note->type == ' ') + { + if (!in_comment) + cpp_error_with_line (pfile, CPP_DL_WARNING, + pfile->line_table->highest_line, col, + "backslash and newline separated by " + "space"); + else if (CPP_OPTION (pfile, cpp_warn_trailing_blanks)) + cpp_warning_with_line (pfile, CPP_W_TRAILING_BLANKS, + pfile->line_table->highest_line, col, + "trailing blanks"); + } if (buffer->next_line > buffer->rlimit) { - cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line_table->highest_line, col, + cpp_error_with_line (pfile, CPP_DL_PEDWARN, + pfile->line_table->highest_line, col, "backslash-newline at end of file"); /* Prevent "no newline at end of file" warning. */ buffer->next_line = buffer->rlimit; @@ -1040,15 +1054,16 @@ _cpp_process_line_notes (cpp_reader *pfi note->type, (int) _cpp_trigraph_map[note->type]); else - { - cpp_warning_with_line - (pfile, CPP_W_TRIGRAPHS, - pfile->line_table->highest_line, col, - "trigraph ??%c ignored, use -trigraphs to enable", - note->type); - } + cpp_warning_with_line (pfile, CPP_W_TRIGRAPHS, + pfile->line_table->highest_line, col, + "trigraph ??%c ignored, use -trigraphs " + "to enable", note->type); } } + else if (note->type == 'B') + cpp_warning_with_line (pfile, CPP_W_TRAILING_BLANKS, + pfile->line_table->highest_line, col, + "trailing blanks"); else if (note->type == 0) /* Already processed in lex_raw_string. */; else @@ -2539,6 +2554,12 @@ lex_raw_string (cpp_reader *pfile, cpp_t note->type = 0; note++; break; + + case 'B': + /* Don't warn about trailing blanks in raw string literals. */ + note->type = 0; + note++; + break; default: gcc_checking_assert (_cpp_trigraph_map[note->type]); --- gcc/doc/invoke.texi.jj 2024-09-12 18:15:20.458626277 +0200 +++ gcc/doc/invoke.texi 2024-09-18 14:46:39.584782466 +0200 @@ -8996,6 +8996,13 @@ will always be false. This warning is enabled by @option{-Wall}. +@opindex Wtrailing-blanks +@opindex Wno-trailing-blanks +@item -Wtrailing-blanks +Warn about trailing blanks (spaces or horizontal tabs) at the end of lines, +including inside of comments, but excluding trailing blanks in raw string +literals. This is a coding style warning. + @opindex Wtrampolines @opindex Wno-trampolines @item -Wtrampolines --- gcc/c-family/c.opt.jj 2024-09-12 18:15:20.415626861 +0200 +++ gcc/c-family/c.opt 2024-09-18 13:01:56.404927852 +0200 @@ -1450,6 +1450,10 @@ Wtraditional-conversion C ObjC Var(warn_traditional_conversion) Warning Warn of prototypes causing type conversions different from what would happen in the absence of prototype. +Wtrailing-blanks +C ObjC C++ ObjC++ CPP(cpp_warn_trailing_blanks) CppReason(CPP_W_TRAILING_BLANKS) Var(warn_trailing_blanks) Init(0) Warning +Warn about trailing blanks on lines except when in raw string literals. + Wtrigraphs C ObjC C++ ObjC++ CPP(warn_trigraphs) CppReason(CPP_W_TRIGRAPHS) Var(cpp_warn_trigraphs) Init(2) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) Warn if trigraphs are encountered that might affect the meaning of the program. --- gcc/testsuite/c-c++-common/cpp/Wtrailing-blanks.c.jj 2024-09-18 14:44:22.712636656 +0200 +++ gcc/testsuite/c-c++-common/cpp/Wtrailing-blanks.c 2024-09-18 13:21:20.898071467 +0200 @@ -0,0 +1,30 @@ +/* { dg-do compile { target { c || c++11 } } } */ +/* { dg-options "-Wtrailing-blanks" } */ + +int i; +/* { dg-warning "trailing blanks" "" { target *-*-* } .-1 } */ +int j; +/* { dg-warning "trailing blanks" "" { target *-*-* } .-1 } */ +int \ + k \ + ; +/* { dg-warning "backslash and newline separated by space" "" { target *-*-* } .-3 } */ +/* { dg-warning "backslash and newline separated by space" "" { target *-*-* } .-3 } */ +/* { dg-warning "trailing blanks" "" { target *-*-* } .-3 } */ + + + +/* { dg-warning "trailing blanks" "" { target *-*-* } .-1 } */ +const char *p = R"*|*( + + +. +)*|*"; +/* { dg-warning "trailing blanks" "" { target *-*-* } .-1 } */ +// This is a comment with trailing blank +/* { dg-warning "trailing blanks" "" { target *-*-* } .-1 } */ +/* This is a comment with trailing blanks +*/ +/* { dg-warning "trailing blanks" "" { target *-*-* } .-2 } */ +/* { dg-warning "trailing blanks" "" { target *-*-* } .+1 } */ + \ No newline at end of file