From debbugs-submit-bounces@debbugs.gnu.org Sun Aug 18 05:51:34 2024 Received: (at submit) by debbugs.gnu.org; 18 Aug 2024 09:51:35 +0000 Received: from localhost ([127.0.0.1]:55467 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sfcZP-0000We-6z for submit@debbugs.gnu.org; Sun, 18 Aug 2024 05:51:34 -0400 Received: from lists.gnu.org ([209.51.188.17]:58672) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sfcZM-0000WV-TE for submit@debbugs.gnu.org; Sun, 18 Aug 2024 05:51:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sfcYh-0002k5-4e for bug-gnu-emacs@gnu.org; Sun, 18 Aug 2024 05:50:48 -0400 Received: from mout-p-102.mailbox.org ([80.241.56.152]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_CHACHA20_POLY1305:256) (Exim 4.90_1) (envelope-from ) id 1sfcYf-00045R-88 for bug-gnu-emacs@gnu.org; Sun, 18 Aug 2024 05:50:46 -0400 Received: from smtp102.mailbox.org (smtp102.mailbox.org [10.196.197.102]) (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 mout-p-102.mailbox.org (Postfix) with ESMTPS id 4WmrZN33pTz9skj for ; Sun, 18 Aug 2024 11:50:36 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aarsen.me; s=MBO0001; t=1723974636; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=pewJPwOdUBnnTLqs6S2H5ZS+XgNdmu9GVxWdKpDkKPI=; b=1cS+AQaM28qv8dCLoNVGEBSdAkJo7yFJW/LwtqE/QzubETPsCDIFWmM4aWpvjlTYhmYxG7 nQrjS+DJ9shE4+ABd3vBC/0fvqE84I8qB8qlBANhUfsKHToIpniHft4nYyrPIT1TRM7f3m D9ImCFwcgaarUwNAi9rBUdMYDj4/OtPS9OE3zvIDArcFPfQ7yKt480gBRsKRgMl4NiivCo cqwMEyoV1Pm67+hrechAS3rH5GLUcZxG6tK0DKG4GAwfqx4kbVUylC8ZlPy1khXF03CI7y L2ZxTpohVTnXyIdILJI7hLRhs4+5c5YKbtkk5qylsc2Os1fPY/bpYBSEXGWnew== From: =?utf-8?Q?Arsen_Arsenovi=C4=87?= To: bug-gnu-emacs@gnu.org Subject: CC Mode 5.35.2 (C++//l); c++-mode misindents 'if constexpr' inside lambdas X-Debbugs-Package: cc-mode Date: Sun, 18 Aug 2024 11:50:32 +0200 Message-ID: <8634n2qhw7.fsf@aarsen.me> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Received-SPF: pass client-ip=80.241.56.152; envelope-from=arsen@aarsen.me; helo=mout-p-102.mailbox.org X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-Spam-Score: -1.6 (-) X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Package: cc-mode <#secure method=3Dpgpmime mode=3Dsign> Package: cc-mode Hi! CC-mode appears to misindent the following C++ snippet: void f() { auto data_printer =3D [] (const T& data) { if constexpr (true) { if constexpr (std::same_as) std::println (" data: \"{}\"", data); else std::println (" data: {}", data); } else std::println (""); }; =20=20 if constexpr (false) { foo (); } } This example is supposed to be formatted in accordance to the default GNU style, but the 'if constexpr' in the lambda expression are misindented. This might be the case because the inline-open of the lambda gets mis-interpreted as statement-cont, so the statements in the body are indented as brace-list-intro and brace-entry-open rather than statement-block-intro and substatement-open. WRT lambda indentation generally, CC-mode appears to format lambdas in GNU style so that their '{' aligns with their '[' (i.e. aligns their compound-statement with their lambda-introducer per ISO parlance). Maybe we should consider indenting them less. For instance, that indentation leads to: std::visit ([] (const T& data) { if constexpr (!std::same_as) { if constexpr (std::same_as) std::println (" data: \"{}\"", data); else std::println (" data: {}", data); } else std::println (""); }, tok.data); ... which is /really/ aggressive. Maybe it'd be better to do something like: std::visit ([] (args) { body }, visit-args-cont); I realize this is a bit inconsistent with the rest of the style, but given that placing the introducer (and generally function arguments) on a new line does not work in the GNU C/++ style as it does in Lisp: function_name ( arg1, arg2); ... versus: (function-name arg1 arg2) Anyway, thanks in advance! Have a most lovely day. Emacs : GNU Emacs 31.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24= .42, cairo version 1.18.0) of 2024-08-13 Package: CC Mode 5.35.2 (C++//l) Buffer Style: gnu c-emacs-features: (pps-extended-state col-0-paren posix-char-classes gen-st= ring-delim gen-comment-delim syntax-properties category-properties 1-bit) current state: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D (setq c-basic-offset 2 c-comment-only-line-offset '(0 . 0) c-indent-comment-alist '((anchored-comment column . 0) (end-block space . = 1) (cpp-end-block space . 2)) c-indent-comments-syntactically-p nil c-block-comment-prefix "" c-comment-prefix-regexp '((pike-mode . "//+!?\\|\\**") (awk-mode . "#+") (= other . "//+\\|\\**")) c-doc-comment-style '((java-mode . javadoc) (pike-mode . autodoc) (c-mode = . gtkdoc) (c++-mode . gtkdoc)) c-cleanup-list '(scope-operator) c-hanging-braces-alist '((substatement-open before after) (arglist-cont-no= nempty)) c-hanging-colons-alist nil c-hanging-semi&comma-criteria '(c-semi&comma-inside-parenlist) c-backslash-column 48 c-backslash-max-column 72 c-special-indent-hook '(t c-gnu-impose-minimum) c-label-minimum-indentation 1 c-offsets-alist '((inexpr-class . +) (inexpr-statement . +) (lambda-intro-cont . +) (inlambda . 0) (template-args-cont c-lineup-template-args c-lineup-template-args-indented-from-margin) (incomposition . +) (inmodule . +) (innamespace . +) (inextern-lang . +) (composition-close . 0) (module-close . 0) (namespace-close . 0) (extern-lang-close . 0) (composition-open . 0) (module-open . 0) (namespace-open . 0) (extern-lang-open . 0) (objc-method-call-cont c-lineup-ObjC-method-call-colons c-lineup-ObjC-method-call +) (objc-method-args-cont . c-lineup-ObjC-method-args) (objc-method-intro . [0]) (friend . 0) (cpp-define-intro c-lineup-cpp-define +) (cpp-macro-cont . +) (cpp-macro . [0]) (inclass . +) (stream-op . c-lineup-streamop) (arglist-cont-nonempty c-lineup-gcc-asm-reg c-lineup-arglist) (arglist-cont c-lineup-gcc-asm-reg 0) (comment-intro c-lineup-knr-region-comment c-lineup-comment) (catch-clause . 0) (else-clause . 0) (do-while-closure . 0) (access-label . -) (case-label . 0) (substatement . +) (statement-case-intro . +) (statement . 0) (brace-entry-open . 0) (brace-list-entry . 0) (brace-list-close . 0) (block-close . 0) (block-open . 0) (inher-cont . c-lineup-multi-inher) (inher-intro . +) (member-init-cont . c-lineup-multi-inher) (member-init-intro . +) (annotation-var-cont . +) (annotation-top-cont . 0) (constraint-cont . +) (topmost-intro . 0) (knr-argdecl . 0) (func-decl-cont . +) (inline-close . 0) (class-close . 0) (class-open . 0) (defun-block-intro . +) (defun-close . 0) (defun-open . 0) (c . c-lineup-C-comments) (string . c-lineup-dont-change) (topmost-intro-cont first c-lineup-topmost-intro-cont c-lineup-gnu-DEFUN-intro-cont) (brace-list-intro first c-lineup-2nd-brace-entry-in-arglist c-lineup-class-decl-init-+ +) (brace-list-open . +) (inline-open . 0) (arglist-close . c-lineup-arglist) (arglist-intro . c-lineup-arglist-intro-after-paren) (statement-cont . +) (statement-case-open . +) (label . 0) (substatement-label . 0) (substatement-open . +) (knr-argdecl-intro . 5) (statement-block-intro . +) ) c-buffer-is-cc-mode 'c++-mode c-tab-always-indent t c-syntactic-indentation t c-syntactic-indentation-in-macros t c-ignore-auto-fill '(string cpp code) c-auto-align-backslashes t c-backspace-function 'backward-delete-char-untabify c-delete-function 'delete-char c-electric-pound-behavior nil c-default-style '((java-mode . "java") (awk-mode . "awk") (other . "gnu")) c-enable-xemacs-performance-kludge-p nil c-old-style-variable-behavior nil defun-prompt-regexp nil tab-width 8 comment-column 32 parse-sexp-ignore-comments t parse-sexp-lookup-properties t auto-fill-function 'c-do-auto-fill comment-multi-line t comment-start-skip "\\(?://+\\|/\\*+\\)\\s *" fill-prefix nil fill-column 79 paragraph-start "[ ]*\\(//+\\|\\**\\)[ ]*$\\|^\f" adaptive-fill-mode t adaptive-fill-regexp "[ ]*\\(//+\\|\\**\\)[ ]*\\([-=E2=80=93!|#%;>*=C2= =B7=E2=80=A2=E2=80=A3=E2=81=83=E2=97=A6 ]*\\)" ) --=20 Arsen Arsenovi=C4=87 From debbugs-submit-bounces@debbugs.gnu.org Sun Aug 18 11:04:21 2024 Received: (at 72695) by debbugs.gnu.org; 18 Aug 2024 15:04:21 +0000 Received: from localhost ([127.0.0.1]:56484 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sfhS9-0000mP-By for submit@debbugs.gnu.org; Sun, 18 Aug 2024 11:04:21 -0400 Received: from mail.muc.de ([193.149.48.3]:53792) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sfhS7-0000lz-MK for 72695@debbugs.gnu.org; Sun, 18 Aug 2024 11:04:20 -0400 Received: (qmail 73700 invoked by uid 3782); 18 Aug 2024 17:03:32 +0200 Received: from muc.de (p4fe15e55.dip0.t-ipconnect.de [79.225.94.85]) (using STARTTLS) by colin.muc.de (tmda-ofmipd) with ESMTP; Sun, 18 Aug 2024 17:03:31 +0200 Received: (qmail 16605 invoked by uid 1000); 18 Aug 2024 15:03:31 -0000 Date: Sun, 18 Aug 2024 15:03:31 +0000 To: Arsen =?utf-8?Q?Arsenovi=C4=87?= Subject: Re: bug#72695: CC Mode 5.35.2 (C++//l); c++-mode misindents 'if constexpr' inside lambdas Message-ID: References: <8634n2qhw7.fsf@aarsen.me> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <8634n2qhw7.fsf@aarsen.me> X-Submission-Agent: TMDA/1.3.x (Ph3nix) From: Alan Mackenzie X-Primary-Address: acm@muc.de X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 72695 Cc: acm@muc.de, 72695@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hello, Arsen. Thanks for the bug report! On Sun, Aug 18, 2024 at 11:50:32 +0200, Arsen Arsenović via CC-Mode-help wrote: > Package: cc-mode > <#secure method=pgpmime mode=sign> > Package: cc-mode > Hi! > CC-mode appears to misindent the following C++ snippet: > void f() > { > auto data_printer = [] > (const T& data) > { > if constexpr (true) > { > if constexpr (std::same_as) > std::println (" data: \"{}\"", data); > else > std::println (" data: {}", data); > } > else > std::println (""); > }; > if constexpr (false) > { > foo (); > } > } > This example is supposed to be formatted in accordance to the default > GNU style, but the 'if constexpr' in the lambda expression are > misindented. Yes. > This might be the case because the inline-open of the lambda gets > mis-interpreted as statement-cont, so the statements in the body are > indented as brace-list-intro and brace-entry-open rather than > statement-block-intro and substatement-open. It's definitely something to do with the lambda function. If I comment out Lines 3 and 4, the remainder of the function then indents correctly. As you remark, at the moment some lines are being wrongly analysed as brace-list constructs. > WRT lambda indentation generally, CC-mode appears to format lambdas in > GNU style so that their '{' aligns with their '[' (i.e. aligns their > compound-statement with their lambda-introducer per ISO parlance). > Maybe we should consider indenting them less. .... OK. I'll fix the "brace-list" indentation bug first, then come back to this lambda indentation problem. [ .... ] > Anyway, thanks in advance! > Have a most lovely day. And yourself, too! [ .... ] -- Alan Mackenzie (Nuremberg, Germany). From debbugs-submit-bounces@debbugs.gnu.org Wed Aug 21 16:41:32 2024 Received: (at 72695) by debbugs.gnu.org; 21 Aug 2024 20:41:32 +0000 Received: from localhost ([127.0.0.1]:36406 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sgs96-0007ci-0I for submit@debbugs.gnu.org; Wed, 21 Aug 2024 16:41:32 -0400 Received: from mout-p-101.mailbox.org ([80.241.56.151]:34502) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sgs92-0007cR-W8 for 72695@debbugs.gnu.org; Wed, 21 Aug 2024 16:41:30 -0400 Received: from smtp102.mailbox.org (smtp102.mailbox.org [10.196.197.102]) (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 mout-p-101.mailbox.org (Postfix) with ESMTPS id 4WpyrP6zrqz9smr; Wed, 21 Aug 2024 22:40:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aarsen.me; s=MBO0001; t=1724272806; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=ja0WuJqwEIOfIGua/SKwkgfAt0rD9FeWEnBI7TzHcqI=; b=gPmnENGpbqVQ+XSmvqcpcnPYXo3YuVqODz3YnwlnvRfKWbhWV8DxrdUaPWJfw7VV5bpiA+ etVGuesZn/FcAAM9ZTV5GAJe7ic6JPaEXgTD+ObutlzVjVd4Xq1m6uTHWFx3Dlgv+vPaW3 veTR2erm3aNL1OoKc4dFoHlX+UTiVc5Dzp5K4DR8ogTLkjp5idnXAi6urgtbG+yz17rrP9 fzZObwcThT+CsWUG4gJraVKWn7noHsOG5Xi8ILLklFKIuViTqJiJU5dcq1jYOimbpY3waS PStpYQrVEMXYhGNCLDIIDp2nM+2TrNmPeNoUiRVq/mYjsiIoMH9i/N4d9Pt4WA== From: =?utf-8?Q?Arsen_Arsenovi=C4=87?= To: Alan Mackenzie Subject: Re: bug#72695: CC Mode 5.35.2 (C++//l); c++-mode misindents 'if constexpr' inside lambdas In-Reply-To: (Alan Mackenzie's message of "Sun, 18 Aug 2024 15:03:31 +0000") References: <8634n2qhw7.fsf@aarsen.me> Date: Wed, 21 Aug 2024 22:40:02 +0200 Message-ID: <86wmk9vcd9.fsf@aarsen.me> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 72695 Cc: 72695@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hello Alan, Alan Mackenzie writes: > Hello, Arsen. > > Thanks for the bug report! My pleasure. Thanks for being as fast as always. > On Sun, Aug 18, 2024 at 11:50:32 +0200, Arsen Arsenovi=C4=87 via CC-Mode-= help wrote: >> Package: cc-mode > >> <#secure method=3Dpgpmime mode=3Dsign> >> Package: cc-mode >> Hi! > >> CC-mode appears to misindent the following C++ snippet: > >> void f() >> { >> auto data_printer =3D [] >> (const T& data) >> { >> if constexpr (true) >> { >> if constexpr (std::same_as) >> std::println (" data: \"{}\"", data); >> else >> std::println (" data: {}", data); >> } >> else >> std::println (""); >> }; >=20=20=20 >> if constexpr (false) >> { >> foo (); >> } >> } > >> This example is supposed to be formatted in accordance to the default >> GNU style, but the 'if constexpr' in the lambda expression are >> misindented. > > Yes. > >> This might be the case because the inline-open of the lambda gets >> mis-interpreted as statement-cont, so the statements in the body are >> indented as brace-list-intro and brace-entry-open rather than >> statement-block-intro and substatement-open. > > It's definitely something to do with the lambda function. If I comment > out Lines 3 and 4, the remainder of the function then indents correctly. > As you remark, at the moment some lines are being wrongly analysed as > brace-list constructs. > >> WRT lambda indentation generally, CC-mode appears to format lambdas in >> GNU style so that their '{' aligns with their '[' (i.e. aligns their >> compound-statement with their lambda-introducer per ISO parlance). >> Maybe we should consider indenting them less. .... > > OK. I'll fix the "brace-list" indentation bug first, then come back to > this lambda indentation problem. Thank you very much! In the in-between time since I've sent this bug report with a feature request snuck in, I've noticed the following in the GCC code: stattype =3D (cp_build_type_attribute_variant (stattype, TYPE_ATTRIBUTES (optype))); ... which clued me into a different way to get the effect Lisp had, so I figured out I can use the same trick for nested multi-line constructs: (std::visit ([] (const T& data) { if constexpr (!std::same_as) { if constexpr (std::same_as) /* TODO(arsen): use {:?} here */ std::println (" data: \"{}\"", data); else std::println (" data: {}", data); } else std::println (""); }, tok.data)); } ... which is an okay immitation of what Lisp does, and seems to provide okay indentation here. So maybe it's best not to avoid messing with peoples styles ;) - please do not worry about the latter part of my original message. Thank you again! Have a lovely evening. =2D-=20 Arsen Arsenovi=C4=87 --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iOYEARYKAI4WIQT+4rPRE/wAoxYtYGFSwpQwHqLEkwUCZsZQol8UgAAAAAAuAChp c3N1ZXItZnByQG5vdGF0aW9ucy5vcGVucGdwLmZpZnRoaG9yc2VtYW4ubmV0RkVF MkIzRDExM0ZDMDBBMzE2MkQ2MDYxNTJDMjk0MzAxRUEyQzQ5MxAcYXJzZW5AYWFy c2VuLm1lAAoJEFLClDAeosSTuGQBAJvPE1mRhhDVpM6IDkdOnsdjhuDqfDAxzfB6 sXpXvRCWAPwPXdzwsiw0CDvyVagPqTuIsmpFBitRUw5fTY/0H7b3CA== =3GJj -----END PGP SIGNATURE----- --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Fri Aug 30 13:51:45 2024 Received: (at 72695) by debbugs.gnu.org; 30 Aug 2024 17:51:45 +0000 Received: from localhost ([127.0.0.1]:53416 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sk5mj-0006bB-6m for submit@debbugs.gnu.org; Fri, 30 Aug 2024 13:51:45 -0400 Received: from mail.muc.de ([193.149.48.3]:57793) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sk5md-0006ap-Ub for 72695@debbugs.gnu.org; Fri, 30 Aug 2024 13:51:43 -0400 Received: (qmail 46001 invoked by uid 3782); 30 Aug 2024 19:50:35 +0200 Received: from muc.de (p4fe15e8f.dip0.t-ipconnect.de [79.225.94.143]) (using STARTTLS) by colin.muc.de (tmda-ofmipd) with ESMTP; Fri, 30 Aug 2024 19:50:35 +0200 Received: (qmail 23185 invoked by uid 1000); 30 Aug 2024 17:50:35 -0000 Date: Fri, 30 Aug 2024 17:50:35 +0000 To: Arsen =?utf-8?Q?Arsenovi=C4=87?= Subject: Re: bug#72695: CC Mode 5.35.2 (C++//l); c++-mode misindents 'if constexpr' inside lambdas Message-ID: References: <8634n2qhw7.fsf@aarsen.me> <86wmk9vcd9.fsf@aarsen.me> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <86wmk9vcd9.fsf@aarsen.me> X-Submission-Agent: TMDA/1.3.x (Ph3nix) From: Alan Mackenzie X-Primary-Address: acm@muc.de X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 72695 Cc: 72695@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hello, Arsen. A short progress report. On Wed, Aug 21, 2024 at 22:40:02 +0200, Arsen Arsenović wrote: > Hello Alan, > Alan Mackenzie writes: > > Thanks for the bug report! > My pleasure. Thanks for being as fast as always. I apologise for not having been as fast over the last few days. Partly, I'm bringing up a new computer, which never goes as fast as one would like. But mainly I'm struggling with the unfathomable complexity of C++ lambda functions, as documented on https://en.cppreference.com/w/cpp/language/lambda. In my not so humble opinion, the C++ standards people have completely lost the plot. The number of special cases in just the syntax, apparently just to save a few characters from a program's text, has got beyond the point where anybody can grasp it. Nobody in this group of people appears to be able to say "STOP!", though somebody sorely needs to. I dread to think what will be coming out in C++26. :-( Anyhow, I've spent all afternoon on the problem so far, and I think I can see my way to a solution. It will still take a few more days yet, I'm afraid. [ .... ] > > OK. I'll fix the "brace-list" indentation bug first, then come back to > > this lambda indentation problem. > Thank you very much! [ .... ] > -- > Arsen Arsenović -- Alan Mackenzie (Nuremberg, Germany). From debbugs-submit-bounces@debbugs.gnu.org Fri Aug 30 20:55:16 2024 Received: (at 72695) by debbugs.gnu.org; 31 Aug 2024 00:55:16 +0000 Received: from localhost ([127.0.0.1]:53617 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1skCOZ-0001sH-Us for submit@debbugs.gnu.org; Fri, 30 Aug 2024 20:55:16 -0400 Received: from mout-p-101.mailbox.org ([80.241.56.151]:56368) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1skCOW-0001rr-9O for 72695@debbugs.gnu.org; Fri, 30 Aug 2024 20:55:14 -0400 Received: from smtp2.mailbox.org (smtp2.mailbox.org [IPv6:2001:67c:2050:b231:465::2]) (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 mout-p-101.mailbox.org (Postfix) with ESMTPS id 4Wwc3K2BpQz9sc2; Sat, 31 Aug 2024 02:54:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aarsen.me; s=MBO0001; t=1725065645; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=rW6EvgaBmkQDJgdrEHiWv/4XIDG5LHEPzUHlfH904x0=; b=sWg5jzmv+m5lsOp05V1vs8jluWBvatg6taJ5CsUPgpbbe22KvtotxPwELzIpsy81S48YU0 BDtAprLZq/fnh+6Li1SXpG1s78NtrPfkDamjol2TFn+Ut3Il12BfGyvwiZvs6XkPnadoIj gzvVu50u4nRVc2B84j0ysOWaVpoU3QrG8rncfgHevBLZhj43HEKUAf3U83UIaJ+ROKOQ+8 8J+YkyN8He1I7en/Cbu7NZTXFgthT2t14vmQ8nZsj0rr2KhdBYV8Tjwae+/YUTiZ1u1BdF 6LoA+rPqtbMF8IXEJjj2zKDcG52aOu+AKH70JXUVM7XAqwUvJh2YJO3oUjJ0Cw== From: =?utf-8?Q?Arsen_Arsenovi=C4=87?= To: Alan Mackenzie Subject: Re: bug#72695: CC Mode 5.35.2 (C++//l); c++-mode misindents 'if constexpr' inside lambdas In-Reply-To: (Alan Mackenzie's message of "Fri, 30 Aug 2024 17:50:35 +0000") References: <8634n2qhw7.fsf@aarsen.me> <86wmk9vcd9.fsf@aarsen.me> Date: Sat, 31 Aug 2024 02:54:01 +0200 Message-ID: <875xrhtsuu.fsf@aarsen.me> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Rspamd-Queue-Id: 4Wwc3K2BpQz9sc2 X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 72695 Cc: 72695@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hello, Alan, Alan Mackenzie writes: > Hello, Arsen. > > A short progress report. > > On Wed, Aug 21, 2024 at 22:40:02 +0200, Arsen Arsenovi=C4=87 wrote: >> Hello Alan, > >> Alan Mackenzie writes: >> > Thanks for the bug report! > >> My pleasure. Thanks for being as fast as always. > > I apologise for not having been as fast over the last few days. Partly, > I'm bringing up a new computer, which never goes as fast as one would > like. No worries, of course! Hope the setup went well. > But mainly I'm struggling with the unfathomable complexity of C++ lambda > functions, as documented on > https://en.cppreference.com/w/cpp/language/lambda. It should be quite simple - just a few optional productions preceded by an introducer production (see https://eel.is/c++draft/expr.prim.lambda for a formal grammar - this is the text from the standard draft). > In my not so humble opinion, the C++ standards people have completely > lost the plot. Should help be necessary, I do work on G++ so I'm quite familiar with the language. Feel free to ping me. > The number of special cases in just the syntax, apparently just to > save a few characters from a program's text, has got beyond the point > where anybody can grasp it. Nobody in this group of people appears to > be able to say "STOP!", though somebody sorely needs to. I dread to > think what will be coming out in C++26. :-( It really shouldn't be that bad - I'll help demystify if need be. > Anyhow, I've spent all afternoon on the problem so far, and I think I can > see my way to a solution. It will still take a few more days yet, I'm > afraid. Thank you very much! My apologies for the trouble. Have a lovely day. =2D-=20 Arsen Arsenovi=C4=87 --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iIYEARYKAC4WIQT+4rPRE/wAoxYtYGFSwpQwHqLEkwUCZtJpqRAcYXJzZW5AYWFy c2VuLm1lAAoJEFLClDAeosSTkqAA/0lWIc81IC2RVGYHISUyhJ+lvys/+ULDriEC DCOx2GZlAQCye6Cgqazz9cF2H4D5RXLH4Xu2ZPkDYDAGeApwSl/dCg== =Z1N4 -----END PGP SIGNATURE----- --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Sat Aug 31 13:02:18 2024 Received: (at 72695) by debbugs.gnu.org; 31 Aug 2024 17:02:18 +0000 Received: from localhost ([127.0.0.1]:55896 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1skRUP-0005dP-1o for submit@debbugs.gnu.org; Sat, 31 Aug 2024 13:02:18 -0400 Received: from mail.muc.de ([193.149.48.3]:26730) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1skRUL-0005cx-SY for 72695@debbugs.gnu.org; Sat, 31 Aug 2024 13:02:15 -0400 Received: (qmail 34360 invoked by uid 3782); 31 Aug 2024 19:01:08 +0200 Received: from muc.de (p4fe15282.dip0.t-ipconnect.de [79.225.82.130]) (using STARTTLS) by colin.muc.de (tmda-ofmipd) with ESMTP; Sat, 31 Aug 2024 19:01:08 +0200 Received: (qmail 10741 invoked by uid 1000); 31 Aug 2024 17:01:07 -0000 Date: Sat, 31 Aug 2024 17:01:07 +0000 To: Arsen =?utf-8?Q?Arsenovi=C4=87?= Subject: Re: bug#72695: CC Mode 5.35.2 (C++//l); c++-mode misindents 'if constexpr' inside lambdas Message-ID: References: <8634n2qhw7.fsf@aarsen.me> <86wmk9vcd9.fsf@aarsen.me> <875xrhtsuu.fsf@aarsen.me> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <875xrhtsuu.fsf@aarsen.me> X-Submission-Agent: TMDA/1.3.x (Ph3nix) From: Alan Mackenzie X-Primary-Address: acm@muc.de X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 72695 Cc: 72695@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hello again, Arsen. On Sat, Aug 31, 2024 at 02:54:01 +0200, Arsen Arsenović wrote: > Hello, Alan, > Alan Mackenzie writes: > > Hello, Arsen. > > A short progress report. > > On Wed, Aug 21, 2024 at 22:40:02 +0200, Arsen Arsenović wrote: > >> Hello Alan, > >> Alan Mackenzie writes: > >> > Thanks for the bug report! > >> My pleasure. Thanks for being as fast as always. > > I apologise for not having been as fast over the last few days. Partly, > > I'm bringing up a new computer, which never goes as fast as one would > > like. > No worries, of course! Hope the setup went well. It's going well, thanks! At the current rate of progress, I'll have my mail setup set up by this time next week, and that is the point at which, at least for me, my new machine becomes my current machine. > > But mainly I'm struggling with the unfathomable complexity of C++ lambda > > functions, as documented on > > https://en.cppreference.com/w/cpp/language/lambda. > It should be quite simple - just a few optional productions preceded by > an introducer production (see https://eel.is/c++draft/expr.prim.lambda > for a formal grammar - this is the text from the standard draft). > > In my not so humble opinion, the C++ standards people have completely > > lost the plot. > Should help be necessary, I do work on G++ so I'm quite familiar with > the language. Feel free to ping me. Thanks! It's just that the explanatory text on en.cppreference.com about just lambda functions takes 20 scrolls of ~45 lines per scroll, coming out at many hundreds of lines, just for lambda functions. I feel that the entire language part of Emacs Lisp could fit into that quite comfortably, at the same density. > > The number of special cases in just the syntax, apparently just to > > save a few characters from a program's text, has got beyond the point > > where anybody can grasp it. Nobody in this group of people appears to > > be able to say "STOP!", though somebody sorely needs to. I dread to > > think what will be coming out in C++26. :-( > It really shouldn't be that bad - I'll help demystify if need be. Thanks! > > Anyhow, I've spent all afternoon on the problem so far, and I think I can > > see my way to a solution. It will still take a few more days yet, I'm > > afraid. > Thank you very much! My apologies for the trouble. No apologies called for. You raised a bug report, for which thanks! Anyhow, I've got a first version, incompletely tested, of a new handling for a lambda expression. The patch is not nearly as big as it looks, two thirds of it is just re-indenting a large function I put an extra `if' form aroun. Would you please apply this patch, which should fix the test case, and then test it out on your real C++ code, then let me know how it's gone. I'll see if I can get some new test cases written. Thanks! diff -r 48ad661a2d7d cc-engine.el --- a/cc-engine.el Mon Jul 22 12:09:34 2024 +0000 +++ b/cc-engine.el Sat Aug 31 16:44:39 2024 +0000 @@ -13178,229 +13178,223 @@ ;; ;; Here, "brace list" does not include the body of an enum. (save-excursion - (let ((start (point)) - (braceassignp 'dontknow) - inexpr-brace-list bufpos macro-start res pos after-type-id-pos - pos2 in-paren parens-before-brace - paren-state paren-pos) - - (setq res - (or (progn (c-backward-syntactic-ws) - (c-back-over-compound-identifier)) - (c-backward-token-2 1 t lim))) - ;; Checks to do only on the first sexp before the brace. - ;; Have we a C++ initialization, without an "="? - (if (and (c-major-mode-is 'c++-mode) - (cond - ((and (or (not (memq res '(t 0))) - (eq (char-after) ?,)) - (setq paren-state (c-parse-state)) - (setq paren-pos (c-pull-open-brace paren-state)) - (eq (char-after paren-pos) ?\()) - (goto-char paren-pos) - (setq braceassignp 'c++-noassign - in-paren 'in-paren)) - ((looking-at c-pre-brace-non-bracelist-key) - (setq braceassignp nil)) - ((and - (looking-at c-fun-name-substitute-key) - (not (eq (char-after (match-end 0)) ?_))) - (setq braceassignp nil)) - ((looking-at c-return-key)) - ((and (looking-at c-symbol-start) - (not (looking-at c-keywords-regexp))) - (if (save-excursion - (and (zerop (c-backward-token-2 1 t lim)) - (looking-at c-pre-id-bracelist-key))) - (setq braceassignp 'c++-noassign) - (setq after-type-id-pos (point)))) - ((eq (char-after) ?\() - (setq parens-before-brace t) - ;; Have we a requires with a parenthesis list? - (when (save-excursion - (and (zerop (c-backward-token-2 1 nil lim)) - (looking-at c-fun-name-substitute-key) - (not (eq (char-after (match-end 0)) ?_)))) + (unless (and (c-major-mode-is 'c++-mode) + (c-backward-over-lambda-expression lim)) + (let ((start (point)) + (braceassignp 'dontknow) + inexpr-brace-list bufpos macro-start res pos after-type-id-pos + pos2 in-paren ;; parens-before-brace STOUGH, 2024-08-31 + paren-state paren-pos) + + (setq res + (or (progn (c-backward-syntactic-ws) + (c-back-over-compound-identifier)) + (c-backward-token-2 1 t lim))) + ;; Checks to do only on the first sexp before the brace. + ;; Have we a C++ initialization, without an "="? + (if (and (c-major-mode-is 'c++-mode) + (cond + ((and (or (not (memq res '(t 0))) + (eq (char-after) ?,)) + (setq paren-state (c-parse-state)) + (setq paren-pos (c-pull-open-brace paren-state)) + (eq (char-after paren-pos) ?\()) + (goto-char paren-pos) + (setq braceassignp 'c++-noassign + in-paren 'in-paren)) + ((looking-at c-pre-brace-non-bracelist-key) (setq braceassignp nil)) - nil) - (t nil)) - (save-excursion - (cond - ((or (not (memq res '(t 0))) - (eq (char-after) ?,)) - (and (setq paren-state (c-parse-state)) - (setq paren-pos (c-pull-open-brace paren-state)) - (eq (char-after paren-pos) ?\() - (setq in-paren 'in-paren) - (goto-char paren-pos))) - ((looking-at c-pre-brace-non-bracelist-key)) + ((and + (looking-at c-fun-name-substitute-key) + (not (eq (char-after (match-end 0)) ?_))) + (setq braceassignp nil)) ((looking-at c-return-key)) ((and (looking-at c-symbol-start) - (not (looking-at c-keywords-regexp)) - (save-excursion - (and (zerop (c-backward-token-2 1 t lim)) - (looking-at c-pre-id-bracelist-key))))) - (t (setq after-type-id-pos (point)) - nil)))) - (setq braceassignp 'c++-noassign)) - - (when (and c-opt-inexpr-brace-list-key - (eq (char-after) ?\[)) - ;; In Java, an initialization brace list may follow - ;; directly after "new Foo[]", so check for a "new" - ;; earlier. - (while (eq braceassignp 'dontknow) - (setq braceassignp - (cond ((/= (c-backward-token-2 1 t lim) 0) nil) - ((looking-at c-opt-inexpr-brace-list-key) - (setq inexpr-brace-list t) - t) - ((looking-at "\\sw\\|\\s_\\|[.[]") - ;; Carry on looking if this is an - ;; identifier (may contain "." in Java) - ;; or another "[]" sexp. - 'dontknow) - (t nil))))) - - (setq pos (point)) - (cond - ((not braceassignp) - nil) - ((and after-type-id-pos - (goto-char after-type-id-pos) - (setq res (c-back-over-member-initializers)) - (goto-char res) - (eq (car (c-beginning-of-decl-1 lim)) 'same)) - (cons (point) nil)) ; Return value. - - ((and after-type-id-pos - (progn - (c-backward-syntactic-ws) - (eq (char-before) ?\())) - ;; Single identifier between '(' and '{'. We have a bracelist. - (cons after-type-id-pos 'in-paren)) - - ;; Are we at the parens of a C++ lambda expression? - ((and parens-before-brace - (save-excursion - (and - (zerop (c-backward-token-2 1 t lim)) - (c-looking-at-c++-lambda-capture-list)))) - nil) ; a lambda expression isn't a brace list. - - (t - (goto-char pos) - (when (eq braceassignp 'dontknow) - (let* ((cache-entry (and containing-sexp - (c-laomib-get-cache containing-sexp pos))) - (lim2 (or (cadr cache-entry) lim)) - sub-bassign-p) - (if cache-entry - (cond - ((<= (point) (cadr cache-entry)) - ;; We're inside the region we've already scanned over, so - ;; just go to that scan's end position. - (goto-char (nth 2 cache-entry)) - (setq braceassignp (nth 3 cache-entry))) - ((> (point) (cadr cache-entry)) - ;; We're beyond the previous scan region, so just scan as - ;; far as the end of that region. - (setq sub-bassign-p (c-laomib-loop lim2)) - (if (<= (point) (cadr cache-entry)) - (progn - (c-laomib-put-cache containing-sexp - start (nth 2 cache-entry) - (nth 3 cache-entry) ;; sub-bassign-p - ) - (setq braceassignp (nth 3 cache-entry)) - (goto-char (nth 2 cache-entry))) - (c-laomib-put-cache containing-sexp - start (point) sub-bassign-p) - (setq braceassignp sub-bassign-p))) - (t)) - - (setq braceassignp (c-laomib-loop lim)) - (when lim - (c-laomib-put-cache lim start (point) braceassignp))))) - + (not (looking-at c-keywords-regexp))) + (if (save-excursion + (and (zerop (c-backward-token-2 1 t lim)) + (looking-at c-pre-id-bracelist-key))) + (setq braceassignp 'c++-noassign) + (setq after-type-id-pos (point)))) + ((eq (char-after) ?\() + ;; (setq parens-before-brace t) STOUGH, 2024-08-31 + ;; Have we a requires with a parenthesis list? + (when (save-excursion + (and (zerop (c-backward-token-2 1 nil lim)) + (looking-at c-fun-name-substitute-key) + (not (eq (char-after (match-end 0)) ?_)))) + (setq braceassignp nil)) + nil) + (t nil)) + (save-excursion + (cond + ((or (not (memq res '(t 0))) + (eq (char-after) ?,)) + (and (setq paren-state (c-parse-state)) + (setq paren-pos (c-pull-open-brace paren-state)) + (eq (char-after paren-pos) ?\() + (setq in-paren 'in-paren) + (goto-char paren-pos))) + ((looking-at c-pre-brace-non-bracelist-key)) + ((looking-at c-return-key)) + ((and (looking-at c-symbol-start) + (not (looking-at c-keywords-regexp)) + (save-excursion + (and (zerop (c-backward-token-2 1 t lim)) + (looking-at c-pre-id-bracelist-key))))) + (t (setq after-type-id-pos (point)) + nil)))) + (setq braceassignp 'c++-noassign)) + + (when (and c-opt-inexpr-brace-list-key + (eq (char-after) ?\[)) + ;; In Java, an initialization brace list may follow + ;; directly after "new Foo[]", so check for a "new" + ;; earlier. + (while (eq braceassignp 'dontknow) + (setq braceassignp + (cond ((/= (c-backward-token-2 1 t lim) 0) nil) + ((looking-at c-opt-inexpr-brace-list-key) + (setq inexpr-brace-list t) + t) + ((looking-at "\\sw\\|\\s_\\|[.[]") + ;; Carry on looking if this is an + ;; identifier (may contain "." in Java) + ;; or another "[]" sexp. + 'dontknow) + (t nil))))) + + (setq pos (point)) (cond - (braceassignp - ;; We've hit the beginning of the aggregate list. - (setq pos2 (point)) - (cons - (if (eq (c-beginning-of-statement-1 containing-sexp) 'same) - (point) - pos2) - (or in-paren inexpr-brace-list))) + ((not braceassignp) + nil) + ((and after-type-id-pos + (goto-char after-type-id-pos) + (setq res (c-back-over-member-initializers)) + (goto-char res) + (eq (car (c-beginning-of-decl-1 lim)) 'same)) + (cons (point) nil)) ; Return value. + ((and after-type-id-pos - (save-excursion - (when (eq (char-after) ?\;) - (c-forward-over-token-and-ws t)) - (setq bufpos (point)) - (when (looking-at c-opt-<>-sexp-key) - (c-forward-over-token-and-ws) - (when (and (eq (char-after) ?<) - (c-get-char-property (point) 'syntax-table)) - (c-go-list-forward nil after-type-id-pos) - (c-forward-syntactic-ws))) - (if (and (not (eq (point) after-type-id-pos)) - (or (not (looking-at c-class-key)) - (save-excursion - (goto-char (match-end 1)) - (c-forward-syntactic-ws) - (not (eq (point) after-type-id-pos))))) - (progn - (setq res - (c-forward-decl-or-cast-1 (c-point 'bosws) - nil nil)) - (and (consp res) - (cond - ((eq (car res) after-type-id-pos)) - ((> (car res) after-type-id-pos) nil) - (t - (catch 'find-decl + (progn + (c-backward-syntactic-ws) + (eq (char-before) ?\())) + ;; Single identifier between '(' and '{'. We have a bracelist. + (cons after-type-id-pos 'in-paren)) + + (t + (goto-char pos) + (when (eq braceassignp 'dontknow) + (let* ((cache-entry (and containing-sexp + (c-laomib-get-cache containing-sexp pos))) + (lim2 (or (cadr cache-entry) lim)) + sub-bassign-p) + (if cache-entry + (cond + ((<= (point) (cadr cache-entry)) + ;; We're inside the region we've already scanned over, so + ;; just go to that scan's end position. + (goto-char (nth 2 cache-entry)) + (setq braceassignp (nth 3 cache-entry))) + ((> (point) (cadr cache-entry)) + ;; We're beyond the previous scan region, so just scan as + ;; far as the end of that region. + (setq sub-bassign-p (c-laomib-loop lim2)) + (if (<= (point) (cadr cache-entry)) + (progn + (c-laomib-put-cache containing-sexp + start (nth 2 cache-entry) + (nth 3 cache-entry) ;; sub-bassign-p + ) + (setq braceassignp (nth 3 cache-entry)) + (goto-char (nth 2 cache-entry))) + (c-laomib-put-cache containing-sexp + start (point) sub-bassign-p) + (setq braceassignp sub-bassign-p))) + (t)) + + (setq braceassignp (c-laomib-loop lim)) + (when lim + (c-laomib-put-cache lim start (point) braceassignp))))) + + (cond + (braceassignp + ;; We've hit the beginning of the aggregate list. + (setq pos2 (point)) + (cons + (if (eq (c-beginning-of-statement-1 containing-sexp) 'same) + (point) + pos2) + (or in-paren inexpr-brace-list))) + ((and after-type-id-pos + (save-excursion + (when (eq (char-after) ?\;) + (c-forward-over-token-and-ws t)) + (setq bufpos (point)) + (when (looking-at c-opt-<>-sexp-key) + (c-forward-over-token-and-ws) + (when (and (eq (char-after) ?<) + (c-get-char-property (point) 'syntax-table)) + (c-go-list-forward nil after-type-id-pos) + (c-forward-syntactic-ws))) + (if (and (not (eq (point) after-type-id-pos)) + (or (not (looking-at c-class-key)) (save-excursion - (goto-char (car res)) - (c-do-declarators - (point-max) t nil nil - (lambda (id-start _id-end _tok _not-top _func _init) - (cond - ((> id-start after-type-id-pos) - (throw 'find-decl nil)) - ((eq id-start after-type-id-pos) - (throw 'find-decl t))))) - nil)))))) - (save-excursion - (goto-char start) - (not (c-looking-at-statement-block)))))) - (cons bufpos (or in-paren inexpr-brace-list))) - ((or (eq (char-after) ?\;) - ;; Brace lists can't contain a semicolon, so we're done. - (save-excursion - (c-backward-syntactic-ws) - (eq (char-before) ?})) - ;; They also can't contain a bare }, which is probably the end - ;; of a function. - ) - nil) - ((and (setq macro-start (point)) - (c-forward-to-cpp-define-body) - (eq (point) start)) - ;; We've a macro whose expansion starts with the '{'. - ;; Heuristically, if we have a ';' in it we've not got a - ;; brace list, otherwise we have. - (let ((macro-end (progn (c-end-of-macro) (point)))) - (goto-char start) - (forward-char) - (if (and (c-syntactic-re-search-forward "[;,]" macro-end t t) - (eq (char-before) ?\;)) - nil - (cons macro-start nil)))) ; (2016-08-30): Lazy! We have no + (goto-char (match-end 1)) + (c-forward-syntactic-ws) + (not (eq (point) after-type-id-pos))))) + (progn + (setq res + (c-forward-decl-or-cast-1 (c-point 'bosws) + nil nil)) + (and (consp res) + (cond + ((eq (car res) after-type-id-pos)) + ((> (car res) after-type-id-pos) nil) + (t + (catch 'find-decl + (save-excursion + (goto-char (car res)) + (c-do-declarators + (point-max) t nil nil + (lambda (id-start _id-end _tok _not-top _func _init) + (cond + ((> id-start after-type-id-pos) + (throw 'find-decl nil)) + ((eq id-start after-type-id-pos) + (throw 'find-decl t))))) + nil)))))) + (save-excursion + (goto-char start) + (not (c-looking-at-statement-block)))))) + (cons bufpos (or in-paren inexpr-brace-list))) + ((or (eq (char-after) ?\;) + ;; Brace lists can't contain a semicolon, so we're done. + (save-excursion + (c-backward-syntactic-ws) + (eq (char-before) ?})) + ;; They also can't contain a bare }, which is probably the end + ;; of a function. + ) + nil) + ((and (setq macro-start (point)) + (c-forward-to-cpp-define-body) + (eq (point) start)) + ;; We've a macro whose expansion starts with the '{'. + ;; Heuristically, if we have a ';' in it we've not got a + ;; brace list, otherwise we have. + (let ((macro-end (progn (c-end-of-macro) (point)))) + (goto-char start) + (forward-char) + (if (and (c-syntactic-re-search-forward "[;,]" macro-end t t) + (eq (char-before) ?\;)) + nil + (cons macro-start nil)))) ; (2016-08-30): Lazy! We have no ; languages where ; `c-opt-inexpr-brace-list-key' is ; non-nil and we have macros. - (t t)))) ;; The caller can go up one level. - ))) + (t t)))) ;; The caller can go up one level. + )))) (defun c-inside-bracelist-p (containing-sexp paren-state accept-in-paren) ;; return the buffer position of the beginning of the brace list statement @@ -13863,6 +13857,71 @@ (looking-at c-pre-lambda-tokens-re))) (not (c-in-literal)))) +(defun c-looking-at-c++-lambda-expression (&optional lim) + ;; If point is at the [ opening a C++ lambda expressions's capture list, + ;; and the lambda expression is complete, return the position of the { which + ;; opens the body form, otherwise return nil. LIM is the limit for forward + ;; searching for the {. + (let ((here (point)) + got-params) + (when (and (c-looking-at-c++-lambda-capture-list) + (c-go-list-forward nil lim)) + (c-forward-syntactic-ws lim) + (when (c-forward-<>-arglist t) + (c-forward-syntactic-ws lim) + (when (looking-at "requires\\([^a-zA-Z0-9_]\\|$\\)") + (c-forward-c++-requires-clause lim nil))) + (when (and (eq (char-after) ?\() + (c-go-list-forward nil lim)) + (setq got-params t) + (c-forward-syntactic-ws lim)) + (while (and c-lambda-spec-key (looking-at c-lambda-spec-key)) + (goto-char (match-end 1)) + (c-forward-syntactic-ws lim)) + (let (after-except-pos) + (cond + ((save-excursion + (and (looking-at "throw\\([^a-zA-Z0-9_]\\|$\\)") + (progn (goto-char (match-beginning 1)) + (c-forward-syntactic-ws lim) + (eq (char-after) ?\()) + (c-go-list-forward nil lim) + (progn (c-forward-syntactic-ws lim) + (setq after-except-pos (point))))) + (goto-char after-except-pos) + (c-forward-syntactic-ws lim)) + ((looking-at "noexcept\\([^a-zA-Z0-9_]\\|$\\)") + (c-forward-syntactic-ws lim) + (setq after-except-pos (point)) + (when (and (eq (char-after) ?\() + (c-go-list-forward nil lim)) + (c-forward-syntactic-ws lim))))) + (and (looking-at c-haskell-op-re) + (goto-char (match-end 0)) + (c-forward-syntactic-ws lim) + (c-forward-type t)) ; t is BRACE-BLOCK-TOO. + (and got-params + (looking-at "requires\\([^a-zA-Z0-9_]\\|$\\)") + (c-forward-c++-requires-clause lim nil)) + (prog1 (and (eq (char-after) ?{) + (point)) + (goto-char here))))) + +(defun c-backward-over-lambda-expression (&optional lim) + ;; Point is at a {. Move back over the lambda expression this is a part of, + ;; stopping at the [ of the capture list, if this is the case, returning + ;; the position of that opening bracket. If we're not at such a list, leave + ;; point unchanged and return nil. + (let ((here (point))) + (c-syntactic-skip-backward "^;}]" lim t) + (if (and (eq (char-before) ?\]) + (c-go-list-backward nil lim) + (eq (c-looking-at-c++-lambda-expression (1+ here)) + here)) + (point) + (goto-char here) + nil))) + (defun c-c++-vsemi-p (&optional pos) ;; C++ Only - Is there a "virtual semicolon" at POS or point? ;; (See cc-defs.el for full details of "virtual semicolons".) diff -r 48ad661a2d7d cc-langs.el --- a/cc-langs.el Mon Jul 22 12:09:34 2024 +0000 +++ b/cc-langs.el Sat Aug 31 16:44:39 2024 +0000 @@ -2639,6 +2639,19 @@ t (c-make-keywords-re t (c-lang-const c-equals-type-clause-kwds))) (c-lang-defvar c-equals-type-clause-key (c-lang-const c-equals-type-clause-key)) +(c-lang-defconst c-lambda-spec-kwds + "Keywords which are specifiers of certain elements of a C++ lambda function. +This is only used in C++ Mode." + t nil + c++ '("mutable" "constexpr" "consteval" "static")) + +(c-lang-defconst c-lambda-spec-key + ;; A regular expression which matches a member of `c-lambda-spec-kwds', + ;; or nil. + t (if (c-lang-const c-lambda-spec-kwds) + (c-make-keywords-re t (c-lang-const c-lambda-spec-kwds)))) +(c-lang-defvar c-lambda-spec-key (c-lang-const c-lambda-spec-key)) + (c-lang-defconst c-equals-nontype-decl-kwds "Keywords which are followed by an identifier then an \"=\" sign, which declares the identifier to be something other than a > Have a lovely day. > -- > Arsen Arsenović -- Alan Mackenzie (Nuremberg, Germany). From debbugs-submit-bounces@debbugs.gnu.org Sat Aug 31 21:04:43 2024 Received: (at 72695) by debbugs.gnu.org; 1 Sep 2024 01:04:44 +0000 Received: from localhost ([127.0.0.1]:58894 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1skZ1H-000300-Au for submit@debbugs.gnu.org; Sat, 31 Aug 2024 21:04:43 -0400 Received: from mout-p-202.mailbox.org ([80.241.56.172]:58764) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1skZ1E-0002zm-Ux for 72695@debbugs.gnu.org; Sat, 31 Aug 2024 21:04:42 -0400 Received: from smtp102.mailbox.org (smtp102.mailbox.org [10.196.197.102]) (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 mout-p-202.mailbox.org (Postfix) with ESMTPS id 4WxDCm5Nq0z9sqW; Sun, 1 Sep 2024 03:03:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aarsen.me; s=MBO0001; t=1725152612; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=4Q6zMNEWj+sAW4v56PDITy4T7oBUpBUNyMJQgmpCN7Q=; b=DKpEcim/5GsP2coLxw3ISAiHZf43eQoftdW5jVxsgcQ+OXE5r30U3L+1Saxd7rvsZZdgSE 5DqNCyoDyAFbrB18+oAlog4V+qJXmTAkP5Q20mvNwIM8P2DZDSeuhR8Xxi2Q1CUMSvj+CK c0CyZdbE6BOC8q8cx7jkcsS60GhPVbra14TC/AxOa3HS3E5rm1hniY4KfPIgDkfGiFCHPY vdqMxJAegJhFGiDjuuUa5K+umLmAVH/mA/ZT67mOprh8Bw5gFgndgyUH5MYswVVFrg3sHU DC+XYBLNO0IZnZcFQKg8od3J5xUs3k1A2gnpMhPpmO6tZe1PzGc057MAlI4CBg== From: =?utf-8?Q?Arsen_Arsenovi=C4=87?= To: Alan Mackenzie Subject: Re: bug#72695: CC Mode 5.35.2 (C++//l); c++-mode misindents 'if constexpr' inside lambdas In-Reply-To: (Alan Mackenzie's message of "Sat, 31 Aug 2024 17:01:07 +0000") References: <8634n2qhw7.fsf@aarsen.me> <86wmk9vcd9.fsf@aarsen.me> <875xrhtsuu.fsf@aarsen.me> Date: Sun, 01 Sep 2024 03:03:30 +0200 Message-ID: <86y14cfan1.fsf@aarsen.me> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 72695 Cc: 72695@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi Alan, Alan Mackenzie writes: > It's going well, thanks! At the current rate of progress, I'll have my > mail setup set up by this time next week, and that is the point at > which, at least for me, my new machine becomes my current machine. Great to hear! >> > But mainly I'm struggling with the unfathomable complexity of C++ lamb= da >> > functions, as documented on >> > https://en.cppreference.com/w/cpp/language/lambda. > >> It should be quite simple - just a few optional productions preceded by >> an introducer production (see https://eel.is/c++draft/expr.prim.lambda >> for a formal grammar - this is the text from the standard draft). > >> > In my not so humble opinion, the C++ standards people have completely >> > lost the plot. > >> Should help be necessary, I do work on G++ so I'm quite familiar with >> the language. Feel free to ping me. > > Thanks! It's just that the explanatory text on en.cppreference.com > about just lambda functions takes 20 scrolls of ~45 lines per scroll, > coming out at many hundreds of lines, just for lambda functions. I feel > that the entire language part of Emacs Lisp could fit into that quite > comfortably, at the same density. Heh, given there's only a dozen or so syntax elements in Elisp, I agree ;-). C++ exposes lots of flexibility, so the syntax grew to match. Lambda expressions declare both a data type and a function, and their syntax exposes the syntax elements of both, hence the proverbial complexity being the sum of the two. >> > The number of special cases in just the syntax, apparently just to >> > save a few characters from a program's text, has got beyond the point >> > where anybody can grasp it. Nobody in this group of people appears to >> > be able to say "STOP!", though somebody sorely needs to. I dread to >> > think what will be coming out in C++26. :-( > >> It really shouldn't be that bad - I'll help demystify if need be. > > Thanks! > >> > Anyhow, I've spent all afternoon on the problem so far, and I think I = can >> > see my way to a solution. It will still take a few more days yet, I'm >> > afraid. > >> Thank you very much! My apologies for the trouble. > > No apologies called for. You raised a bug report, for which thanks! > > Anyhow, I've got a first version, incompletely tested, of a new handling > for a lambda expression. The patch is not nearly as big as it looks, > two thirds of it is just re-indenting a large function I put an extra > `if' form aroun. I've tried it on a few examples I came up with, it seems to work well in 'real-life' code. I've also constructed the following "stress test" which includes (almost =2D see below) all the productions that can exist in a lambda function, in the same context as the original bad example: void def () { auto foo =3D [&, a, b =3D 123, c, ...d, ...e =3D 123 ] //alignas (128) [[gnu::noreturn]] requires some_concept (int a, int b, int c) consteval constexpr mutable static //noexcept(true) [[gnu::packed]] //alignas (128) //-> //int //requires (std::same_as ) { if constexpr (true) ; } } c-backward-over-lambda-expression does not work for this example. It seems that it gets confused by the trailing requires clauses, the alignas, the noexcept and the trailing return type (all commented - uncomment any or all to reproduce). However, this does not appear to negatively impact the syntax recognition instead, for the most part (I removed an element from the stress test above in order to demonstrate that the issue with indentation appears to be separate). In the following example: void def () { auto foo =3D [&, a, b =3D 123, c, ...d, ...e =3D 123 ] alignas (128) [[gnu::noreturn]] //requires some_concept (int a, int b, int c) consteval constexpr mutable static noexcept(true) [[gnu::packed]] alignas (128) -> int requires (std::same_as ) { if constexpr (true) ; } } ... uncommenting the requires line confuses the indentation engine. Hopefully these examples help. Please also note that in a few places (such as alignas, the noexcept specifier, RHS of assignments in the capture list) near-arbitrary expressions can appear, and that requires clause have special boolean expression syntax (see https://eel.is/c++draft/temp.pre#nt:requires-clause). Both of these pieces of syntax are reused in other contexts (other declarations), so if there's a bug in them in the lambda case, it likely carries over to the general declaration case. Thank you again for maintaining CC-mode! It is immeasurably useful. And apologies for the trouble :-) Have a lovely day. =2D-=20 Arsen Arsenovi=C4=87 --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iOYEARYKAI4WIQT+4rPRE/wAoxYtYGFSwpQwHqLEkwUCZtO9Yl8UgAAAAAAuAChp c3N1ZXItZnByQG5vdGF0aW9ucy5vcGVucGdwLmZpZnRoaG9yc2VtYW4ubmV0RkVF MkIzRDExM0ZDMDBBMzE2MkQ2MDYxNTJDMjk0MzAxRUEyQzQ5MxAcYXJzZW5AYWFy c2VuLm1lAAoJEFLClDAeosSTj2QA/RH0uILzXbbk02Edaza22lZ6Q9DesB/jwtTk kxLsdY4cAQDXfz9TpsJbamig888PAAZr7n0SdHQ5eWEcquxnlgW/AA== =X2mP -----END PGP SIGNATURE----- --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Mon Sep 09 11:15:50 2024 Received: (at 72695) by debbugs.gnu.org; 9 Sep 2024 15:15:50 +0000 Received: from localhost ([127.0.0.1]:33880 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sng7I-0003e4-Mg for submit@debbugs.gnu.org; Mon, 09 Sep 2024 11:15:50 -0400 Received: from mail.muc.de ([193.149.48.3]:28541) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sng7G-0003do-4b for 72695@debbugs.gnu.org; Mon, 09 Sep 2024 11:15:48 -0400 Received: (qmail 36809 invoked by uid 3782); 9 Sep 2024 17:15:35 +0200 Received: from muc.de (p4fe158a0.dip0.t-ipconnect.de [79.225.88.160]) (using STARTTLS) by colin.muc.de (tmda-ofmipd) with ESMTP; Mon, 09 Sep 2024 17:15:35 +0200 Received: (qmail 9643 invoked by uid 1000); 9 Sep 2024 15:15:34 -0000 Date: Mon, 9 Sep 2024 15:15:34 +0000 To: Arsen =?utf-8?Q?Arsenovi=C4=87?= Subject: Re: bug#72695: CC Mode 5.35.2 (C++//l); c++-mode misindents 'if constexpr' inside lambdas Message-ID: References: <8634n2qhw7.fsf@aarsen.me> <86wmk9vcd9.fsf@aarsen.me> <875xrhtsuu.fsf@aarsen.me> <86y14cfan1.fsf@aarsen.me> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <86y14cfan1.fsf@aarsen.me> X-Submission-Agent: TMDA/1.3.x (Ph3nix) From: Alan Mackenzie X-Primary-Address: acm@muc.de X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 72695 Cc: acm@muc.de, 72695@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hello, Arsen. On Sun, Sep 01, 2024 at 03:03:30 +0200, Arsen Arsenović wrote: > Hi Alan, > Alan Mackenzie writes: > > It's going well, thanks! At the current rate of progress, I'll have my > > mail setup set up by this time next week, and that is the point at > > which, at least for me, my new machine becomes my current machine. > Great to hear! Thanks! I'm afraid I've spent all week on that dashed email setup, and it's now finally working. So I've made only some progress on the bug, sorry. But here is what I have: [ .... ] > Heh, given there's only a dozen or so syntax elements in Elisp, I agree > ;-). C++ exposes lots of flexibility, so the syntax grew to match. Anyhow, I'm feeling less negative about C++'s syntax, now. > Lambda expressions declare both a data type and a function, and their > syntax exposes the syntax elements of both, hence the proverbial > complexity being the sum of the two. [ .... ] > > Anyhow, I've got a first version, incompletely tested, of a new > > handling for a lambda expression. The patch is not nearly as big as > > it looks, two thirds of it is just re-indenting a large function I > > put an extra `if' form aroun. > I've tried it on a few examples I came up with, it seems to work well in > 'real-life' code. > I've also constructed the following "stress test" which includes (almost > - see below) all the productions that can exist in a lambda function, in > the same context as the original bad example: Thanks, this was very useful. As an important question, can and alignas specifier exist inside a lambda expression? If so, what does it mean? My new patch below doesn't (yet) handle it. > void > def () > { > auto foo = [&, > a, > b = 123, > c, > ...d, > ...e = 123 > ] > typename S> > //alignas (128) > [[gnu::noreturn]] > requires some_concept > (int a, > int b, > int c) > consteval > constexpr > mutable > static > //noexcept(true) > [[gnu::packed]] > //alignas (128) > //-> > //int > //requires (std::same_as ) > { > if constexpr (true) > ; > } > } Here's a modified version which is now fully handled (as far as it goes): void def () { auto foo = [&, a, b = 123, c, ...d, ...e = 123 ] //alignas (128) [[gnu::noreturn]] requires some_concept (int a, int b, int c) consteval constexpr mutable static noexcept(true) [[gnu::packed]] //alignas (128) -> int requires (std::same_as ) { if constexpr (true) ; } } [ .... ] > It seems that it gets confused by the trailing requires clauses, the > alignas, the noexcept and the trailing return type (all commented - > uncomment any or all to reproduce). These were coding errors in CC Mode. I hope the patch below will have fixed these, apart from the alignas (see above). > However, this does not appear to negatively impact the syntax > recognition instead, for the most part (I removed an element from the > stress test above in order to demonstrate that the issue with > indentation appears to be separate). > In the following example: > void > def () > { > auto foo = [&, > a, > b = 123, > c, > ...d, > ...e = 123 > ] > typename S> > alignas (128) > [[gnu::noreturn]] > //requires some_concept > (int a, > int b, > int c) > consteval > constexpr > mutable > static > noexcept(true) > [[gnu::packed]] > alignas (128) > -> > int > requires (std::same_as ) > { > if constexpr (true) > ; > } > } > ... uncommenting the requires line confuses the indentation engine. I think this is fixed, now. > Hopefully these examples help. Very much so. > Please also note that in a few places (such as alignas, the noexcept > specifier, RHS of assignments in the capture list) near-arbitrary > expressions can appear, and that requires clause have special boolean > expression syntax (see > https://eel.is/c++draft/temp.pre#nt:requires-clause). I'm afraid I haven't looked at this, yet. > Both of these pieces of syntax are reused in other contexts (other > declarations), so if there's a bug in them in the lambda case, it likely > carries over to the general declaration case. > Thank you again for maintaining CC-mode! It is immeasurably useful. > And apologies for the trouble :-) No trouble at all! Here's an up to date version of the patch, which should work better than the last version. Please do the usual with it, and let me know how it goes. Thanks! diff -r 48ad661a2d7d cc-engine.el --- a/cc-engine.el Mon Jul 22 12:09:34 2024 +0000 +++ b/cc-engine.el Mon Sep 09 14:49:55 2024 +0000 @@ -9929,12 +9929,20 @@ ((eq (char-after) ?\() (and (c-go-list-forward (point) limit) (eq (char-before) ?\)) - (let ((after-paren (point))) - (c-forward-syntactic-ws limit) - (prog1 - (not (eq (char-after) ?{)) - (when stop-at-end - (goto-char after-paren)))))) +;;;; OLD STOUGH, 2024-09-01 + ;; (let ((after-paren (point))) + ;; (c-forward-syntactic-ws limit) + ;; (prog1 + ;; (not (eq (char-after) ?{)) + ;; (when stop-at-end + ;; (goto-char after-paren)))) +;;;; NEW STOUGH, 2024-09-01 + (progn + (unless stop-at-end + (c-forward-syntactic-ws limit)) + t) +;;;; END OF NEW STOUGH + )) ((c-forward-over-compound-identifier) (let ((after-id (point))) (c-forward-syntactic-ws limit) @@ -13178,229 +13186,223 @@ ;; ;; Here, "brace list" does not include the body of an enum. (save-excursion - (let ((start (point)) - (braceassignp 'dontknow) - inexpr-brace-list bufpos macro-start res pos after-type-id-pos - pos2 in-paren parens-before-brace - paren-state paren-pos) - - (setq res - (or (progn (c-backward-syntactic-ws) - (c-back-over-compound-identifier)) - (c-backward-token-2 1 t lim))) - ;; Checks to do only on the first sexp before the brace. - ;; Have we a C++ initialization, without an "="? - (if (and (c-major-mode-is 'c++-mode) - (cond - ((and (or (not (memq res '(t 0))) - (eq (char-after) ?,)) - (setq paren-state (c-parse-state)) - (setq paren-pos (c-pull-open-brace paren-state)) - (eq (char-after paren-pos) ?\()) - (goto-char paren-pos) - (setq braceassignp 'c++-noassign - in-paren 'in-paren)) - ((looking-at c-pre-brace-non-bracelist-key) - (setq braceassignp nil)) - ((and - (looking-at c-fun-name-substitute-key) - (not (eq (char-after (match-end 0)) ?_))) - (setq braceassignp nil)) - ((looking-at c-return-key)) - ((and (looking-at c-symbol-start) - (not (looking-at c-keywords-regexp))) - (if (save-excursion - (and (zerop (c-backward-token-2 1 t lim)) - (looking-at c-pre-id-bracelist-key))) - (setq braceassignp 'c++-noassign) - (setq after-type-id-pos (point)))) - ((eq (char-after) ?\() - (setq parens-before-brace t) - ;; Have we a requires with a parenthesis list? - (when (save-excursion - (and (zerop (c-backward-token-2 1 nil lim)) - (looking-at c-fun-name-substitute-key) - (not (eq (char-after (match-end 0)) ?_)))) + (unless (and (c-major-mode-is 'c++-mode) + (c-backward-over-lambda-expression lim)) + (let ((start (point)) + (braceassignp 'dontknow) + inexpr-brace-list bufpos macro-start res pos after-type-id-pos + pos2 in-paren ;; parens-before-brace STOUGH, 2024-08-31 + paren-state paren-pos) + + (setq res + (or (progn (c-backward-syntactic-ws) + (c-back-over-compound-identifier)) + (c-backward-token-2 1 t lim))) + ;; Checks to do only on the first sexp before the brace. + ;; Have we a C++ initialization, without an "="? + (if (and (c-major-mode-is 'c++-mode) + (cond + ((and (or (not (memq res '(t 0))) + (eq (char-after) ?,)) + (setq paren-state (c-parse-state)) + (setq paren-pos (c-pull-open-brace paren-state)) + (eq (char-after paren-pos) ?\()) + (goto-char paren-pos) + (setq braceassignp 'c++-noassign + in-paren 'in-paren)) + ((looking-at c-pre-brace-non-bracelist-key) (setq braceassignp nil)) - nil) - (t nil)) - (save-excursion - (cond - ((or (not (memq res '(t 0))) - (eq (char-after) ?,)) - (and (setq paren-state (c-parse-state)) - (setq paren-pos (c-pull-open-brace paren-state)) - (eq (char-after paren-pos) ?\() - (setq in-paren 'in-paren) - (goto-char paren-pos))) - ((looking-at c-pre-brace-non-bracelist-key)) + ((and + (looking-at c-fun-name-substitute-key) + (not (eq (char-after (match-end 0)) ?_))) + (setq braceassignp nil)) ((looking-at c-return-key)) ((and (looking-at c-symbol-start) - (not (looking-at c-keywords-regexp)) - (save-excursion - (and (zerop (c-backward-token-2 1 t lim)) - (looking-at c-pre-id-bracelist-key))))) - (t (setq after-type-id-pos (point)) - nil)))) - (setq braceassignp 'c++-noassign)) - - (when (and c-opt-inexpr-brace-list-key - (eq (char-after) ?\[)) - ;; In Java, an initialization brace list may follow - ;; directly after "new Foo[]", so check for a "new" - ;; earlier. - (while (eq braceassignp 'dontknow) - (setq braceassignp - (cond ((/= (c-backward-token-2 1 t lim) 0) nil) - ((looking-at c-opt-inexpr-brace-list-key) - (setq inexpr-brace-list t) - t) - ((looking-at "\\sw\\|\\s_\\|[.[]") - ;; Carry on looking if this is an - ;; identifier (may contain "." in Java) - ;; or another "[]" sexp. - 'dontknow) - (t nil))))) - - (setq pos (point)) - (cond - ((not braceassignp) - nil) - ((and after-type-id-pos - (goto-char after-type-id-pos) - (setq res (c-back-over-member-initializers)) - (goto-char res) - (eq (car (c-beginning-of-decl-1 lim)) 'same)) - (cons (point) nil)) ; Return value. - - ((and after-type-id-pos - (progn - (c-backward-syntactic-ws) - (eq (char-before) ?\())) - ;; Single identifier between '(' and '{'. We have a bracelist. - (cons after-type-id-pos 'in-paren)) - - ;; Are we at the parens of a C++ lambda expression? - ((and parens-before-brace - (save-excursion - (and - (zerop (c-backward-token-2 1 t lim)) - (c-looking-at-c++-lambda-capture-list)))) - nil) ; a lambda expression isn't a brace list. - - (t - (goto-char pos) - (when (eq braceassignp 'dontknow) - (let* ((cache-entry (and containing-sexp - (c-laomib-get-cache containing-sexp pos))) - (lim2 (or (cadr cache-entry) lim)) - sub-bassign-p) - (if cache-entry - (cond - ((<= (point) (cadr cache-entry)) - ;; We're inside the region we've already scanned over, so - ;; just go to that scan's end position. - (goto-char (nth 2 cache-entry)) - (setq braceassignp (nth 3 cache-entry))) - ((> (point) (cadr cache-entry)) - ;; We're beyond the previous scan region, so just scan as - ;; far as the end of that region. - (setq sub-bassign-p (c-laomib-loop lim2)) - (if (<= (point) (cadr cache-entry)) - (progn - (c-laomib-put-cache containing-sexp - start (nth 2 cache-entry) - (nth 3 cache-entry) ;; sub-bassign-p - ) - (setq braceassignp (nth 3 cache-entry)) - (goto-char (nth 2 cache-entry))) - (c-laomib-put-cache containing-sexp - start (point) sub-bassign-p) - (setq braceassignp sub-bassign-p))) - (t)) - - (setq braceassignp (c-laomib-loop lim)) - (when lim - (c-laomib-put-cache lim start (point) braceassignp))))) - + (not (looking-at c-keywords-regexp))) + (if (save-excursion + (and (zerop (c-backward-token-2 1 t lim)) + (looking-at c-pre-id-bracelist-key))) + (setq braceassignp 'c++-noassign) + (setq after-type-id-pos (point)))) + ((eq (char-after) ?\() + ;; (setq parens-before-brace t) STOUGH, 2024-08-31 + ;; Have we a requires with a parenthesis list? + (when (save-excursion + (and (zerop (c-backward-token-2 1 nil lim)) + (looking-at c-fun-name-substitute-key) + (not (eq (char-after (match-end 0)) ?_)))) + (setq braceassignp nil)) + nil) + (t nil)) + (save-excursion + (cond + ((or (not (memq res '(t 0))) + (eq (char-after) ?,)) + (and (setq paren-state (c-parse-state)) + (setq paren-pos (c-pull-open-brace paren-state)) + (eq (char-after paren-pos) ?\() + (setq in-paren 'in-paren) + (goto-char paren-pos))) + ((looking-at c-pre-brace-non-bracelist-key)) + ((looking-at c-return-key)) + ((and (looking-at c-symbol-start) + (not (looking-at c-keywords-regexp)) + (save-excursion + (and (zerop (c-backward-token-2 1 t lim)) + (looking-at c-pre-id-bracelist-key))))) + (t (setq after-type-id-pos (point)) + nil)))) + (setq braceassignp 'c++-noassign)) + + (when (and c-opt-inexpr-brace-list-key + (eq (char-after) ?\[)) + ;; In Java, an initialization brace list may follow + ;; directly after "new Foo[]", so check for a "new" + ;; earlier. + (while (eq braceassignp 'dontknow) + (setq braceassignp + (cond ((/= (c-backward-token-2 1 t lim) 0) nil) + ((looking-at c-opt-inexpr-brace-list-key) + (setq inexpr-brace-list t) + t) + ((looking-at "\\sw\\|\\s_\\|[.[]") + ;; Carry on looking if this is an + ;; identifier (may contain "." in Java) + ;; or another "[]" sexp. + 'dontknow) + (t nil))))) + + (setq pos (point)) (cond - (braceassignp - ;; We've hit the beginning of the aggregate list. - (setq pos2 (point)) - (cons - (if (eq (c-beginning-of-statement-1 containing-sexp) 'same) - (point) - pos2) - (or in-paren inexpr-brace-list))) + ((not braceassignp) + nil) + ((and after-type-id-pos + (goto-char after-type-id-pos) + (setq res (c-back-over-member-initializers)) + (goto-char res) + (eq (car (c-beginning-of-decl-1 lim)) 'same)) + (cons (point) nil)) ; Return value. + ((and after-type-id-pos - (save-excursion - (when (eq (char-after) ?\;) - (c-forward-over-token-and-ws t)) - (setq bufpos (point)) - (when (looking-at c-opt-<>-sexp-key) - (c-forward-over-token-and-ws) - (when (and (eq (char-after) ?<) - (c-get-char-property (point) 'syntax-table)) - (c-go-list-forward nil after-type-id-pos) - (c-forward-syntactic-ws))) - (if (and (not (eq (point) after-type-id-pos)) - (or (not (looking-at c-class-key)) - (save-excursion - (goto-char (match-end 1)) - (c-forward-syntactic-ws) - (not (eq (point) after-type-id-pos))))) - (progn - (setq res - (c-forward-decl-or-cast-1 (c-point 'bosws) - nil nil)) - (and (consp res) - (cond - ((eq (car res) after-type-id-pos)) - ((> (car res) after-type-id-pos) nil) - (t - (catch 'find-decl + (progn + (c-backward-syntactic-ws) + (eq (char-before) ?\())) + ;; Single identifier between '(' and '{'. We have a bracelist. + (cons after-type-id-pos 'in-paren)) + + (t + (goto-char pos) + (when (eq braceassignp 'dontknow) + (let* ((cache-entry (and containing-sexp + (c-laomib-get-cache containing-sexp pos))) + (lim2 (or (cadr cache-entry) lim)) + sub-bassign-p) + (if cache-entry + (cond + ((<= (point) (cadr cache-entry)) + ;; We're inside the region we've already scanned over, so + ;; just go to that scan's end position. + (goto-char (nth 2 cache-entry)) + (setq braceassignp (nth 3 cache-entry))) + ((> (point) (cadr cache-entry)) + ;; We're beyond the previous scan region, so just scan as + ;; far as the end of that region. + (setq sub-bassign-p (c-laomib-loop lim2)) + (if (<= (point) (cadr cache-entry)) + (progn + (c-laomib-put-cache containing-sexp + start (nth 2 cache-entry) + (nth 3 cache-entry) ;; sub-bassign-p + ) + (setq braceassignp (nth 3 cache-entry)) + (goto-char (nth 2 cache-entry))) + (c-laomib-put-cache containing-sexp + start (point) sub-bassign-p) + (setq braceassignp sub-bassign-p))) + (t)) + + (setq braceassignp (c-laomib-loop lim)) + (when lim + (c-laomib-put-cache lim start (point) braceassignp))))) + + (cond + (braceassignp + ;; We've hit the beginning of the aggregate list. + (setq pos2 (point)) + (cons + (if (eq (c-beginning-of-statement-1 containing-sexp) 'same) + (point) + pos2) + (or in-paren inexpr-brace-list))) + ((and after-type-id-pos + (save-excursion + (when (eq (char-after) ?\;) + (c-forward-over-token-and-ws t)) + (setq bufpos (point)) + (when (looking-at c-opt-<>-sexp-key) + (c-forward-over-token-and-ws) + (when (and (eq (char-after) ?<) + (c-get-char-property (point) 'syntax-table)) + (c-go-list-forward nil after-type-id-pos) + (c-forward-syntactic-ws))) + (if (and (not (eq (point) after-type-id-pos)) + (or (not (looking-at c-class-key)) (save-excursion - (goto-char (car res)) - (c-do-declarators - (point-max) t nil nil - (lambda (id-start _id-end _tok _not-top _func _init) - (cond - ((> id-start after-type-id-pos) - (throw 'find-decl nil)) - ((eq id-start after-type-id-pos) - (throw 'find-decl t))))) - nil)))))) - (save-excursion - (goto-char start) - (not (c-looking-at-statement-block)))))) - (cons bufpos (or in-paren inexpr-brace-list))) - ((or (eq (char-after) ?\;) - ;; Brace lists can't contain a semicolon, so we're done. - (save-excursion - (c-backward-syntactic-ws) - (eq (char-before) ?})) - ;; They also can't contain a bare }, which is probably the end - ;; of a function. - ) - nil) - ((and (setq macro-start (point)) - (c-forward-to-cpp-define-body) - (eq (point) start)) - ;; We've a macro whose expansion starts with the '{'. - ;; Heuristically, if we have a ';' in it we've not got a - ;; brace list, otherwise we have. - (let ((macro-end (progn (c-end-of-macro) (point)))) - (goto-char start) - (forward-char) - (if (and (c-syntactic-re-search-forward "[;,]" macro-end t t) - (eq (char-before) ?\;)) - nil - (cons macro-start nil)))) ; (2016-08-30): Lazy! We have no + (goto-char (match-end 1)) + (c-forward-syntactic-ws) + (not (eq (point) after-type-id-pos))))) + (progn + (setq res + (c-forward-decl-or-cast-1 (c-point 'bosws) + nil nil)) + (and (consp res) + (cond + ((eq (car res) after-type-id-pos)) + ((> (car res) after-type-id-pos) nil) + (t + (catch 'find-decl + (save-excursion + (goto-char (car res)) + (c-do-declarators + (point-max) t nil nil + (lambda (id-start _id-end _tok _not-top _func _init) + (cond + ((> id-start after-type-id-pos) + (throw 'find-decl nil)) + ((eq id-start after-type-id-pos) + (throw 'find-decl t))))) + nil)))))) + (save-excursion + (goto-char start) + (not (c-looking-at-statement-block)))))) + (cons bufpos (or in-paren inexpr-brace-list))) + ((or (eq (char-after) ?\;) + ;; Brace lists can't contain a semicolon, so we're done. + (save-excursion + (c-backward-syntactic-ws) + (eq (char-before) ?})) + ;; They also can't contain a bare }, which is probably the end + ;; of a function. + ) + nil) + ((and (setq macro-start (point)) + (c-forward-to-cpp-define-body) + (eq (point) start)) + ;; We've a macro whose expansion starts with the '{'. + ;; Heuristically, if we have a ';' in it we've not got a + ;; brace list, otherwise we have. + (let ((macro-end (progn (c-end-of-macro) (point)))) + (goto-char start) + (forward-char) + (if (and (c-syntactic-re-search-forward "[;,]" macro-end t t) + (eq (char-before) ?\;)) + nil + (cons macro-start nil)))) ; (2016-08-30): Lazy! We have no ; languages where ; `c-opt-inexpr-brace-list-key' is ; non-nil and we have macros. - (t t)))) ;; The caller can go up one level. - ))) + (t t)))) ;; The caller can go up one level. + )))) (defun c-inside-bracelist-p (containing-sexp paren-state accept-in-paren) ;; return the buffer position of the beginning of the brace list statement @@ -13863,6 +13865,72 @@ (looking-at c-pre-lambda-tokens-re))) (not (c-in-literal)))) +(defun c-looking-at-c++-lambda-expression (&optional lim) + ;; If point is at the [ opening a C++ lambda expressions's capture list, + ;; and the lambda expression is complete, return the position of the { which + ;; opens the body form, otherwise return nil. LIM is the limit for forward + ;; searching for the {. + (let ((here (point)) + got-params) + (when (and (c-looking-at-c++-lambda-capture-list) + (c-go-list-forward nil lim)) + (c-forward-syntactic-ws lim) + (when (c-forward-<>-arglist t) + (c-forward-syntactic-ws lim) + (when (looking-at "requires\\([^a-zA-Z0-9_]\\|$\\)") + (c-forward-c++-requires-clause lim nil))) + (when (and (eq (char-after) ?\() + (c-go-list-forward nil lim)) + (setq got-params t) + (c-forward-syntactic-ws lim)) + (while (and c-lambda-spec-key (looking-at c-lambda-spec-key)) + (goto-char (match-end 1)) + (c-forward-syntactic-ws lim)) + (let (after-except-pos) + (cond + ((save-excursion + (and (looking-at "throw\\([^a-zA-Z0-9_]\\|$\\)") + (progn (goto-char (match-beginning 1)) + (c-forward-syntactic-ws lim) + (eq (char-after) ?\()) + (c-go-list-forward nil lim) + (progn (c-forward-syntactic-ws lim) + (setq after-except-pos (point))))) + (goto-char after-except-pos) + (c-forward-syntactic-ws lim)) + ((looking-at "noexcept\\([^a-zA-Z0-9_]\\|$\\)") + (goto-char (match-beginning 1)) + (c-forward-syntactic-ws lim) + (setq after-except-pos (point)) + (when (and (eq (char-after) ?\() + (c-go-list-forward nil lim)) + (c-forward-syntactic-ws lim))))) + (and (looking-at c-haskell-op-re) + (goto-char (match-end 0)) + (progn (c-forward-syntactic-ws lim) + (c-forward-type t))) ; t is BRACE-BLOCK-TOO. + (and got-params + (looking-at "requires\\([^a-zA-Z0-9_]\\|$\\)") + (c-forward-c++-requires-clause lim nil)) + (prog1 (and (eq (char-after) ?{) + (point)) + (goto-char here))))) + +(defun c-backward-over-lambda-expression (&optional lim) + ;; Point is at a {. Move back over the lambda expression this is a part of, + ;; stopping at the [ of the capture list, if this is the case, returning + ;; the position of that opening bracket. If we're not at such a list, leave + ;; point unchanged and return nil. + (let ((here (point))) + (c-syntactic-skip-backward "^;}]" lim t) + (if (and (eq (char-before) ?\]) + (c-go-list-backward nil lim) + (eq (c-looking-at-c++-lambda-expression (1+ here)) + here)) + (point) + (goto-char here) + nil))) + (defun c-c++-vsemi-p (&optional pos) ;; C++ Only - Is there a "virtual semicolon" at POS or point? ;; (See cc-defs.el for full details of "virtual semicolons".) @@ -13870,11 +13938,17 @@ ;; This is true when point is at the last non syntactic WS position on the ;; line, and either there is a "macro with semicolon" just before it (see ;; `c-at-macro-vsemi-p') or there is a "requires" clause which ends there. - (let (res) - (cond - ((setq res (c-in-requires-or-at-end-of-clause pos)) - (and res (eq (cdr res) t))) - ((c-at-macro-vsemi-p))))) +;;;; TEMP COMMENTED OUT STOUGH, 2024-09-01 + ;; (let (res) + ;; (cond + ;; ((setq res (c-in-requires-or-at-end-of-clause pos)) + ;; (and res (eq (cdr res) t))) + ;; ( +;;;; END OF TCO STOUGH + (c-at-macro-vsemi-p pos ; POS is NEW STOUGH, 2024-09-01 + ) + ;; ))) TEMP COMMENTED OUT STOUGH, 2024-09-01 +) (defun c-at-macro-vsemi-p (&optional pos) ;; Is there a "virtual semicolon" at POS or point? diff -r 48ad661a2d7d cc-langs.el --- a/cc-langs.el Mon Jul 22 12:09:34 2024 +0000 +++ b/cc-langs.el Mon Sep 09 14:49:55 2024 +0000 @@ -2639,6 +2639,19 @@ t (c-make-keywords-re t (c-lang-const c-equals-type-clause-kwds))) (c-lang-defvar c-equals-type-clause-key (c-lang-const c-equals-type-clause-key)) +(c-lang-defconst c-lambda-spec-kwds + "Keywords which are specifiers of certain elements of a C++ lambda function. +This is only used in C++ Mode." + t nil + c++ '("mutable" "constexpr" "consteval" "static")) + +(c-lang-defconst c-lambda-spec-key + ;; A regular expression which matches a member of `c-lambda-spec-kwds', + ;; or nil. + t (if (c-lang-const c-lambda-spec-kwds) + (c-make-keywords-re t (c-lang-const c-lambda-spec-kwds)))) +(c-lang-defvar c-lambda-spec-key (c-lang-const c-lambda-spec-key)) + (c-lang-defconst c-equals-nontype-decl-kwds "Keywords which are followed by an identifier then an \"=\" sign, which declares the identifier to be something other than a > Have a lovely day. > -- > Arsen Arsenović -- Alan Mackenzie (Nuremberg, Germany). From debbugs-submit-bounces@debbugs.gnu.org Mon Sep 09 19:03:39 2024 Received: (at 72695) by debbugs.gnu.org; 9 Sep 2024 23:03:39 +0000 Received: from localhost ([127.0.0.1]:34357 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1snnQ2-00029j-NE for submit@debbugs.gnu.org; Mon, 09 Sep 2024 19:03:39 -0400 Received: from mout-p-202.mailbox.org ([80.241.56.172]:40064) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1snnPz-00029V-UK for 72695@debbugs.gnu.org; Mon, 09 Sep 2024 19:03:37 -0400 Received: from smtp2.mailbox.org (smtp2.mailbox.org [IPv6:2001:67c:2050:b231:465::2]) (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 mout-p-202.mailbox.org (Postfix) with ESMTPS id 4X2j6P2RGvz9sNw; Tue, 10 Sep 2024 01:02:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aarsen.me; s=MBO0001; t=1725922973; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=ylWPPgbEium3x3G5rJb3rvi3ycU8gjS4KUFbeLO1SKI=; b=AplEgJkGoyI1JaCNrYhMcZJdUOIvgF9uxjSjjlQUalfahdkj0kmXml3RHjaGJlpxjaTTlx GD/pUzI9zOJEUJSHdmzZ4/sbOSvbEPSVLP863LTydt2x+B7xhslkNweo8E3AqbnPt+0wVW hYjWNLFTMVKksJdCORI17OA0ujcOzNJFM4AEfImu8VTZ0VzMntSYtK4trG4T6SU6Zg6D0S P7cjomNOBbHn3y38hSCjjbIngknBCgE/W8wq8nyIZVP9xxg5DfW5itk0WaU7rpZ00UHDei ULTcu8boMaRf6ZcnPl9Kh0Il08v6TXGo43zSRwuYn3Y88wWOvxEhawQX7GOWNg== From: =?utf-8?Q?Arsen_Arsenovi=C4=87?= To: Alan Mackenzie Subject: Re: bug#72695: CC Mode 5.35.2 (C++//l); c++-mode misindents 'if constexpr' inside lambdas In-Reply-To: (Alan Mackenzie's message of "Mon, 9 Sep 2024 15:15:34 +0000") References: <8634n2qhw7.fsf@aarsen.me> <86wmk9vcd9.fsf@aarsen.me> <875xrhtsuu.fsf@aarsen.me> <86y14cfan1.fsf@aarsen.me> Date: Tue, 10 Sep 2024 01:02:50 +0200 Message-ID: <86a5ggsa5h.fsf@aarsen.me> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Rspamd-Queue-Id: 4X2j6P2RGvz9sNw X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 72695 Cc: 72695@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi Alan, Alan Mackenzie writes: > Thanks! I'm afraid I've spent all week on that dashed email setup, > and it's now finally working. So I've made only some progress on the > bug, sorry. No worries! > But here is what I have: > > [ .... ] > >> Heh, given there's only a dozen or so syntax elements in Elisp, I agree >> ;-). C++ exposes lots of flexibility, so the syntax grew to match. > > Anyhow, I'm feeling less negative about C++'s syntax, now. :-) >> Lambda expressions declare both a data type and a function, and their >> syntax exposes the syntax elements of both, hence the proverbial >> complexity being the sum of the two. > > [ .... ] > >> > Anyhow, I've got a first version, incompletely tested, of a new >> > handling for a lambda expression. The patch is not nearly as big as >> > it looks, two thirds of it is just re-indenting a large function I >> > put an extra `if' form aroun. > >> I've tried it on a few examples I came up with, it seems to work well in >> 'real-life' code. > >> I've also constructed the following "stress test" which includes (almost >> - see below) all the productions that can exist in a lambda function, in >> the same context as the original bad example: > > Thanks, this was very useful. As an important question, can and alignas > specifier exist inside a lambda expression? If so, what does it mean? > My new patch below doesn't (yet) handle it. It certainly can in the body. I presume you mean in the leader/declarator/whathaveyou however; in that case, yes, as part of the attribute-specifier-seq in lambda-expression and lambda-declarator, and its meaning depends on the position (see https://eel.is/c++draft/expr.prim.lambda#closure-6). In short: in the following: [] alignas (128) () alignas (64) {...} ... the operator() - i.e. the function containing the lambda body - of the closure type will have alignment of 128 (whatever that means for functions), and the function type itself will be have alignment of 64 (whatever that means for the function type). >> void >> def () >> { >> auto foo =3D [&, >> a, >> b =3D 123, >> c, >> ...d, >> ...e =3D 123 >> ] >> > typename S> >> //alignas (128) >> [[gnu::noreturn]] >> requires some_concept >> (int a, >> int b, >> int c) >> consteval >> constexpr >> mutable >> static >> //noexcept(true) >> [[gnu::packed]] >> //alignas (128) >> //-> >> //int >> //requires (std::same_as ) >> { >> if constexpr (true) >> ; >> } >> } > > Here's a modified version which is now fully handled (as far as it goes): > > > void > def () > { > auto foo =3D [&, > a, > b =3D 123, > c, > ...d, > ...e =3D 123 > ] > typename S> > //alignas (128) > [[gnu::noreturn]] > requires some_concept > (int a, > int b, > int c) > consteval > constexpr > mutable > static > noexcept(true) > [[gnu::packed]] > //alignas (128) > -> int > requires (std::same_as ) > { > if constexpr (true) > ; > } > } > > > [ .... ] > >> It seems that it gets confused by the trailing requires clauses, the >> alignas, the noexcept and the trailing return type (all commented - >> uncomment any or all to reproduce). > > These were coding errors in CC Mode. I hope the patch below will have > fixed these, apart from the alignas (see above). Indeed that appears to be the case! >> However, this does not appear to negatively impact the syntax >> recognition instead, for the most part (I removed an element from the >> stress test above in order to demonstrate that the issue with >> indentation appears to be separate). > >> In the following example: > >> void >> def () >> { >> auto foo =3D [&, >> a, >> b =3D 123, >> c, >> ...d, >> ...e =3D 123 >> ] >> > typename S> >> alignas (128) >> [[gnu::noreturn]] >> //requires some_concept >> (int a, >> int b, >> int c) >> consteval >> constexpr >> mutable >> static >> noexcept(true) >> [[gnu::packed]] >> alignas (128) >> -> >> int >> requires (std::same_as ) >> { >> if constexpr (true) >> ; >> } >> } > >> ... uncommenting the requires line confuses the indentation engine. > > I think this is fixed, now. > >> Hopefully these examples help. > > Very much so. > >> Please also note that in a few places (such as alignas, the noexcept >> specifier, RHS of assignments in the capture list) near-arbitrary >> expressions can appear, and that requires clause have special boolean >> expression syntax (see >> https://eel.is/c++draft/temp.pre#nt:requires-clause). > > I'm afraid I haven't looked at this, yet. No worries. This is somewhat akin to a few other constructs in C and C++ where expressions can appear in an otherwise "type" context, so it might already be handled (and the handling for concepts /could/ be generic handling probably, without worrying about the special case in the grammar - just something to consider). >> Both of these pieces of syntax are reused in other contexts (other >> declarations), so if there's a bug in them in the lambda case, it likely >> carries over to the general declaration case. > >> Thank you again for maintaining CC-mode! It is immeasurably useful. >> And apologies for the trouble :-) > > No trouble at all! > > Here's an up to date version of the patch, which should work better than > the last version. Please do the usual with it, and let me know how it > goes. Thanks! Seems to be working quite well in some contrived tests and a few fragments of realistic looking code. Thank you! Have a lovely evening. =2D-=20 Arsen Arsenovi=C4=87 --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iOYEARYKAI4WIQT+4rPRE/wAoxYtYGFSwpQwHqLEkwUCZt9+ml8UgAAAAAAuAChp c3N1ZXItZnByQG5vdGF0aW9ucy5vcGVucGdwLmZpZnRoaG9yc2VtYW4ubmV0RkVF MkIzRDExM0ZDMDBBMzE2MkQ2MDYxNTJDMjk0MzAxRUEyQzQ5MxAcYXJzZW5AYWFy c2VuLm1lAAoJEFLClDAeosSTD2MA/1LbmLWU2ZHm1jDXY1oq2bf/3qto8US6s7k8 Ei1n1v5pAQD3q9gg+RGSbAY059lcSRSLsOR5j4/f3q0Vo+XGQmjpDQ== =89M1 -----END PGP SIGNATURE----- --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Fri Sep 20 10:59:33 2024 Received: (at 72695) by debbugs.gnu.org; 20 Sep 2024 14:59:33 +0000 Received: from localhost ([127.0.0.1]:36087 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1srf6a-0007wv-0b for submit@debbugs.gnu.org; Fri, 20 Sep 2024 10:59:33 -0400 Received: from mail.muc.de ([193.149.48.3]:53333) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1srf6W-0007wa-8S for 72695@debbugs.gnu.org; Fri, 20 Sep 2024 10:59:30 -0400 Received: (qmail 24657 invoked by uid 3782); 20 Sep 2024 16:59:02 +0200 Received: from muc.de (pd953aea2.dip0.t-ipconnect.de [217.83.174.162]) (using STARTTLS) by colin.muc.de (tmda-ofmipd) with ESMTP; Fri, 20 Sep 2024 16:59:01 +0200 Received: (qmail 11736 invoked by uid 1000); 20 Sep 2024 14:59:01 -0000 Date: Fri, 20 Sep 2024 14:59:01 +0000 To: Arsen =?utf-8?Q?Arsenovi=C4=87?= Subject: Re: bug#72695: CC Mode 5.35.2 (C++//l); c++-mode misindents 'if constexpr' inside lambdas Message-ID: References: <8634n2qhw7.fsf@aarsen.me> <86wmk9vcd9.fsf@aarsen.me> <875xrhtsuu.fsf@aarsen.me> <86y14cfan1.fsf@aarsen.me> <86a5ggsa5h.fsf@aarsen.me> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <86a5ggsa5h.fsf@aarsen.me> X-Submission-Agent: TMDA/1.3.x (Ph3nix) From: Alan Mackenzie X-Primary-Address: acm@muc.de X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 72695 Cc: acm@muc.de, 72695@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hello, Arsen. On Tue, Sep 10, 2024 at 01:02:50 +0200, Arsen Arsenović wrote: > Hi Alan, > Alan Mackenzie writes: [ .... ] I'm hoping I've now fixed this bug (see patch below). [ .... ] > >> I've tried it on a few examples I came up with, it seems to work well in > >> 'real-life' code. > >> I've also constructed the following "stress test" which includes (almost > >> - see below) all the productions that can exist in a lambda function, in > >> the same context as the original bad example: > > Thanks, this was very useful. As an important question, can and alignas > > specifier exist inside a lambda expression? If so, what does it mean? > > My new patch below doesn't (yet) handle it. > It certainly can in the body. I presume you mean in the > leader/declarator/whathaveyou however; in that case, yes, as part of the > attribute-specifier-seq in lambda-expression and lambda-declarator, and > its meaning depends on the position (see > https://eel.is/c++draft/expr.prim.lambda#closure-6). Thanks, I've now found the place in the C++ syntax where alignas can go in a lambda construct. It is the only specifier which may go in these places, although any number of attributes are allowed. (As a matter of interest, attributes in CC Mode are treated as syntactic whitespace.) [ .... ] > >> void > >> def () > >> { > >> auto foo = [&, > >> a, > >> b = 123, > >> c, > >> ...d, > >> ...e = 123 > >> ] > >> >> typename S> > >> //alignas (128) > >> [[gnu::noreturn]] > >> requires some_concept > >> (int a, > >> int b, > >> int c) > >> consteval > >> constexpr > >> mutable > >> static > >> //noexcept(true) > >> [[gnu::packed]] > >> //alignas (128) > >> //-> > >> //int > >> //requires (std::same_as ) > >> { > >> if constexpr (true) > >> ; > >> } > >> } Question: Is that first (commented out) alignas correct where it is? My reading of the version of the standard suggests that the alignas (128) should come _after_ the requires some_concept, not before it. > > Here's a modified version which is now fully handled (as far as it goes): And here's a further modified version, which my patch (below) now handles: void def () { auto foo = [&, a, b = 123, c, ...d, ...e = 123 ] //alignas (128) [[gnu::noreturn]] requires some_concept alignas (128) (int a, int b, int c) consteval constexpr mutable static noexcept(true) [[gnu::packed]] alignas (128) -> int requires (std::same_as ) { if constexpr (true) ; } } [ .... ] > >> Hopefully these examples help. > > Very much so. > >> Please also note that in a few places (such as alignas, the noexcept > >> specifier, RHS of assignments in the capture list) near-arbitrary > >> expressions can appear, and that requires clause have special boolean > >> expression syntax (see > >> https://eel.is/c++draft/temp.pre#nt:requires-clause). > > I'm afraid I haven't looked at this, yet. I have now. :-) [ .... ] > > Here's an up to date version of the patch, which should work better than > > the last version. Please do the usual with it, and let me know how it > > goes. Thanks! And here's what I'm hoping will be the final version of the patch to fix this bug. Again, could you try it out (on real code as well as test code), and let me know how well it works. It should apply cleanly to the Emacs master branch. Thanks! Even it the patch is good, I'm not quite ready to commit it yet, since I need to amend the test suite somewhat. diff -r 48ad661a2d7d cc-align.el --- a/cc-align.el Mon Jul 22 12:09:34 2024 +0000 +++ b/cc-align.el Fri Sep 20 14:15:17 2024 +0000 @@ -95,7 +95,9 @@ (c-backward-syntactic-ws (c-langelem-pos langelem)) (if (and (memq (char-before) '(?} ?,)) (not (and c-overloadable-operators-regexp - (c-after-special-operator-id)))) + (c-after-special-operator-id))) + (progn (goto-char (c-langelem-pos langelem)) + (not (looking-at c-requires-clause-key)))) c-basic-offset)))) (defun c-lineup-gnu-DEFUN-intro-cont (langelem) diff -r 48ad661a2d7d cc-engine.el --- a/cc-engine.el Mon Jul 22 12:09:34 2024 +0000 +++ b/cc-engine.el Fri Sep 20 14:15:17 2024 +0000 @@ -8694,10 +8694,9 @@ (c-forward-syntactic-ws) (c-forward-id-comma-list ref t t)) - ((and (c-keyword-member kwd-sym 'c-paren-any-kwds) + ((and (c-keyword-member kwd-sym 'c-paren-type-kwds) (eq (char-after) ?\()) ;; There's an open paren after a keyword in `c-paren-any-kwds'. - (forward-char) (when (and (setq pos (c-up-list-forward)) (eq (char-before pos) ?\))) @@ -8715,6 +8714,12 @@ (setq safe-pos (point))) (c-forward-syntactic-ws)) + ((c-keyword-member kwd-sym 'c-paren-nontype-kwds) + (when (and (eq (char-after) ?\() + (c-go-list-forward)) + (setq safe-pos (point)) + (c-forward-syntactic-ws))) + ((and (c-keyword-member kwd-sym 'c-<>-sexp-kwds) (eq (char-after) ?<) (c-forward-<>-arglist (c-keyword-member kwd-sym 'c-<>-type-kwds))) @@ -9914,9 +9919,6 @@ ;; ;; Note that this function is incomplete, handling only those cases expected ;; to be common in a C++20 requires clause. - ;; - ;; Note also that (...) is not recognized as a primary expression if the - ;; next token is an open brace. (let ((here (point)) (c-restricted-<>-arglists t) (c-parse-and-markup-<>-arglists nil) @@ -9929,12 +9931,10 @@ ((eq (char-after) ?\() (and (c-go-list-forward (point) limit) (eq (char-before) ?\)) - (let ((after-paren (point))) - (c-forward-syntactic-ws limit) - (prog1 - (not (eq (char-after) ?{)) - (when stop-at-end - (goto-char after-paren)))))) + (progn + (unless stop-at-end + (c-forward-syntactic-ws limit)) + t))) ((c-forward-over-compound-identifier) (let ((after-id (point))) (c-forward-syntactic-ws limit) @@ -9953,9 +9953,7 @@ (c-forward-over-compound-identifier) (c-forward-syntactic-ws limit)))))) (goto-char after-id))) - ((and - (looking-at c-fun-name-substitute-key) ; "requires" - (not (eq (char-after (match-end 0)) ?_))) + ((looking-at c-fun-name-substitute-key) ; "requires" (goto-char (match-end 1)) (c-forward-syntactic-ws limit) (and @@ -10210,9 +10208,7 @@ ((looking-at c-type-decl-suffix-key) (cond ((save-match-data - (and - (looking-at c-fun-name-substitute-key) - (not (eq (char-after (match-end 0)) ?_)))) + (looking-at c-requires-clause-key)) (c-forward-c++-requires-clause)) ((eq (char-after) ?\() (if (c-forward-decl-arglist not-top decorated limit) @@ -10667,10 +10663,8 @@ (c-forward-keyword-clause 1) (when (and (c-major-mode-is 'c++-mode) (c-keyword-member kwd-sym 'c-<>-sexp-kwds) - (save-match-data - (and - (looking-at c-fun-name-substitute-key) - (not (eq (char-after (match-end 0)) ?_))))) + (save-match-data ; Probably unnecessary (2024-09-20) + (looking-at c-requires-clause-key))) (c-forward-c++-requires-clause)) (setq kwd-clause-end (point)))) ((and c-opt-cpp-prefix @@ -11028,9 +11022,7 @@ ((save-match-data (looking-at "\\s(")) (c-safe (c-forward-sexp 1) t)) ((save-match-data - (and - (looking-at c-fun-name-substitute-key) - (not (eq (char-after (match-end 0)) ?_)))) ; C++ requires + (looking-at c-requires-clause-key)) (c-forward-c++-requires-clause)) (t (goto-char (match-end 1)) t)) @@ -13178,229 +13170,218 @@ ;; ;; Here, "brace list" does not include the body of an enum. (save-excursion - (let ((start (point)) - (braceassignp 'dontknow) - inexpr-brace-list bufpos macro-start res pos after-type-id-pos - pos2 in-paren parens-before-brace - paren-state paren-pos) - - (setq res - (or (progn (c-backward-syntactic-ws) - (c-back-over-compound-identifier)) - (c-backward-token-2 1 t lim))) - ;; Checks to do only on the first sexp before the brace. - ;; Have we a C++ initialization, without an "="? - (if (and (c-major-mode-is 'c++-mode) - (cond - ((and (or (not (memq res '(t 0))) - (eq (char-after) ?,)) - (setq paren-state (c-parse-state)) - (setq paren-pos (c-pull-open-brace paren-state)) - (eq (char-after paren-pos) ?\()) - (goto-char paren-pos) - (setq braceassignp 'c++-noassign - in-paren 'in-paren)) - ((looking-at c-pre-brace-non-bracelist-key) - (setq braceassignp nil)) - ((and - (looking-at c-fun-name-substitute-key) - (not (eq (char-after (match-end 0)) ?_))) - (setq braceassignp nil)) - ((looking-at c-return-key)) - ((and (looking-at c-symbol-start) - (not (looking-at c-keywords-regexp))) - (if (save-excursion - (and (zerop (c-backward-token-2 1 t lim)) - (looking-at c-pre-id-bracelist-key))) - (setq braceassignp 'c++-noassign) - (setq after-type-id-pos (point)))) - ((eq (char-after) ?\() - (setq parens-before-brace t) - ;; Have we a requires with a parenthesis list? - (when (save-excursion - (and (zerop (c-backward-token-2 1 nil lim)) - (looking-at c-fun-name-substitute-key) - (not (eq (char-after (match-end 0)) ?_)))) + (unless (and (c-major-mode-is 'c++-mode) + (c-backward-over-lambda-expression lim)) + (let ((start (point)) + (braceassignp 'dontknow) + inexpr-brace-list bufpos macro-start res pos after-type-id-pos + pos2 in-paren paren-state paren-pos) + + (setq res + (or (progn (c-backward-syntactic-ws) + (c-back-over-compound-identifier)) + (c-backward-token-2 1 t lim))) + ;; Checks to do only on the first sexp before the brace. + ;; Have we a C++ initialization, without an "="? + (if (and (c-major-mode-is 'c++-mode) + (cond + ((and (or (not (memq res '(t 0))) + (eq (char-after) ?,)) + (setq paren-state (c-parse-state)) + (setq paren-pos (c-pull-open-brace paren-state)) + (eq (char-after paren-pos) ?\()) + (goto-char paren-pos) + (setq braceassignp 'c++-noassign + in-paren 'in-paren)) + ((looking-at c-pre-brace-non-bracelist-key) (setq braceassignp nil)) - nil) - (t nil)) - (save-excursion - (cond - ((or (not (memq res '(t 0))) - (eq (char-after) ?,)) - (and (setq paren-state (c-parse-state)) - (setq paren-pos (c-pull-open-brace paren-state)) - (eq (char-after paren-pos) ?\() - (setq in-paren 'in-paren) - (goto-char paren-pos))) - ((looking-at c-pre-brace-non-bracelist-key)) + ((looking-at c-fun-name-substitute-key) + (setq braceassignp nil)) ((looking-at c-return-key)) ((and (looking-at c-symbol-start) - (not (looking-at c-keywords-regexp)) - (save-excursion - (and (zerop (c-backward-token-2 1 t lim)) - (looking-at c-pre-id-bracelist-key))))) - (t (setq after-type-id-pos (point)) - nil)))) - (setq braceassignp 'c++-noassign)) - - (when (and c-opt-inexpr-brace-list-key - (eq (char-after) ?\[)) - ;; In Java, an initialization brace list may follow - ;; directly after "new Foo[]", so check for a "new" - ;; earlier. - (while (eq braceassignp 'dontknow) - (setq braceassignp - (cond ((/= (c-backward-token-2 1 t lim) 0) nil) - ((looking-at c-opt-inexpr-brace-list-key) - (setq inexpr-brace-list t) - t) - ((looking-at "\\sw\\|\\s_\\|[.[]") - ;; Carry on looking if this is an - ;; identifier (may contain "." in Java) - ;; or another "[]" sexp. - 'dontknow) - (t nil))))) - - (setq pos (point)) - (cond - ((not braceassignp) - nil) - ((and after-type-id-pos - (goto-char after-type-id-pos) - (setq res (c-back-over-member-initializers)) - (goto-char res) - (eq (car (c-beginning-of-decl-1 lim)) 'same)) - (cons (point) nil)) ; Return value. - - ((and after-type-id-pos - (progn - (c-backward-syntactic-ws) - (eq (char-before) ?\())) - ;; Single identifier between '(' and '{'. We have a bracelist. - (cons after-type-id-pos 'in-paren)) - - ;; Are we at the parens of a C++ lambda expression? - ((and parens-before-brace - (save-excursion - (and - (zerop (c-backward-token-2 1 t lim)) - (c-looking-at-c++-lambda-capture-list)))) - nil) ; a lambda expression isn't a brace list. - - (t - (goto-char pos) - (when (eq braceassignp 'dontknow) - (let* ((cache-entry (and containing-sexp - (c-laomib-get-cache containing-sexp pos))) - (lim2 (or (cadr cache-entry) lim)) - sub-bassign-p) - (if cache-entry - (cond - ((<= (point) (cadr cache-entry)) - ;; We're inside the region we've already scanned over, so - ;; just go to that scan's end position. - (goto-char (nth 2 cache-entry)) - (setq braceassignp (nth 3 cache-entry))) - ((> (point) (cadr cache-entry)) - ;; We're beyond the previous scan region, so just scan as - ;; far as the end of that region. - (setq sub-bassign-p (c-laomib-loop lim2)) - (if (<= (point) (cadr cache-entry)) - (progn - (c-laomib-put-cache containing-sexp - start (nth 2 cache-entry) - (nth 3 cache-entry) ;; sub-bassign-p - ) - (setq braceassignp (nth 3 cache-entry)) - (goto-char (nth 2 cache-entry))) - (c-laomib-put-cache containing-sexp - start (point) sub-bassign-p) - (setq braceassignp sub-bassign-p))) - (t)) - - (setq braceassignp (c-laomib-loop lim)) - (when lim - (c-laomib-put-cache lim start (point) braceassignp))))) - + (not (looking-at c-keywords-regexp))) + (if (save-excursion + (and (zerop (c-backward-token-2 1 t lim)) + (looking-at c-pre-id-bracelist-key))) + (setq braceassignp 'c++-noassign) + (setq after-type-id-pos (point)))) + ((eq (char-after) ?\() + ;; Have we a requires with a parenthesis list? + (when (save-excursion + (and (zerop (c-backward-token-2 1 nil lim)) + (looking-at c-fun-name-substitute-key))) + (setq braceassignp nil)) + nil) + (t nil)) + (save-excursion + (cond + ((or (not (memq res '(t 0))) + (eq (char-after) ?,)) + (and (setq paren-state (c-parse-state)) + (setq paren-pos (c-pull-open-brace paren-state)) + (eq (char-after paren-pos) ?\() + (setq in-paren 'in-paren) + (goto-char paren-pos))) + ((looking-at c-pre-brace-non-bracelist-key)) + ((looking-at c-return-key)) + ((and (looking-at c-symbol-start) + (not (looking-at c-keywords-regexp)) + (save-excursion + (and (zerop (c-backward-token-2 1 t lim)) + (looking-at c-pre-id-bracelist-key))))) + (t (setq after-type-id-pos (point)) + nil)))) + (setq braceassignp 'c++-noassign)) + + (when (and c-opt-inexpr-brace-list-key + (eq (char-after) ?\[)) + ;; In Java, an initialization brace list may follow + ;; directly after "new Foo[]", so check for a "new" + ;; earlier. + (while (eq braceassignp 'dontknow) + (setq braceassignp + (cond ((/= (c-backward-token-2 1 t lim) 0) nil) + ((looking-at c-opt-inexpr-brace-list-key) + (setq inexpr-brace-list t) + t) + ((looking-at "\\sw\\|\\s_\\|[.[]") + ;; Carry on looking if this is an + ;; identifier (may contain "." in Java) + ;; or another "[]" sexp. + 'dontknow) + (t nil))))) + + (setq pos (point)) (cond - (braceassignp - ;; We've hit the beginning of the aggregate list. - (setq pos2 (point)) - (cons - (if (eq (c-beginning-of-statement-1 containing-sexp) 'same) - (point) - pos2) - (or in-paren inexpr-brace-list))) + ((not braceassignp) + nil) + ((and after-type-id-pos + (goto-char after-type-id-pos) + (setq res (c-back-over-member-initializers)) + (goto-char res) + (eq (car (c-beginning-of-decl-1 lim)) 'same)) + (cons (point) nil)) ; Return value. + ((and after-type-id-pos - (save-excursion - (when (eq (char-after) ?\;) - (c-forward-over-token-and-ws t)) - (setq bufpos (point)) - (when (looking-at c-opt-<>-sexp-key) - (c-forward-over-token-and-ws) - (when (and (eq (char-after) ?<) - (c-get-char-property (point) 'syntax-table)) - (c-go-list-forward nil after-type-id-pos) - (c-forward-syntactic-ws))) - (if (and (not (eq (point) after-type-id-pos)) - (or (not (looking-at c-class-key)) - (save-excursion - (goto-char (match-end 1)) - (c-forward-syntactic-ws) - (not (eq (point) after-type-id-pos))))) - (progn - (setq res - (c-forward-decl-or-cast-1 (c-point 'bosws) - nil nil)) - (and (consp res) - (cond - ((eq (car res) after-type-id-pos)) - ((> (car res) after-type-id-pos) nil) - (t - (catch 'find-decl + (progn + (c-backward-syntactic-ws) + (eq (char-before) ?\())) + ;; Single identifier between '(' and '{'. We have a bracelist. + (cons after-type-id-pos 'in-paren)) + + (t + (goto-char pos) + (when (eq braceassignp 'dontknow) + (let* ((cache-entry (and containing-sexp + (c-laomib-get-cache containing-sexp pos))) + (lim2 (or (cadr cache-entry) lim)) + sub-bassign-p) + (if cache-entry + (cond + ((<= (point) (cadr cache-entry)) + ;; We're inside the region we've already scanned over, so + ;; just go to that scan's end position. + (goto-char (nth 2 cache-entry)) + (setq braceassignp (nth 3 cache-entry))) + ((> (point) (cadr cache-entry)) + ;; We're beyond the previous scan region, so just scan as + ;; far as the end of that region. + (setq sub-bassign-p (c-laomib-loop lim2)) + (if (<= (point) (cadr cache-entry)) + (progn + (c-laomib-put-cache containing-sexp + start (nth 2 cache-entry) + (nth 3 cache-entry) ;; sub-bassign-p + ) + (setq braceassignp (nth 3 cache-entry)) + (goto-char (nth 2 cache-entry))) + (c-laomib-put-cache containing-sexp + start (point) sub-bassign-p) + (setq braceassignp sub-bassign-p))) + (t)) + + (setq braceassignp (c-laomib-loop lim)) + (when lim + (c-laomib-put-cache lim start (point) braceassignp))))) + + (cond + (braceassignp + ;; We've hit the beginning of the aggregate list. + (setq pos2 (point)) + (cons + (if (eq (c-beginning-of-statement-1 containing-sexp) 'same) + (point) + pos2) + (or in-paren inexpr-brace-list))) + ((and after-type-id-pos + (save-excursion + (when (eq (char-after) ?\;) + (c-forward-over-token-and-ws t)) + (setq bufpos (point)) + (when (looking-at c-opt-<>-sexp-key) + (c-forward-over-token-and-ws) + (when (and (eq (char-after) ?<) + (c-get-char-property (point) 'syntax-table)) + (c-go-list-forward nil after-type-id-pos) + (c-forward-syntactic-ws))) + (if (and (not (eq (point) after-type-id-pos)) + (or (not (looking-at c-class-key)) (save-excursion - (goto-char (car res)) - (c-do-declarators - (point-max) t nil nil - (lambda (id-start _id-end _tok _not-top _func _init) - (cond - ((> id-start after-type-id-pos) - (throw 'find-decl nil)) - ((eq id-start after-type-id-pos) - (throw 'find-decl t))))) - nil)))))) - (save-excursion - (goto-char start) - (not (c-looking-at-statement-block)))))) - (cons bufpos (or in-paren inexpr-brace-list))) - ((or (eq (char-after) ?\;) - ;; Brace lists can't contain a semicolon, so we're done. - (save-excursion - (c-backward-syntactic-ws) - (eq (char-before) ?})) - ;; They also can't contain a bare }, which is probably the end - ;; of a function. - ) - nil) - ((and (setq macro-start (point)) - (c-forward-to-cpp-define-body) - (eq (point) start)) - ;; We've a macro whose expansion starts with the '{'. - ;; Heuristically, if we have a ';' in it we've not got a - ;; brace list, otherwise we have. - (let ((macro-end (progn (c-end-of-macro) (point)))) - (goto-char start) - (forward-char) - (if (and (c-syntactic-re-search-forward "[;,]" macro-end t t) - (eq (char-before) ?\;)) - nil - (cons macro-start nil)))) ; (2016-08-30): Lazy! We have no + (goto-char (match-end 1)) + (c-forward-syntactic-ws) + (not (eq (point) after-type-id-pos))))) + (progn + (setq res + (c-forward-decl-or-cast-1 (c-point 'bosws) + nil nil)) + (and (consp res) + (cond + ((eq (car res) after-type-id-pos)) + ((> (car res) after-type-id-pos) nil) + (t + (catch 'find-decl + (save-excursion + (goto-char (car res)) + (c-do-declarators + (point-max) t nil nil + (lambda (id-start _id-end _tok _not-top _func _init) + (cond + ((> id-start after-type-id-pos) + (throw 'find-decl nil)) + ((eq id-start after-type-id-pos) + (throw 'find-decl t))))) + nil)))))) + (save-excursion + (goto-char start) + (not (c-looking-at-statement-block)))))) + (cons bufpos (or in-paren inexpr-brace-list))) + ((or (eq (char-after) ?\;) + ;; Brace lists can't contain a semicolon, so we're done. + (save-excursion + (c-backward-syntactic-ws) + (eq (char-before) ?})) + ;; They also can't contain a bare }, which is probably the end + ;; of a function. + ) + nil) + ((and (setq macro-start (point)) + (c-forward-to-cpp-define-body) + (eq (point) start)) + ;; We've a macro whose expansion starts with the '{'. + ;; Heuristically, if we have a ';' in it we've not got a + ;; brace list, otherwise we have. + (let ((macro-end (progn (c-end-of-macro) (point)))) + (goto-char start) + (forward-char) + (if (and (c-syntactic-re-search-forward "[;,]" macro-end t t) + (eq (char-before) ?\;)) + nil + (cons macro-start nil)))) ; (2016-08-30): Lazy! We have no ; languages where ; `c-opt-inexpr-brace-list-key' is ; non-nil and we have macros. - (t t)))) ;; The caller can go up one level. - ))) + (t t)))) ;; The caller can go up one level. + )))) (defun c-inside-bracelist-p (containing-sexp paren-state accept-in-paren) ;; return the buffer position of the beginning of the brace list statement @@ -13652,7 +13633,7 @@ nil)) ((progn (goto-char req-pos) - (if (looking-at c-fun-name-substitute-key) + (if (looking-at c-requires-clause-key) (setq found-clause (c-forward-c++-requires-clause nil t)) (and (c-forward-concept-fragment) (setq found-clause (point)))) @@ -13863,18 +13844,84 @@ (looking-at c-pre-lambda-tokens-re))) (not (c-in-literal)))) +(defun c-looking-at-c++-lambda-expression (&optional lim) + ;; If point is at the [ opening a C++ lambda expressions's capture list, + ;; and the lambda expression is complete, return the position of the { which + ;; opens the body form, otherwise return nil. LIM is the limit for forward + ;; searching for the {. + (let ((here (point)) + (lim-or-max (or lim (point-max))) + got-params) + (when (and (c-looking-at-c++-lambda-capture-list) + (c-go-list-forward nil lim)) + (c-forward-syntactic-ws lim) + (when (c-forward-<>-arglist t) + (c-forward-syntactic-ws lim) + (when (looking-at c-requires-clause-key) + (c-forward-c++-requires-clause lim nil))) + (when (looking-at "\\(alignas\\)\\([^a-zA-Z0-9_$]\\|$\\)") + (c-forward-keyword-clause 1)) + (when (and (eq (char-after) ?\() + (c-go-list-forward nil lim)) + (setq got-params t) + (c-forward-syntactic-ws lim)) + (while (and c-lambda-spec-key (looking-at c-lambda-spec-key)) + (goto-char (match-end 1)) + (c-forward-syntactic-ws lim)) + (let (after-except-pos) + (while + (and (<= (point) lim-or-max) + (cond + ((save-excursion + (and (looking-at "throw\\([^a-zA-Z0-9_]\\|$\\)") + (progn (goto-char (match-beginning 1)) + (c-forward-syntactic-ws lim) + (eq (char-after) ?\()) + (c-go-list-forward nil lim) + (progn (c-forward-syntactic-ws lim) + (setq after-except-pos (point))))) + (goto-char after-except-pos) + (c-forward-syntactic-ws lim) + t) + ((looking-at c-paren-nontype-key) ; "noexcept" or "alignas" + (c-forward-keyword-clause 1)))))) + (and (<= (point) lim-or-max) + (looking-at c-haskell-op-re) + (goto-char (match-end 0)) + (progn (c-forward-syntactic-ws lim) + (c-forward-type t))) ; t is BRACE-BLOCK-TOO. + (and got-params + (<= (point) lim-or-max) + (looking-at c-requires-clause-key) + (c-forward-c++-requires-clause lim nil)) + (prog1 (and (<= (point) lim-or-max) + (eq (char-after) ?{) + (point)) + (goto-char here))))) + +(defun c-backward-over-lambda-expression (&optional lim) + ;; Point is at a {. Move back over the lambda expression this is a part of, + ;; stopping at the [ of the capture list, if this is the case, returning + ;; the position of that opening bracket. If we're not at such a list, leave + ;; point unchanged and return nil. + (let ((here (point))) + (c-syntactic-skip-backward "^;}]" lim t) + (if (and (eq (char-before) ?\]) + (c-go-list-backward nil lim) + (eq (c-looking-at-c++-lambda-expression (1+ here)) + here)) + (point) + (goto-char here) + nil))) + (defun c-c++-vsemi-p (&optional pos) ;; C++ Only - Is there a "virtual semicolon" at POS or point? ;; (See cc-defs.el for full details of "virtual semicolons".) ;; ;; This is true when point is at the last non syntactic WS position on the - ;; line, and either there is a "macro with semicolon" just before it (see - ;; `c-at-macro-vsemi-p') or there is a "requires" clause which ends there. - (let (res) - (cond - ((setq res (c-in-requires-or-at-end-of-clause pos)) - (and res (eq (cdr res) t))) - ((c-at-macro-vsemi-p))))) + ;; line, and there is a "macro with semicolon" just before it (see + ;; `c-at-macro-vsemi-p'). + (c-at-macro-vsemi-p pos)) (defun c-at-macro-vsemi-p (&optional pos) ;; Is there a "virtual semicolon" at POS or point? @@ -14857,7 +14904,6 @@ (progn (c-backward-syntactic-ws lim) (zerop (c-backward-token-2 nil nil lim))) (looking-at c-fun-name-substitute-key) - (not (eq (char-after (match-end 0)) ?_)) (setq placeholder (point)))) (goto-char placeholder) (back-to-indentation) @@ -15283,6 +15329,11 @@ ;; NOTE: The point is at the end of the previous token here. + ;; CASE 5U: We are just after a requires clause. + ((and (setq placeholder (c-in-requires-or-at-end-of-clause)) + (eq (cdr-safe placeholder) t)) + (c-add-syntax 'topmost-intro-cont (car placeholder))) + ;; CASE 5J: we are at the topmost level, make ;; sure we skip back past any access specifiers ((and @@ -15818,8 +15869,7 @@ (c-go-list-backward nil lim)) (progn (c-backward-syntactic-ws lim) (zerop (c-backward-token-2 nil nil lim))) - (looking-at c-fun-name-substitute-key) - (not (eq (char-after (match-end 0)) ?_)))) + (looking-at c-fun-name-substitute-key))) (goto-char containing-sexp) (back-to-indentation) (c-add-stmt-syntax 'defun-close nil t lim paren-state)) @@ -15983,8 +16033,7 @@ (c-go-list-backward nil lim)) (progn (c-backward-syntactic-ws lim) (zerop (c-backward-token-2 nil nil lim))) - (looking-at c-fun-name-substitute-key) - (not (eq (char-after (match-end 0)) ?_)))) + (looking-at c-fun-name-substitute-key))) (goto-char containing-sexp) (back-to-indentation) (c-add-syntax 'defun-block-intro (point))) diff -r 48ad661a2d7d cc-fonts.el --- a/cc-fonts.el Mon Jul 22 12:09:34 2024 +0000 +++ b/cc-fonts.el Fri Sep 20 14:15:17 2024 +0000 @@ -1389,8 +1389,7 @@ (memq type '(c-decl-arg-start c-decl-type-start)))))))) ((and (zerop (c-backward-token-2)) - (looking-at c-fun-name-substitute-key) - (not (eq (char-after (match-end 0)) ?_)))))))))) + (looking-at c-fun-name-substitute-key))))))))) ;; Cache the result of this test for next time around. (c-put-char-property (1- match-pos) 'c-type 'c-decl-arg-start) (cons 'decl nil)) diff -r 48ad661a2d7d cc-langs.el --- a/cc-langs.el Mon Jul 22 12:09:34 2024 +0000 +++ b/cc-langs.el Fri Sep 20 14:15:17 2024 +0000 @@ -2639,6 +2639,19 @@ t (c-make-keywords-re t (c-lang-const c-equals-type-clause-kwds))) (c-lang-defvar c-equals-type-clause-key (c-lang-const c-equals-type-clause-key)) +(c-lang-defconst c-lambda-spec-kwds + "Keywords which are specifiers of certain elements of a C++ lambda function. +This is only used in C++ Mode." + t nil + c++ '("mutable" "constexpr" "consteval" "static")) + +(c-lang-defconst c-lambda-spec-key + ;; A regular expression which matches a member of `c-lambda-spec-kwds', + ;; or nil. + t (if (c-lang-const c-lambda-spec-kwds) + (c-make-keywords-re t (c-lang-const c-lambda-spec-kwds)))) +(c-lang-defvar c-lambda-spec-key (c-lang-const c-lambda-spec-key)) + (c-lang-defconst c-equals-nontype-decl-kwds "Keywords which are followed by an identifier then an \"=\" sign, which declares the identifier to be something other than a @@ -2657,20 +2670,33 @@ (c-lang-defconst c-fun-name-substitute-kwds "Keywords which take the place of type+declarator at the beginning of a function-like structure, such as a C++20 \"requires\" -clause. An arglist may or may not follow such a keyword." +expression. An arglist may or may not follow such a keyword. +Not to be confused with `c-requires-clause-kwds'." t nil c++ '("requires")) (c-lang-defconst c-fun-name-substitute-key ;; An unadorned regular expression which matches any member of ;; `c-fun-name-substitute-kwds'. - t (c-make-keywords-re 'appendable (c-lang-const c-fun-name-substitute-kwds))) + t (c-make-keywords-re t (c-lang-const c-fun-name-substitute-kwds))) ;; We use 'appendable, so that we get "\\>" on the regexp, but without a further ;; character, which would mess up backward regexp search from just after the ;; keyword. If only XEmacs had \\_>. ;-( (c-lang-defvar c-fun-name-substitute-key (c-lang-const c-fun-name-substitute-key)) +(c-lang-defconst c-requires-clause-kwds + "Keywords which introduce a C++ requires clause, or something analogous. +This should not be confused with `c-fun-name-substitute-kwds'." + t nil + c++ '("requires")) + +(c-lang-defconst c-requires-clause-key + ;; A regexp matching any member of `c-requires-clause-kwds'. + t (c-make-keywords-re t (c-lang-const c-requires-clause-kwds))) +;; See `c-fun-name-substitute-key' for the justification of appendable. +(c-lang-defvar c-requires-clause-key (c-lang-const c-requires-clause-key)) + (c-lang-defconst c-modifier-kwds "Keywords that can prefix normal declarations of identifiers \(and typically act as flags). Things like argument declarations > Seems to be working quite well in some contrived tests and a few > fragments of realistic looking code. > Thank you! > Have a lovely evening. > -- > Arsen Arsenović -- Alan Mackenzie (Nuremberg, Germany). From debbugs-submit-bounces@debbugs.gnu.org Sat Sep 21 15:33:42 2024 Received: (at 72695) by debbugs.gnu.org; 21 Sep 2024 19:33:43 +0000 Received: from localhost ([127.0.0.1]:40336 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ss5rS-00038w-Ay for submit@debbugs.gnu.org; Sat, 21 Sep 2024 15:33:42 -0400 Received: from mout-p-103.mailbox.org ([80.241.56.161]:55446) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ss5rP-00038c-5O for 72695@debbugs.gnu.org; Sat, 21 Sep 2024 15:33:40 -0400 Received: from smtp1.mailbox.org (smtp1.mailbox.org [IPv6:2001:67c:2050:b231:465::1]) (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 mout-p-103.mailbox.org (Postfix) with ESMTPS id 4X9ztH07Y7z9sW6; Sat, 21 Sep 2024 21:32:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aarsen.me; s=MBO0001; t=1726947159; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=vGDMu6vi8l7q52y5OBFnzCQgFU4ELfTQ958tLwoA9GU=; b=L8cuHj1wpLwEgbbsu2l70W7uKuZ4oh5h62XufEk+GLG8LLIp683lsWnCyHHWyDq3uSw6pS 2uXpmiMp+yIubTjZ+pd9FEdf+5115BOeCG8eEbXSqq+RjxqAShiSD5Oplzt4m0eZ4Ni/6C m1gEL6PaiScRAdOJj4onH5gS+UUU0ezw131n8L4mqlslz1kqvKHugJNhifdF0VCxaS9S1N T1kbwf+KfCB+BoqGDw+uvhFgn/9qBp+30WNhOkzVvDqhMIHo67aFAJSRNlBVuUJL0JpUzw IHL7gd+b6yQAHil0tp3NsaqltZw+OVhSHDf2TC8TMM6Iq7Xp0Kmo/TDWPqvedA== From: =?utf-8?Q?Arsen_Arsenovi=C4=87?= To: Alan Mackenzie Subject: Re: bug#72695: CC Mode 5.35.2 (C++//l); c++-mode misindents 'if constexpr' inside lambdas In-Reply-To: (Alan Mackenzie's message of "Fri, 20 Sep 2024 14:59:01 +0000") References: <8634n2qhw7.fsf@aarsen.me> <86wmk9vcd9.fsf@aarsen.me> <875xrhtsuu.fsf@aarsen.me> <86y14cfan1.fsf@aarsen.me> <86a5ggsa5h.fsf@aarsen.me> Date: Sat, 21 Sep 2024 21:32:36 +0200 Message-ID: <86h6a8by5n.fsf@aarsen.me> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Rspamd-Queue-Id: 4X9ztH07Y7z9sW6 X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 72695 Cc: 72695@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi Alan, Alan Mackenzie writes: > Hello, Arsen. > > On Tue, Sep 10, 2024 at 01:02:50 +0200, Arsen Arsenovi=C4=87 wrote: >> Hi Alan, > >> Alan Mackenzie writes: > > [ .... ] > > I'm hoping I've now fixed this bug (see patch below). Thank you! > [ .... ] > >> >> I've tried it on a few examples I came up with, it seems to work well= in >> >> 'real-life' code. > >> >> I've also constructed the following "stress test" which includes (alm= ost >> >> - see below) all the productions that can exist in a lambda function,= in >> >> the same context as the original bad example: > >> > Thanks, this was very useful. As an important question, can and align= as >> > specifier exist inside a lambda expression? If so, what does it mean? >> > My new patch below doesn't (yet) handle it. > >> It certainly can in the body. I presume you mean in the >> leader/declarator/whathaveyou however; in that case, yes, as part of the >> attribute-specifier-seq in lambda-expression and lambda-declarator, and >> its meaning depends on the position (see >> https://eel.is/c++draft/expr.prim.lambda#closure-6). > > Thanks, I've now found the place in the C++ syntax where alignas can go > in a lambda construct. It is the only specifier which may go in these > places, although any number of attributes are allowed. (As a matter of > interest, attributes in CC Mode are treated as syntactic whitespace.) > > [ .... ] > >> >> void >> >> def () >> >> { >> >> auto foo =3D [&, >> >> a, >> >> b =3D 123, >> >> c, >> >> ...d, >> >> ...e =3D 123 >> >> ] >> >> > >> typename S> >> >> //alignas (128) >> >> [[gnu::noreturn]] >> >> requires some_concept >> >> (int a, >> >> int b, >> >> int c) >> >> consteval >> >> constexpr >> >> mutable >> >> static >> >> //noexcept(true) >> >> [[gnu::packed]] >> >> //alignas (128) >> >> //-> >> >> //int >> >> //requires (std::same_as ) >> >> { >> >> if constexpr (true) >> >> ; >> >> } >> >> } > > Question: Is that first (commented out) alignas correct where it is? My > reading of the version of the standard suggests that the alignas (128) > should come _after_ the requires some_concept, not before it. I think so, through the 2nd lambda-expression derivation: lambda-introducer < template-parameter-list > requires-clause_opt attribute-specifier-seq_opt lambda-declarator compound-statement ... where attribute-specifier-seq is: attribute-specifier-seq_opt attribute-specifier ... and attribute-specifier is also possibly alignment-specifier. Maybe I am missing something, though? >> > Here's a modified version which is now fully handled (as far as it goe= s): > > And here's a further modified version, which my patch (below) now > handles: > > void > def () > { > auto foo =3D [&, > a, > b =3D 123, > c, > ...d, > ...e =3D 123 > ] > typename S> > //alignas (128) > [[gnu::noreturn]] > requires some_concept > alignas (128) > (int a, > int b, > int c) > consteval > constexpr > mutable > static > noexcept(true) > [[gnu::packed]] > alignas (128) > -> int > requires (std::same_as ) > { > if constexpr (true) > ; > } > } > > [ .... ] > >> >> Hopefully these examples help. > >> > Very much so. > >> >> Please also note that in a few places (such as alignas, the noexcept >> >> specifier, RHS of assignments in the capture list) near-arbitrary >> >> expressions can appear, and that requires clause have special boolean >> >> expression syntax (see >> >> https://eel.is/c++draft/temp.pre#nt:requires-clause). > >> > I'm afraid I haven't looked at this, yet. > > I have now. :-) > > [ .... ] > >> > Here's an up to date version of the patch, which should work better th= an >> > the last version. Please do the usual with it, and let me know how it >> > goes. Thanks! > > And here's what I'm hoping will be the final version of the patch to fix > this bug. Again, could you try it out (on real code as well as test > code), and let me know how well it works. It should apply cleanly to the > Emacs master branch. Thanks! > > Even it the patch is good, I'm not quite ready to commit it yet, since I > need to amend the test suite somewhat. I will test it at a later time tonight or tomorrow. Sorry for the delay. Thank you once again for your efforts! Have a lovely evening! =2D-=20 Arsen Arsenovi=C4=87 --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iOYEARYKAI4WIQT+4rPRE/wAoxYtYGFSwpQwHqLEkwUCZu8fVF8UgAAAAAAuAChp c3N1ZXItZnByQG5vdGF0aW9ucy5vcGVucGdwLmZpZnRoaG9yc2VtYW4ubmV0RkVF MkIzRDExM0ZDMDBBMzE2MkQ2MDYxNTJDMjk0MzAxRUEyQzQ5MxAcYXJzZW5AYWFy c2VuLm1lAAoJEFLClDAeosSTYq8BAO45V32QUQkiE4Ig4acT4zJhEtfZyyajt7zF DY+lAORtAP9d3NDcR4Jgyoi1OKzTOwrGoxaqVv51mDHTpH2Nt3ZlCQ== =TvDq -----END PGP SIGNATURE----- --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Wed Sep 25 16:10:16 2024 Received: (at 72695) by debbugs.gnu.org; 25 Sep 2024 20:10:16 +0000 Received: from localhost ([127.0.0.1]:52082 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1stYL1-0005xL-JY for submit@debbugs.gnu.org; Wed, 25 Sep 2024 16:10:16 -0400 Received: from mout-p-201.mailbox.org ([80.241.56.171]:40084) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1stYE7-0005WB-IB for 72695@debbugs.gnu.org; Wed, 25 Sep 2024 16:03:08 -0400 Received: from smtp102.mailbox.org (smtp102.mailbox.org [10.196.197.102]) (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 mout-p-201.mailbox.org (Postfix) with ESMTPS id 4XDSLM33yzz9v52; Wed, 25 Sep 2024 22:02:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aarsen.me; s=MBO0001; t=1727294523; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=eYcuuoXXPUQf7ZrX4FFxTjWRzMbNNk6KYX9P5VHVozg=; b=aM3RRenpBHtqa2CezdBwrb13qDdUO7sKW0XDo8Z1aebXUTM1O+5uXdw8wvMs2oWUMn/ONs pVDjtg+qaqStd4VgUkJDfs7DmyK6w9yHj6Y1JOw12i2/2khyXKGplLkXV3MMXkbFQ3NEtR V5OGX7CgTq5udhnMmH6IMC3BRapOTu6gPc9t0wSjLEDjqNFPKQ7i7ILJXiBC7ro4j+8xqc Igvskozpe6OaEwXHzAWsVmhknTnjrPWtjw/539RWQ81wSBBS/yXfD/vVSV4VIQ5HrAbgXq AbWOSXP5+txwXtYgeoh9FSpQyjAD0fPHEflz6e6poyo68ifLQidtu2eGY1LUBA== From: =?utf-8?Q?Arsen_Arsenovi=C4=87?= To: Alan Mackenzie Subject: Re: bug#72695: CC Mode 5.35.2 (C++//l); c++-mode misindents 'if constexpr' inside lambdas In-Reply-To: (Alan Mackenzie's message of "Fri, 20 Sep 2024 14:59:01 +0000") References: <8634n2qhw7.fsf@aarsen.me> <86wmk9vcd9.fsf@aarsen.me> <875xrhtsuu.fsf@aarsen.me> <86y14cfan1.fsf@aarsen.me> <86a5ggsa5h.fsf@aarsen.me> Date: Wed, 25 Sep 2024 22:01:56 +0200 Message-ID: <86cykrmrij.fsf@aarsen.me> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 72695 Cc: 72695@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi Alan, Apologies for the delay. Alan Mackenzie writes: > And here's what I'm hoping will be the final version of the patch to fix > this bug. Again, could you try it out (on real code as well as test > code), and let me know how well it works. It should apply cleanly to the > Emacs master branch. Thanks! I've tested on my real-life code now and it worked as intended. Thank you again! Have a lovely evening. =2D-=20 Arsen Arsenovi=C4=87 --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iOYEARYKAI4WIQT+4rPRE/wAoxYtYGFSwpQwHqLEkwUCZvRsNF8UgAAAAAAuAChp c3N1ZXItZnByQG5vdGF0aW9ucy5vcGVucGdwLmZpZnRoaG9yc2VtYW4ubmV0RkVF MkIzRDExM0ZDMDBBMzE2MkQ2MDYxNTJDMjk0MzAxRUEyQzQ5MxAcYXJzZW5AYWFy c2VuLm1lAAoJEFLClDAeosSTXpwA+gN7uZl7moC7a4RK+7Z0bgNmn5bm0c6KlUmu NneQVQZjAP9mAGhqzDUSG29WeIMYx5SJN0ESyd/AXX8fTbsPI7BUCg== =h0kc -----END PGP SIGNATURE----- --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Thu Sep 26 07:35:05 2024 Received: (at 72695) by debbugs.gnu.org; 26 Sep 2024 11:35:05 +0000 Received: from localhost ([127.0.0.1]:57577 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1stmly-00008s-0l for submit@debbugs.gnu.org; Thu, 26 Sep 2024 07:35:05 -0400 Received: from mail.muc.de ([193.149.48.3]:44200) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1stmlv-00008L-Gw for 72695@debbugs.gnu.org; Thu, 26 Sep 2024 07:35:00 -0400 Received: (qmail 68374 invoked by uid 3782); 26 Sep 2024 13:34:25 +0200 Received: from muc.de (pd953abcb.dip0.t-ipconnect.de [217.83.171.203]) (using STARTTLS) by colin.muc.de (tmda-ofmipd) with ESMTP; Thu, 26 Sep 2024 13:34:24 +0200 Received: (qmail 6684 invoked by uid 1000); 26 Sep 2024 11:34:24 -0000 Date: Thu, 26 Sep 2024 11:34:24 +0000 To: Arsen =?utf-8?Q?Arsenovi=C4=87?= Subject: Re: bug#72695: CC Mode 5.35.2 (C++//l); c++-mode misindents 'if constexpr' inside lambdas Message-ID: References: <86wmk9vcd9.fsf@aarsen.me> <875xrhtsuu.fsf@aarsen.me> <86y14cfan1.fsf@aarsen.me> <86a5ggsa5h.fsf@aarsen.me> <86h6a8by5n.fsf@aarsen.me> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <86h6a8by5n.fsf@aarsen.me> X-Submission-Agent: TMDA/1.3.x (Ph3nix) From: Alan Mackenzie X-Primary-Address: acm@muc.de X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 72695 Cc: acm@muc.de, 72695@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hello, Arsen. On Sat, Sep 21, 2024 at 21:32:36 +0200, Arsen Arsenović wrote: > Hi Alan, > Alan Mackenzie writes: > > On Tue, Sep 10, 2024 at 01:02:50 +0200, Arsen Arsenović wrote: > >> Alan Mackenzie writes: [ .... ] > > Thanks, I've now found the place in the C++ syntax where alignas can go > > in a lambda construct. It is the only specifier which may go in these > > places, although any number of attributes are allowed. (As a matter of > > interest, attributes in CC Mode are treated as syntactic whitespace.) > > [ .... ] > >> >> void > >> >> def () > >> >> { > >> >> auto foo = [&, > >> >> a, > >> >> b = 123, > >> >> c, > >> >> ...d, > >> >> ...e = 123 > >> >> ] > >> >> >> >> typename S> > >> >> //alignas (128) > >> >> [[gnu::noreturn]] > >> >> requires some_concept > >> >> (int a, > >> >> int b, > >> >> int c) > >> >> consteval > >> >> constexpr > >> >> mutable > >> >> static > >> >> //noexcept(true) > >> >> [[gnu::packed]] > >> >> //alignas (128) > >> >> //-> > >> >> //int > >> >> //requires (std::same_as ) > >> >> { > >> >> if constexpr (true) > >> >> ; > >> >> } > >> >> } > > Question: Is that first (commented out) alignas correct where it is? My > > reading of the version of the standard suggests that the alignas (128) > > should come _after_ the requires some_concept, not before it. Sorry to keep going on about this, but .... > I think so, through the 2nd lambda-expression derivation: I'm interpreting this as being the answer to "Is that first .... alignas correct?", not a comment on my second sentence "My reading of ...., not before it.". If I'm mistaken there, then my next paragraph is without effect, and I apologise. > lambda-introducer < template-parameter-list > requires-clause_opt > attribute-specifier-seq_opt lambda-declarator compound-statement > ... where attribute-specifier-seq is: > attribute-specifier-seq_opt attribute-specifier > ... and attribute-specifier is also possibly alignment-specifier. > Maybe I am missing something, though? ..... My reading of that lambda-expression derivation is that the "alignas (128)" is the atribute-specifier-seq_opt, and the "requires some_concept" is the requires-clause_opt. Surely the first of these, the "alignas" needs to come after the second, the "requires"? Phew! [ .... ] > > Even it the patch is good, I'm not quite ready to commit it yet, since I > > need to amend the test suite somewhat. > I will test it at a later time tonight or tomorrow. Sorry for the > delay. I got your other post where you reported on that the tests you did were satisfactory. Thanks for that! I'm hoping to get the patch committed before the weekend. > Thank you once again for your efforts! > Have a lovely evening! > -- > Arsen Arsenović -- Alan Mackenzie (Nuremberg, Germany). From debbugs-submit-bounces@debbugs.gnu.org Thu Sep 26 16:15:40 2024 Received: (at 72695) by debbugs.gnu.org; 26 Sep 2024 20:15:40 +0000 Received: from localhost ([127.0.0.1]:51904 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1stuto-0002b0-0Q for submit@debbugs.gnu.org; Thu, 26 Sep 2024 16:15:40 -0400 Received: from mout-p-102.mailbox.org ([80.241.56.152]:41488) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1stutl-0002T1-HB for 72695@debbugs.gnu.org; Thu, 26 Sep 2024 16:15:38 -0400 Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:b231:465::102]) (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 mout-p-102.mailbox.org (Postfix) with ESMTPS id 4XF4ZG2Xg6z9s01; Thu, 26 Sep 2024 22:14:30 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aarsen.me; s=MBO0001; t=1727381670; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=NZP/MXa53P6oZbcwMttD9R3CCuV6raXN1x/Iz3Hnizc=; b=DcUzHCu98QbzTwJ9JbOKHDqUCCM1URvqyHhU1vfxvzSfG09/K7H0pZUJc+uCDZempMDJoy kjehoSXAjHfoMeQs3f6Gl3Jr4cKkhHVuUwV1MN5f0fG5szahYzL3OMUr5RhVz7f13f7a/M pGwDlHBpmJO1gu5FUwhLYFmAyIckK0dxALR0DE5tWNbylBn9Ka9mS0naizRywBztetGyP2 IU2bBR5I6r9VAsgKMCRZtUHd7+3MWlJ2ienX1UxrxgR5MWmnWXRV+E0cXNgvBQpLru3k67 ypg3udCfPqFZsEklPc6QvhP02reMH/OLu80Uc+416LKRvIvd6BahCTQpnZWFDg== From: =?utf-8?Q?Arsen_Arsenovi=C4=87?= To: Alan Mackenzie Subject: Re: bug#72695: CC Mode 5.35.2 (C++//l); c++-mode misindents 'if constexpr' inside lambdas In-Reply-To: (Alan Mackenzie's message of "Thu, 26 Sep 2024 11:34:24 +0000") References: <86wmk9vcd9.fsf@aarsen.me> <875xrhtsuu.fsf@aarsen.me> <86y14cfan1.fsf@aarsen.me> <86a5ggsa5h.fsf@aarsen.me> <86h6a8by5n.fsf@aarsen.me> Date: Thu, 26 Sep 2024 22:14:28 +0200 Message-ID: <861q16895n.fsf@aarsen.me> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Rspamd-Queue-Id: 4XF4ZG2Xg6z9s01 X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 72695 Cc: 72695@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi Alan, Alan Mackenzie writes: > Sorry to keep going on about this, but .... > >> I think so, through the 2nd lambda-expression derivation: > > I'm interpreting this as being the answer to "Is that first .... alignas > correct?", not a comment on my second sentence "My reading of ...., not > before it.". If I'm mistaken there, then my next paragraph is without > effect, and I apologise. Ah! Please forgive me, I misread the standard. >> lambda-introducer < template-parameter-list > requires-clause_opt >> attribute-specifier-seq_opt lambda-declarator compound-statement > >> ... where attribute-specifier-seq is: > >> attribute-specifier-seq_opt attribute-specifier > >> ... and attribute-specifier is also possibly alignment-specifier. > >> Maybe I am missing something, though? > > ..... My reading of that lambda-expression derivation is that the "alignas > (128)" is the atribute-specifier-seq_opt, and the "requires > some_concept" is the requires-clause_opt. Surely the first of these, > the "alignas" needs to come after the second, the "requires"? > > Phew! Yes! You're completely right, I accidentally "combined" the two cases of lambda-expression while writing that example. Forgive me. (serves me right for bug-reporting late.. ;-) ) > [ .... ] > >> > Even it the patch is good, I'm not quite ready to commit it yet, since= I >> > need to amend the test suite somewhat. > >> I will test it at a later time tonight or tomorrow. Sorry for the >> delay. > > I got your other post where you reported on that the tests you did were > satisfactory. Thanks for that! > > I'm hoping to get the patch committed before the weekend. Yay! :-) Thank you very much! Have a lovely night. =2D-=20 Arsen Arsenovi=C4=87 --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iOYEARYKAI4WIQT+4rPRE/wAoxYtYGFSwpQwHqLEkwUCZvXApF8UgAAAAAAuAChp c3N1ZXItZnByQG5vdGF0aW9ucy5vcGVucGdwLmZpZnRoaG9yc2VtYW4ubmV0RkVF MkIzRDExM0ZDMDBBMzE2MkQ2MDYxNTJDMjk0MzAxRUEyQzQ5MxAcYXJzZW5AYWFy c2VuLm1lAAoJEFLClDAeosSTvuYBAI3FldSQd8fDGywafMBrXHAzlRa87Rv1WUku T0A/DyenAQDDlgjJBPiKWmnOIj+N8bF0X5RYzVUqLpQspd8ogjyJAQ== =M7St -----END PGP SIGNATURE----- --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Fri Sep 27 10:20:34 2024 Received: (at 72695) by debbugs.gnu.org; 27 Sep 2024 14:20:34 +0000 Received: from localhost ([127.0.0.1]:37632 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1suBph-0007Sh-SF for submit@debbugs.gnu.org; Fri, 27 Sep 2024 10:20:34 -0400 Received: from mail.muc.de ([193.149.48.3]:50370) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1suBpf-0007SC-5q for 72695@debbugs.gnu.org; Fri, 27 Sep 2024 10:20:32 -0400 Received: (qmail 93329 invoked by uid 3782); 27 Sep 2024 16:13:15 +0200 Received: from muc.de (p4fe1578f.dip0.t-ipconnect.de [79.225.87.143]) (using STARTTLS) by colin.muc.de (tmda-ofmipd) with ESMTP; Fri, 27 Sep 2024 16:13:15 +0200 Received: (qmail 13056 invoked by uid 1000); 27 Sep 2024 14:13:14 -0000 Date: Fri, 27 Sep 2024 14:13:14 +0000 To: Arsen =?utf-8?Q?Arsenovi=C4=87?= Subject: Re: bug#72695: CC Mode 5.35.2 (C++//l); c++-mode misindents 'if constexpr' inside lambdas Message-ID: References: <875xrhtsuu.fsf@aarsen.me> <86y14cfan1.fsf@aarsen.me> <86a5ggsa5h.fsf@aarsen.me> <86h6a8by5n.fsf@aarsen.me> <861q16895n.fsf@aarsen.me> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <861q16895n.fsf@aarsen.me> X-Submission-Agent: TMDA/1.3.x (Ph3nix) From: Alan Mackenzie X-Primary-Address: acm@muc.de X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 72695 Cc: acm@muc.de, 72695@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hello, Arsen. On Thu, Sep 26, 2024 at 22:14:28 +0200, Arsen Arsenović wrote: > Hi Alan, [ .... ] > > ..... My reading of that lambda-expression derivation is that the > > "alignas (128)" is the atribute-specifier-seq_opt, and the "requires > > some_concept" is the requires-clause_opt. Surely the first of > > these, the "alignas" needs to come after the second, the "requires"? > > Phew! > Yes! You're completely right, I accidentally "combined" the two cases > of lambda-expression while writing that example. Forgive me. > (serves me right for bug-reporting late.. ;-) ) I'm glad we agree on this point. :-) [ .... ] > > I'm hoping to get the patch committed before the weekend. > Yay! :-) I've now committed a slightly different patch, after noticing and fixing another bug. The bug was that in code like 1 template 2 requires requires (T x) 3 { x + x; } 4 T add(T a, T b) 5 { 6 return a + b; 7 } , L4, a topmost-intro-cont used to be anchored on the previous topmost-intro-cont line, L2, whereas it should be anchored on the topmost-intro, L1. I've now corrected this. I didn't send you yet another patch with request for testing, because I've done that rather a lot of late, and I'm confident about the patch. I haven't yet closed the bug, just in case you wanted to do some final, final testing on the committed version. Please let me know what you feel about that, so that I can finally close this bug. Just as a matter of interest, one or two other bugs reared their heads, but I'm fixing these separately in the next few days. > Thank you very much! Thank you again. > Have a lovely night. > -- > Arsen Arsenović -- Alan Mackenzie (Nuremberg, Germany). From debbugs-submit-bounces@debbugs.gnu.org Fri Sep 27 17:56:11 2024 Received: (at 72695) by debbugs.gnu.org; 27 Sep 2024 21:56:11 +0000 Received: from localhost ([127.0.0.1]:58046 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1suIwd-0005Cd-CR for submit@debbugs.gnu.org; Fri, 27 Sep 2024 17:56:11 -0400 Received: from mout-p-101.mailbox.org ([80.241.56.151]:41690) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1suIwa-0005Bq-GW for 72695@debbugs.gnu.org; Fri, 27 Sep 2024 17:56:09 -0400 Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:b231:465::102]) (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 mout-p-101.mailbox.org (Postfix) with ESMTPS id 4XFkll6tCzz9sqQ; Fri, 27 Sep 2024 23:54:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aarsen.me; s=MBO0001; t=1727474100; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=bCBgUkucPFWQ+L7BEAJCf5LSAimgrF7D03MJjWMp2MM=; b=cqzHdvHayFPUeefcypxi03uAqs85Z4BwzFLA/aVUBquSIAzXffVY8J1i0dt156k6rn5ZIC LAiwijebYyjM3JEG16glK78ECOA5IUqCd4bUqBtLghypamlFpUz5frsv5rPdAegsq4us16 lu42pWoTWv7jBenEoOrEv6p4d0YVGlfClKjOW1b7ZawqNB2TlOFLZA3k+uePSPILYCrSzr vS/s5bbjLNGzaTCro3uIRzOo/Gci/9Gg/Kgq2hCRACQrWLgAlHLV9aQf794GG9VWMuT7+x kMH6xtD/jLbomNmPVi1rLQWcsLgNMyN/vWIFLyHr7psASytiHHaurv2MVryhJA== From: =?utf-8?Q?Arsen_Arsenovi=C4=87?= To: Alan Mackenzie Subject: Re: bug#72695: CC Mode 5.35.2 (C++//l); c++-mode misindents 'if constexpr' inside lambdas In-Reply-To: (Alan Mackenzie's message of "Fri, 27 Sep 2024 14:13:14 +0000") References: <875xrhtsuu.fsf@aarsen.me> <86y14cfan1.fsf@aarsen.me> <86a5ggsa5h.fsf@aarsen.me> <86h6a8by5n.fsf@aarsen.me> <861q16895n.fsf@aarsen.me> Date: Fri, 27 Sep 2024 23:54:57 +0200 Message-ID: <861q14oj7y.fsf@aarsen.me> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Rspamd-Queue-Id: 4XFkll6tCzz9sqQ X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 72695 Cc: 72695@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi Alan, Alan Mackenzie writes: > I've now committed a slightly different patch, after noticing and fixing > another bug. > > The bug was that in code like > > 1 template > 2 requires requires (T x) > 3 { x + x; } > 4 T add(T a, T b) > 5 { > 6 return a + b; > 7 } > > , L4, a topmost-intro-cont used to be anchored on the previous > topmost-intro-cont line, L2, whereas it should be anchored on the > topmost-intro, L1. > > I've now corrected this. Ah! Good catch. > I didn't send you yet another patch with request for testing, because > I've done that rather a lot of late, and I'm confident about the patch. > > I haven't yet closed the bug, just in case you wanted to do some final, > final testing on the committed version. Please let me know what you feel > about that, so that I can finally close this bug. I'm not sure this is a bug but it is something I noticed by accident: (std::visit ([] (const T& data) { })); ... the { is not an inline-open, but an arglist-cont-nonempty (though, to be clear, the body is indented okay; I've elided it from the example above for that reason). Same goes for the (const T& data), which doesn't get indented the same as a 'standalone' lambda, but it does indent the same as one saved into a variable: [] () { }; auto x =3D [] () { }; auto x =3D ([] () { }); I do not know whether this is correct. But thank you again for working on this! Have a lovely day. =2D-=20 Arsen Arsenovi=C4=87 --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iOYEARYKAI4WIQT+4rPRE/wAoxYtYGFSwpQwHqLEkwUCZvcpsV8UgAAAAAAuAChp c3N1ZXItZnByQG5vdGF0aW9ucy5vcGVucGdwLmZpZnRoaG9yc2VtYW4ubmV0RkVF MkIzRDExM0ZDMDBBMzE2MkQ2MDYxNTJDMjk0MzAxRUEyQzQ5MxAcYXJzZW5AYWFy c2VuLm1lAAoJEFLClDAeosSTLAgA/iCwh+CocQvsJSYetGpQWVpIXEBkVc4JuMSZ iIRH5hGAAQDgEqRC+TusGmQZT3u7sX65sds9+ta6rN5RcQquGqvcCw== =2T3W -----END PGP SIGNATURE----- --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Fri Sep 27 18:38:48 2024 Received: (at 72695) by debbugs.gnu.org; 27 Sep 2024 22:38:48 +0000 Received: from localhost ([127.0.0.1]:58125 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1suJbr-0007VC-Lx for submit@debbugs.gnu.org; Fri, 27 Sep 2024 18:38:48 -0400 Received: from mail.muc.de ([193.149.48.3]:41771) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1suJbp-0007Ut-EW for 72695@debbugs.gnu.org; Fri, 27 Sep 2024 18:38:46 -0400 Received: (qmail 68401 invoked by uid 3782); 28 Sep 2024 00:38:08 +0200 Received: from muc.de (p4fe1578f.dip0.t-ipconnect.de [79.225.87.143]) (using STARTTLS) by colin.muc.de (tmda-ofmipd) with ESMTP; Sat, 28 Sep 2024 00:38:08 +0200 Received: (qmail 32035 invoked by uid 1000); 27 Sep 2024 22:38:07 -0000 Date: Fri, 27 Sep 2024 22:38:07 +0000 To: Arsen =?utf-8?Q?Arsenovi=C4=87?= Subject: Re: bug#72695: CC Mode 5.35.2 (C++//l); c++-mode misindents 'if constexpr' inside lambdas Message-ID: References: <86y14cfan1.fsf@aarsen.me> <86a5ggsa5h.fsf@aarsen.me> <86h6a8by5n.fsf@aarsen.me> <861q16895n.fsf@aarsen.me> <861q14oj7y.fsf@aarsen.me> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <861q14oj7y.fsf@aarsen.me> X-Submission-Agent: TMDA/1.3.x (Ph3nix) From: Alan Mackenzie X-Primary-Address: acm@muc.de X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 72695 Cc: acm@muc.de, 72695@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hello, Arsen. On Fri, Sep 27, 2024 at 23:54:57 +0200, Arsen Arsenović wrote: > Hi Alan, > Alan Mackenzie writes: > > I've now committed a slightly different patch, after noticing and fixing > > another bug. > > The bug was that in code like > > 1 template > > 2 requires requires (T x) > > 3 { x + x; } > > 4 T add(T a, T b) > > 5 { > > 6 return a + b; > > 7 } > > , L4, a topmost-intro-cont used to be anchored on the previous > > topmost-intro-cont line, L2, whereas it should be anchored on the > > topmost-intro, L1. > > I've now corrected this. > Ah! Good catch. > > I didn't send you yet another patch with request for testing, because > > I've done that rather a lot of late, and I'm confident about the patch. > > I haven't yet closed the bug, just in case you wanted to do some final, > > final testing on the committed version. Please let me know what you feel > > about that, so that I can finally close this bug. So, can I close bug#72695 now? > I'm not sure this is a bug but it is something I noticed by accident: > (std::visit > ([] > (const T& data) > { > })); > ... the { is not an inline-open, but an arglist-cont-nonempty (though, > to be clear, the body is indented okay; I've elided it from the example > above for that reason). That is a bug, yes, but a different bug. Could I ask you to raise a new Emacs bug report for it, please? I think it will require some effort to solve, since it involves "function type" constructs inside parentheses, which I think was something new to CC Mode with C++20 (but I'm not sure). Rather than just relying on the context of the outer (, c-guess-basic-syntax will have to examine the contents of (...) to get better analysis. > Same goes for the (const T& data), which doesn't get indented the same > as a 'standalone' lambda, but it does indent the same as one saved into > a variable: > [] > () > { > }; > auto x = > [] > () > { > }; > auto x = > ([] > () > { > }); > I do not know whether this is correct. Neither do I, this late at night. ;-) I'll have a look at all these examples tomorrow. > But thank you again for working on this! A pleasure! > Have a lovely day. > -- > Arsen Arsenović -- Alan Mackenzie (Nuremberg, Germany). From debbugs-submit-bounces@debbugs.gnu.org Fri Sep 27 19:26:04 2024 Received: (at 72695) by debbugs.gnu.org; 27 Sep 2024 23:26:05 +0000 Received: from localhost ([127.0.0.1]:58200 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1suKLc-0001hy-Ia for submit@debbugs.gnu.org; Fri, 27 Sep 2024 19:26:04 -0400 Received: from mout-p-102.mailbox.org ([80.241.56.152]:50100) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1suKLa-0001hP-D2 for 72695@debbugs.gnu.org; Fri, 27 Sep 2024 19:26:03 -0400 Received: from smtp202.mailbox.org (smtp202.mailbox.org [10.196.197.202]) (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 mout-p-102.mailbox.org (Postfix) with ESMTPS id 4XFmlV5lWRz9scX; Sat, 28 Sep 2024 01:24:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aarsen.me; s=MBO0001; t=1727479494; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=O+ogFenHmaA/f+qdK5SbXalAjgYV4axZQaH6q0ft+PE=; b=B+Rl0nN8ZwdfCcM0ZBTdmEO6r+niTwysTfCxmSSQ2cujfwFSzR/8iPib1/0SXzaM3ubfsj VvpfFLsLZZSo7WTH0Xcy6MK35xWGQaLHyewhiy8a9FBprJcLf2JReAi/9qZbiDF/UjJ+bj ppLuEONY92fcg3GAGnVxNr5oxtk7HTk/dBDbAl1v3bhQq2penDBIRsZZjHDoRbVP5Bh4fl IzDkCoX/uH8SNTdXWaLGF987bg4g5ug9yWj9LJBh0NIao9UkLKEyrp9W5pPtrQhkA4TVXn 9rPnnj8SkPoj03kejr8lGiDhffl4N2vXrlcJ8tLFsoHi/OufX8PXwNpOjSZVaw== From: =?utf-8?Q?Arsen_Arsenovi=C4=87?= To: Alan Mackenzie Subject: Re: bug#72695: CC Mode 5.35.2 (C++//l); c++-mode misindents 'if constexpr' inside lambdas In-Reply-To: (Alan Mackenzie's message of "Fri, 27 Sep 2024 22:38:07 +0000") References: <86y14cfan1.fsf@aarsen.me> <86a5ggsa5h.fsf@aarsen.me> <86h6a8by5n.fsf@aarsen.me> <861q16895n.fsf@aarsen.me> <861q14oj7y.fsf@aarsen.me> Date: Sat, 28 Sep 2024 01:24:52 +0200 Message-ID: <864j60n0hn.fsf@aarsen.me> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 72695 Cc: 72695@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi Alan, Alan Mackenzie writes: > So, can I close bug#72695 now? Ah, excuse me. Yes, I do believe so. >> I'm not sure this is a bug but it is something I noticed by accident: > >> (std::visit >> ([] >> (const T& data) >> { >> })); > >> ... the { is not an inline-open, but an arglist-cont-nonempty (though, >> to be clear, the body is indented okay; I've elided it from the example >> above for that reason). > > That is a bug, yes, but a different bug. Could I ask you to raise a new > Emacs bug report for it, please? I can do so tomorrow - getting drowsy at this point. > I think it will require some effort to solve, since it involves "function > type" constructs inside parentheses, which I think was something new to > CC Mode with C++20 (but I'm not sure). Rather than just relying on the > context of the outer (, c-guess-basic-syntax will have to examine the > contents of (...) to get better analysis. Hmm, I think this was here in 11 also (and perhaps before, due to the GNU statement expression extension). >> Same goes for the (const T& data), which doesn't get indented the same >> as a 'standalone' lambda, but it does indent the same as one saved into >> a variable: > >> [] >> () >> { >> }; >> auto x =3D >> [] >> () >> { >> }; >> auto x =3D >> ([] >> () >> { >> }); > >> I do not know whether this is correct. > > Neither do I, this late at night. ;-) I'll have a look at all these > examples tomorrow. :-) Thanks. I will file a bug with these tomorrow. Have a lovely evening! =2D-=20 Arsen Arsenovi=C4=87 --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iOYEARYKAI4WIQT+4rPRE/wAoxYtYGFSwpQwHqLEkwUCZvc+xF8UgAAAAAAuAChp c3N1ZXItZnByQG5vdGF0aW9ucy5vcGVucGdwLmZpZnRoaG9yc2VtYW4ubmV0RkVF MkIzRDExM0ZDMDBBMzE2MkQ2MDYxNTJDMjk0MzAxRUEyQzQ5MxAcYXJzZW5AYWFy c2VuLm1lAAoJEFLClDAeosST/u4A/2lr6kBsQ4u/nSdSE2l9SrhQU9eWcWFS6ilL eKzCMac6AQDTROf1OoY/6MHfR5K0z1ih7RZvo/dIcx0FS0mt8+irAQ== =BmwT -----END PGP SIGNATURE----- --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Sat Sep 28 06:44:35 2024 Received: (at 72695-done) by debbugs.gnu.org; 28 Sep 2024 10:44:35 +0000 Received: from localhost ([127.0.0.1]:51972 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1suUwF-0003gY-Ch for submit@debbugs.gnu.org; Sat, 28 Sep 2024 06:44:35 -0400 Received: from mail.muc.de ([193.149.48.3]:12821) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1suUwD-0003gI-9z for 72695-done@debbugs.gnu.org; Sat, 28 Sep 2024 06:44:33 -0400 Received: (qmail 1731 invoked by uid 3782); 28 Sep 2024 12:43:56 +0200 Received: from muc.de (pd953a689.dip0.t-ipconnect.de [217.83.166.137]) (using STARTTLS) by colin.muc.de (tmda-ofmipd) with ESMTP; Sat, 28 Sep 2024 12:43:56 +0200 Received: (qmail 5293 invoked by uid 1000); 28 Sep 2024 10:43:55 -0000 Date: Sat, 28 Sep 2024 10:43:55 +0000 To: Arsen =?utf-8?Q?Arsenovi=C4=87?= Subject: Re: bug#72695: CC Mode 5.35.2 (C++//l); c++-mode misindents 'if constexpr' inside lambdas Message-ID: References: <8634n2qhw7.fsf@aarsen.me> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <8634n2qhw7.fsf@aarsen.me> X-Submission-Agent: TMDA/1.3.x (Ph3nix) From: Alan Mackenzie X-Primary-Address: acm@muc.de X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 72695-done Cc: acm@muc.de, 72695-done@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Bug#72695 has been fixed. Closing. -- Alan Mackenzie (Nuremberg, Germany). From unknown Sat Aug 16 16:07:59 2025 Received: (at fakecontrol) by fakecontrolmessage; To: internal_control@debbugs.gnu.org From: Debbugs Internal Request Subject: Internal Control Message-Id: bug archived. Date: Sat, 26 Oct 2024 11:24:15 +0000 User-Agent: Fakemail v42.6.9 # This is a fake control message. # # The action: # bug archived. thanks # This fakemail brought to you by your local debbugs # administrator