bug#28623: 27.0.50; lisp/progmodes/cc-engine.el incorrect indentation of C++14 curly-brace initializer list

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

bug#28623: 27.0.50; lisp/progmodes/cc-engine.el incorrect indentation of C++14 curly-brace initializer list

Tadeus Prastowo
The following C++14 source code, which is also attached as `mwe.cpp',
shows the indentation problem:

--8<------------------------------
#include <vector>
#include <iostream>

static std::vector<std::vector<unsigned>>
fn(std::vector<std::vector<unsigned>> data) {
  return {
          {1, 2, 3},
          {4, 5, 6},
          {7, 8, 9},
  };
}

static std::vector<std::vector<unsigned>>
fn(unsigned n, std::vector<std::vector<unsigned>> data) {
  return {
          {n + 1, n + 2, n + 3},
          {n + 4, n + 5, n + 6},
          {n + 7, n + 8, n + 9},
  };
}

int main() {
  /* Expected indentation */
  fn({
      {1, 2, 3},
      {3, 4, 5},
      {6, 7, 8},
    });
  for (const auto &v : fn({
                           {3, 4, 5},
                           {6, 7, 8},
                           {9, 10, 11},
      })) {
    for (const auto &a : v) {
      std::cout << a << '\n';
    }
  }
  /* End: Expected indentation */

  /* Problem */
  fn(20, {
      {1, 2, 3},
        {3, 4, 5},
          {6, 7, 8},
            });
  for (const auto &v : fn(20, {
        {3, 4, 5},
          {6, 7, 8},
            {9, 10, 11},
              })) {
    for (const auto &a : v) {
      std::cout << a << '\n';
    }
  }
  /* End: Problem */
}
--8<------------------------------

To fix the problem, I make the following patch:
--8<------------------------------
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 05b391a..077e9c9 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -10387,6 +10387,7 @@ comment at the start of cc-engine.el for more info."
               (eq (char-after) ?\())
          (setq braceassignp 'c++-noassign))
         ((looking-at c-pre-id-bracelist-key))
+        ((looking-at ",\\s *"))
         ((looking-at c-return-key))
         ((and (looking-at c-symbol-start)
               (not (looking-at c-keywords-regexp)))
@@ -10398,6 +10399,7 @@ comment at the start of cc-engine.el for more info."
            (and (c-go-up-list-backward nil lim) ; FIXME!!! Check
`lim' 2016-07-12.
             (eq (char-after) ?\()))
           ((looking-at c-pre-id-bracelist-key))
+          ((looking-at ",\\s *"))
           ((looking-at c-return-key))
           (t (setq after-type-id-pos (point))
              nil))))
--8<------------------------------

Any better suggestion as to how to fix the problem?

Thanks.

In GNU Emacs 27.0.50 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.18.9)
 of 2017-09-27 built on lgw01-amd64-052
Windowing system distributor 'The X.Org Foundation', version 11.0.11804000
System Description:    Ubuntu 16.04.3 LTS

Recent messages:
For information about GNU Emacs and the GNU system, type C-h C-a.
Making completion list...
Quit

Configured using:
 'configure --build=x86_64-linux-gnu --prefix=/usr
 '--includedir=${prefix}/include' '--mandir=${prefix}/share/man'
 '--infodir=${prefix}/share/info' --sysconfdir=/etc --localstatedir=/var
 --disable-silent-rules '--libdir=${prefix}/lib/x86_64-linux-gnu'
 '--libexecdir=${prefix}/lib/x86_64-linux-gnu' --disable-maintainer-mode
 --disable-dependency-tracking --prefix=/usr --sharedstatedir=/var/lib
 --program-suffix=-snapshot --with-modules=yes --with-x=yes
 --with-x-toolkit=gtk3 --with-xwidgets=yes 'CFLAGS=-g -O2
 -fstack-protector-strong -Wformat -Werror=format-security'
 'CPPFLAGS=-Wdate-time -D_FORTIFY_SOURCE=2'
 'LDFLAGS=-Wl,-Bsymbolic-functions -Wl,-z,relro''

