From patchwork Mon Aug 30 20:47:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 1522331 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=KbYeS9Mg; dkim-atps=neutral Received: from sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Gz2Tt1VDgz9sR4 for ; Tue, 31 Aug 2021 06:48:32 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0E6DD3858410 for ; Mon, 30 Aug 2021 20:48:30 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0E6DD3858410 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1630356510; bh=FRxRmNXYv0Iged1psvhLIB6F5Ylacvz7LvYnU6floSM=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=KbYeS9Mg/r0yjmYew0ex6DLeMztSgUv2GLhugdUkSImVvXMwoI6rlX5eqpkVs9xSb BbCkF3BnfqGOQGM4sqEdt0oPzwS/ZDXu7SFA0U+Kq6Lac6mxc04S3RhDjbFH6aOqFq HM5MBvf9f8u7KIedbsiXP7xgmmiNL0pxHPjJFaow= 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 BFED13858D35 for ; Mon, 30 Aug 2021 20:47:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BFED13858D35 Received: from mail-qv1-f71.google.com (mail-qv1-f71.google.com [209.85.219.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-344-IMQYbzhLPVaXwUwkaV5b3w-1; Mon, 30 Aug 2021 16:47:46 -0400 X-MC-Unique: IMQYbzhLPVaXwUwkaV5b3w-1 Received: by mail-qv1-f71.google.com with SMTP id e14-20020a056214162e00b00375ec21dd99so2580294qvw.23 for ; Mon, 30 Aug 2021 13:47:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=FRxRmNXYv0Iged1psvhLIB6F5Ylacvz7LvYnU6floSM=; b=cSDR7OGUuNaE8DqjKIvuUkq+Xw9NBTUD6ptiXbA2FC6gNDJIQbOvbxS4i6vSW+da6m 2WT6AqopTwQX8OAuX8IGmP804km2upT+hCEXJDUpEZOLANHaU8mMdL6geKewGLBI2tFG kjoG7n9aLtoVjQStFTnjclyRSc2nZVnqiGcGdNhVCYtvJ5ZU10rsvc/dswOaGdWRyfU5 uoHfOvkopT6qJynpit5Aei5euOWGuvVzBhrffb0kvDkBpBIDG/02HLrtsn06vj1pxZ48 +E++TAR/bDTEWK4YXKqc4dfybUIv6K9gMgWZVC+pwEOJCSpagnwC9Q5k8naetgV7yvdj hL3Q== X-Gm-Message-State: AOAM531h4MJCO9NhPRIhK8w6yXRFQjSmrK8lYe61eOQa9BTSTKD+S/TY pg/y5V87ZmSxof+STDVaehTwsCDR1Hqv6UkFwAsjygbiMzLkXthmUc4PJL6HhOjCODZd+TxTNbP 4HZRZHW+pvT13fWQE/5B08lY63wLUPezggDKYZvPuR0d1OYzhiSzXXeDdjE835n2GfQ== X-Received: by 2002:a0c:e983:: with SMTP id z3mr25737306qvn.1.1630356465462; Mon, 30 Aug 2021 13:47:45 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzdlNeXLqSt/s2fiYP99MFG7e24UlFa2duJjx7x7ezf3yy6amYnTfKi52apvjdiZg+ACH66NA== X-Received: by 2002:a0c:e983:: with SMTP id z3mr25737253qvn.1.1630356464914; Mon, 30 Aug 2021 13:47:44 -0700 (PDT) Received: from barrymore.redhat.com (130-44-159-43.s11817.c3-0.arl-cbr1.sbo-arl.ma.cable.rcncustomer.com. [130.44.159.43]) by smtp.gmail.com with ESMTPSA id w6sm11959861qkw.91.2021.08.30.13.47.44 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Aug 2021 13:47:44 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [pushed] c++: Add warning about missing 'requires' Date: Mon, 30 Aug 2021 16:47:42 -0400 Message-Id: <20210830204742.560432-1-jason@redhat.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.2 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, 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: Jason Merrill via Gcc-patches From: Jason Merrill Reply-To: Jason Merrill Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" I noticed that concepts-lambda14.C had two useless requires-expressions: static_assert(requires { C; }); always succeeds, because C is always a valid expression for any type, regardless of whether C is satisfied for a particular type. Presumably the user means static_assert(requires { requires C; }); to make the C a nested-requirement. Of course, static_assert(C); is much simpler and means the same thing; this is more relevant in the middle of a longer requires-expression, such as the bug this warning found in cmcstl2: template META_CONCEPT input_iterator = input_or_output_iterator && readable && requires(I& i, const I& ci) { typename iterator_category_t; derived_from, input_iterator_tag>; i++; }; where 'requires' is missing before 'derived_from'. Tested x86_64-pc-linux-gnu, applying to trunk. gcc/ChangeLog: * doc/invoke.texi: Document -Wmissing-requires. gcc/c-family/ChangeLog: * c.opt: Add -Wmissing-requires. gcc/cp/ChangeLog: * parser.c (cp_parser_simple_requirement): Warn about missing requires. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-lambda14.C: Add expected warnings. --- gcc/doc/invoke.texi | 22 +++++++++++++++++++ gcc/c-family/c.opt | 4 ++++ gcc/cp/parser.c | 19 ++++++++++++++++ .../g++.dg/cpp2a/concepts-lambda14.C | 4 ++-- 4 files changed, 47 insertions(+), 2 deletions(-) base-commit: 7465c2ed6f1a1dfb2bec4b18bcad5fe3210b3f4e diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index f7bb193b51d..8969bac664d 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -8752,6 +8752,28 @@ s x = @{ @}; This warning is included in @option{-Wextra}. To get other @option{-Wextra} warnings without this one, use @option{-Wextra -Wno-missing-field-initializers}. +@item -Wno-missing-requires +@opindex Wmissing-requires +@opindex Wno-missing-requires + +By default, the compiler warns about a concept-id appearing as a C++20 simple-requirement: + +@smallexample +bool satisfied = requires @{ C @}; +@end smallexample + +Here @samp{satisfied} will be true if @samp{C} is a valid +expression, which it is for all T. Presumably the user meant to write + +@smallexample +bool satisfied = requires @{ requires C @}; +@end smallexample + +so @samp{satisfied} is only true if concept @samp{C} is satisfied for +type @samp{T}. + +This warning can be disabled with @option{-Wno-missing-requires}. + @item -Wno-multichar @opindex Wno-multichar @opindex Wmultichar diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 91929706aff..c5fe90003f2 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -839,6 +839,10 @@ Wmissing-field-initializers C ObjC C++ ObjC++ Var(warn_missing_field_initializers) Warning EnabledBy(Wextra) Warn about missing fields in struct initializers. +Wmissing-requires +C++ ObjC++ Var(warn_missing_requires) Init(1) Warning +Warn about likely missing requires keyword. + Wmultistatement-macros C ObjC C++ ObjC++ Var(warn_multistatement_macros) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) Warn about unsafe macros expanding to multiple statements used as a body of a clause such as if, else, while, switch, or for. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index a959c71dfa3..797e70ba5bb 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -29911,6 +29911,25 @@ cp_parser_simple_requirement (cp_parser *parser) if (expr.get_location() == UNKNOWN_LOCATION) expr.set_location (start); + for (tree t = expr; ; ) + { + if (TREE_CODE (t) == TRUTH_ANDIF_EXPR + || TREE_CODE (t) == TRUTH_ORIF_EXPR) + { + t = TREE_OPERAND (t, 0); + continue; + } + if (concept_check_p (t)) + { + gcc_rich_location richloc (get_start (start)); + richloc.add_fixit_insert_before (start, "requires "); + warning_at (&richloc, OPT_Wmissing_requires, "testing " + "if a concept-id is a valid expression; add " + "% to check satisfaction"); + } + break; + } + return finish_simple_requirement (expr.get_location (), expr); } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-lambda14.C b/gcc/testsuite/g++.dg/cpp2a/concepts-lambda14.C index bdc893da857..02b6b6a8438 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-lambda14.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-lambda14.C @@ -11,9 +11,9 @@ void foo() noexcept(!__is_same(T, void)) { } template auto f() { - return [](T, bool a = requires { C; }){ + return [](T, bool a = requires { C; }){ // { dg-warning Wmissing-requires } static_assert(requires { requires C && (C || C); }); // { dg-error "assert" } - static_assert(requires { C; }); + static_assert(requires { C; }); // { dg-warning Wmissing-requires } static_assert(requires { { foo() } noexcept -> C; }); static_assert(!requires { typename T::blah; }); // { dg-error "assert" } return 0;