Configured features:
XPM JPEG TIFF GIF PNG RSVG IMAGEMAGICK SOUND GPM DBUS GSETTINGS NOTIFY
LIBSELINUX GNUTLS LIBXML2 FREETYPE M17N_FLT LIBOTF XFT ZLIB
TOOLKIT_SCROLL_BARS GTK3 X11 MODULES XWIDGETS LIBSYSTEMD LCMS2

Important settings:
  value of $LC_MONETARY: en_US.UTF-8
  value of $LC_NUMERIC: en_US.UTF-8
  value of $LC_TIME: en_US.UTF-8
  value of $LANG: en_US.UTF-8
  value of $XMODIFIERS: @im=ibus
  locale-coding-system: utf-8-unix

Major mode: C++//l

Minor modes in effect:
  tooltip-mode: t
  global-eldoc-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  line-number-mode: t
  transient-mark-mode: t
  abbrev-mode: t

Load-path shadows:
None found.

Features:
(shadow sort mail-extr emacsbug message subr-x puny seq byte-opt gv
bytecomp byte-compile cconv dired dired-loaddefs format-spec rfc822 mml
mml-sec password-cache epa derived epg epg-config gnus-util rmail
rmail-loaddefs mm-decode mm-bodies mm-encode mail-parse rfc2231
mailabbrev gmm-utils mailheader sendmail rfc2047 rfc2045 ietf-drums
mm-util mail-prsvr mail-utils cc-mode cc-fonts easymenu cc-guess
cc-menus cc-cmds cc-styles cc-align cc-engine cc-vars cc-defs
cl-loaddefs cl-lib elec-pair time-date mule-util tooltip eldoc electric
uniquify ediff-hook vc-hooks lisp-float-type mwheel term/x-win x-win
term/common-win x-dnd tool-bar dnd fontset image regexp-opt fringe
tabulated-list replace newcomment text-mode elisp-mode lisp-mode
prog-mode register page menu-bar rfn-eshadow isearch timer select
scroll-bar mouse jit-lock font-lock syntax facemenu font-core
term/tty-colors frame cl-generic cham georgian utf-8-lang misc-lang
vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms cp51932
hebrew greek romanian slovak czech european ethiopic indian cyrillic
chinese composite charscript charprop case-table epa-hook jka-cmpr-hook
help simple abbrev obarray minibuffer cl-preloaded nadvice loaddefs
button faces cus-face macroexp files text-properties overlay sha1 md5
base64 format env code-pages mule custom widget hashtable-print-readable
backquote dbusbind inotify lcms2 dynamic-setting system-font-setting
font-render-setting xwidget-internal move-toolbar gtk x-toolkit x
multi-tty make-network-process emacs)

Memory information:
((conses 16 115959 7786)
 (symbols 48 22648 1)
 (miscs 40 46 140)
 (strings 32 34019 980)
 (string-bytes 1 1013691)
 (vectors 16 17237)
 (vector-slots 8 521799 8627)
 (floats 8 50 155)
 (intervals 56 397 1)
 (buffers 992 13)
 (heap 1024 40263 1174))

--
Best regards,
Tadeus

mwe.cpp (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

bug#28623: 27.0.50; lisp/progmodes/cc-engine.el incorrect indentation of C++14 curly-brace initializer list

John Wiegley
>>>>> "TP" == Tadeus Prastowo <[hidden email]> writes:

PT> The following C++14 source code, which is also attached as `mwe.cpp',
PT> shows the indentation problem:

Pinging Alan for this one.

--
John Wiegley                  GPG fingerprint = 4710 CF98 AF9B 327B B80F
http://newartisans.com                          60E1 46C4 BD1A 7AC1 4BA2



Reply | Threaded
Open this post in threaded view
|

bug#28623: 27.0.50; lisp/progmodes/cc-engine.el incorrect indentation of C++14 curly-brace initializer list

Alan Mackenzie
In reply to this post by Tadeus Prastowo
Hello, Tadeus.

On Wed, Sep 27, 2017 at 19:49:57 +0200, Tadeus Prastowo wrote:
> The following C++14 source code, which is also attached as `mwe.cpp',
> shows the indentation problem:

> --8<------------------------------
> #include <vector>
> #include <iostream>

> static std::vector<std::vector<unsigned>>
> fn(std::vector<std::vector<unsigned>> data) {
>   return {
>           {1, 2, 3},
>           {4, 5, 6},
>           {7, 8, 9},
>   };
> }

> static std::vector<std::vector<unsigned>>
> fn(unsigned n, std::vector<std::vector<unsigned>> data) {
>   return {
>           {n + 1, n + 2, n + 3},
>           {n + 4, n + 5, n + 6},
>           {n + 7, n + 8, n + 9},
>   };
> }

> int main() {
>   /* Expected indentation */
>   fn({
>       {1, 2, 3},
>       {3, 4, 5},
>       {6, 7, 8},
>     });
>   for (const auto &v : fn({
>                            {3, 4, 5},
>                            {6, 7, 8},
>                            {9, 10, 11},
>       })) {
>     for (const auto &a : v) {
>       std::cout << a << '\n';
>     }
>   }
>   /* End: Expected indentation */

>   /* Problem */
>   fn(20, {
>       {1, 2, 3},
>         {3, 4, 5},
>           {6, 7, 8},
>             });
>   for (const auto &v : fn(20, {
>         {3, 4, 5},
>           {6, 7, 8},
>             {9, 10, 11},
>               })) {
>     for (const auto &a : v) {
>       std::cout << a << '\n';
>     }
>   }
>   /* End: Problem */
> }
> --8<------------------------------

Yes.

> To fix the problem, I make the following patch:
> --8<------------------------------
> diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
> index 05b391a..077e9c9 100644
> --- a/lisp/progmodes/cc-engine.el
> +++ b/lisp/progmodes/cc-engine.el
> @@ -10387,6 +10387,7 @@ comment at the start of cc-engine.el for more info."
>                (eq (char-after) ?\())
>           (setq braceassignp 'c++-noassign))
>          ((looking-at c-pre-id-bracelist-key))
> +        ((looking-at ",\\s *"))
>          ((looking-at c-return-key))
>          ((and (looking-at c-symbol-start)
>                (not (looking-at c-keywords-regexp)))
> @@ -10398,6 +10399,7 @@ comment at the start of cc-engine.el for more info."
>             (and (c-go-up-list-backward nil lim) ; FIXME!!! Check
> `lim' 2016-07-12.
>              (eq (char-after) ?\()))
>            ((looking-at c-pre-id-bracelist-key))
> +          ((looking-at ",\\s *"))
>            ((looking-at c-return-key))
>            (t (setq after-type-id-pos (point))
>               nil))))
> --8<------------------------------

> Any better suggestion as to how to fix the problem?

Hey, I just love it when people diagnose and fix their own bugs,
particularly in some of the more involved bits of CC Mode.  :-)

Just one tiny, tiny, nitpick.  in (looking-at ",\\s *"), isn't the "any
amount of space" bit redundant, since we don't use match-end to get the
precise position?  In fact, I'm tending towards the simpler (eq
(char-after) ?,).

But, as I say, that's a tiny point in a great piece of debugging.  I
will commit this (to the Emacs-26 branch of savannah) soon (from where
it will find its way to the master branch due to some public spirited
person who arranges these things).

Many thanks!

> Thanks.

> In GNU Emacs 27.0.50 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.18.9)
>  of 2017-09-27 built on lgw01-amd64-052
> Windowing system distributor 'The X.Org Foundation', version 11.0.11804000
> System Description:    Ubuntu 16.04.3 LTS

[ .... ]

> Major mode: C++//l

[ .... ]

> --
> Best regards,
> Tadeus

--
Alan Mackenzie (Nuremberg, Germany).



Reply | Threaded
Open this post in threaded view
|

bug#28623: 27.0.50; lisp/progmodes/cc-engine.el incorrect indentation of C++14 curly-brace initializer list

Tadeus Prastowo
On Wed, Oct 4, 2017 at 8:15 PM, Alan Mackenzie <[hidden email]> wrote:
> Hello, Tadeus.

Hi Alan!

[...]

>> Any better suggestion as to how to fix the problem?
>
> Hey, I just love it when people diagnose and fix their own bugs,
> particularly in some of the more involved bits of CC Mode.  :-)

To make the maintainer's life easier :-)

> Just one tiny, tiny, nitpick.  in (looking-at ",\\s *"), isn't the "any
> amount of space" bit redundant, since we don't use match-end to get the
> precise position?  In fact, I'm tending towards the simpler (eq
> (char-after) ?,).

That is surely better.  Please go with that solution.

> But, as I say, that's a tiny point in a great piece of debugging.  I
> will commit this (to the Emacs-26 branch of savannah) soon (from where
> it will find its way to the master branch due to some public spirited
> person who arranges these things).

Thank you very much for your review.

> Many thanks!

No problem.  I'm glad to help.

--
Best regards,
Tadeus



Reply | Threaded
Open this post in threaded view
|

bug#28623: 27.0.50; lisp/progmodes/cc-engine.el incorrect indentation of C++14 curly-brace initializer list

Alan Mackenzie
Hello, Tadeus.

On Fri, Oct 06, 2017 at 04:59:55 +0200, Tadeus Prastowo wrote:
> On Wed, Oct 4, 2017 at 8:15 PM, Alan Mackenzie <[hidden email]> wrote:

> Hi Alan!

> [...]

> >> Any better suggestion as to how to fix the problem?

> > Hey, I just love it when people diagnose and fix their own bugs,
> > particularly in some of the more involved bits of CC Mode.  :-)

> To make the maintainer's life easier :-)

> > Just one tiny, tiny, nitpick.  in (looking-at ",\\s *"), isn't the "any
> > amount of space" bit redundant, since we don't use match-end to get the
> > precise position?  In fact, I'm tending towards the simpler (eq
> > (char-after) ?,).

> That is surely better.  Please go with that solution.

> > But, as I say, that's a tiny point in a great piece of debugging.  I
> > will commit this (to the Emacs-26 branch of savannah) soon (from where
> > it will find its way to the master branch due to some public spirited
> > person who arranges these things).

> Thank you very much for your review.

> > Many thanks!

> No problem.  I'm glad to help.

I'm sorry is been a week without any communication from me.  The reason
is I've run into problems with other related cases.  For example, in

1.    auto bad4 = f <3> (
2.                       {3, 4},

L2 needs to be parsed as an arglist-intro and indented as shown.  It's
actually being parsed as a brace-list-open with anchor point on "auto".

What's confusing me is the confusion between a brace list being
recognised by its context (which is what
c-looking-at-or-maybe-in-bracelist mostly does) and by its content.  The
{3, 4} above is a brace list by its content but not by its context.
However, it's being wrongly recognised as a by-context brace list, hence
is being parsed and indented wrongly.

I'm not going to have much time to sort this out over the next week or
two, so please bear with me.  I haven't forgotten about this.

> --
> Best regards,
> Tadeus

--
Alan Mackenzie (Nuremberg, Germany).



Reply | Threaded
Open this post in threaded view
|

bug#28623: 27.0.50; lisp/progmodes/cc-engine.el incorrect indentation of C++14 curly-brace initializer list

Tadeus Prastowo
Hi Alan!

On Wed, Oct 11, 2017 at 10:32 PM, Alan Mackenzie <[hidden email]> wrote:
> Hello, Tadeus.

[...]

> I'm sorry is been a week without any communication from me.  The reason
> is I've run into problems with other related cases.  For example, in
>
> 1.    auto bad4 = f <3> (
> 2.                       {3, 4},
>
> L2 needs to be parsed as an arglist-intro and indented as shown.  It's
> actually being parsed as a brace-list-open with anchor point on "auto".
>
> What's confusing me is the confusion between a brace list being
> recognised by its context (which is what
> c-looking-at-or-maybe-in-bracelist mostly does) and by its content.  The
> {3, 4} above is a brace list by its content but not by its context.
> However, it's being wrongly recognised as a by-context brace list, hence
> is being parsed and indented wrongly.
>
> I'm not going to have much time to sort this out over the next week or
> two, so please bear with me.  I haven't forgotten about this.

Thanks for sharing the problem with me.  I will also look into the
matter during this weekend.  Hopefully I can come up with a good
solution :)

> --
> Alan Mackenzie (Nuremberg, Germany).

--
Best regards,
Tadeus