1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-03-09 00:11:49 -07:00

CC Mode: Prevent "const" inside an identifier being recognized as the keyword

This fixes bug #45560.

* lisp/progmodes/cc-engine.el (c-forward-declarator)
(c-forward-decl-or-cast-1): Amend certain regexp match numbers on account of
the change below.  Surround some looking-at calls with save-match-data.

* lisp/progmodes/cc-langs.el (c-type-decl-prefix-keywords-key): New lang
const.
(c-type-decl-prefix-key): Reformulate to match operators and keywords
separately, using the new lang const (above).
This commit is contained in:
Alan Mackenzie 2021-02-02 20:34:42 +00:00
parent 04ab3904ed
commit 9a67da98a2
2 changed files with 41 additions and 29 deletions

View file

@ -9021,14 +9021,15 @@ point unchanged and return nil."
(c-forward-noise-clause))
((and (looking-at c-type-decl-prefix-key)
(if (and (c-major-mode-is 'c++-mode)
(match-beginning 3))
(match-beginning 4)) ; Was 3 - 2021-01-01
;; If the third submatch matches in C++ then
;; we're looking at an identifier that's a
;; prefix only if it specifies a member pointer.
(progn
(setq id-start (point))
(c-forward-name)
(if (looking-at "\\(::\\)")
(if (save-match-data
(looking-at "\\(::\\)"))
;; We only check for a trailing "::" and
;; let the "*" that should follow be
;; matched in the next round.
@ -9038,13 +9039,15 @@ point unchanged and return nil."
(setq got-identifier t)
nil))
t))
(if (looking-at c-type-decl-operator-prefix-key)
(if (save-match-data
(looking-at c-type-decl-operator-prefix-key))
(setq decorated t))
(if (eq (char-after) ?\()
(progn
(setq paren-depth (1+ paren-depth))
(forward-char))
(goto-char (match-end 1)))
(goto-char (or (match-end 1)
(match-end 2))))
(c-forward-syntactic-ws)
t)))
@ -9721,14 +9724,15 @@ This function might do hidden buffer changes."
(setq after-paren-pos (point))))
(while (and (looking-at c-type-decl-prefix-key)
(if (and (c-major-mode-is 'c++-mode)
(match-beginning 3))
;; If the third submatch matches in C++ then
(match-beginning 4))
;; If the fourth submatch matches in C++ then
;; we're looking at an identifier that's a
;; prefix only if it specifies a member pointer.
(when (progn (setq pos (point))
(setq got-identifier (c-forward-name)))
(setq name-start pos)
(if (looking-at "\\(::\\)")
(if (save-match-data
(looking-at "\\(::\\)"))
;; We only check for a trailing "::" and
;; let the "*" that should follow be
;; matched in the next round.
@ -9749,7 +9753,8 @@ This function might do hidden buffer changes."
(when (save-match-data
(looking-at c-type-decl-operator-prefix-key))
(setq got-function-name-prefix t))
(goto-char (match-end 1)))
(goto-char (or (match-end 1)
(match-end 2))))
(c-forward-syntactic-ws)))
(setq got-parens (> paren-depth 0))

View file

@ -3433,41 +3433,47 @@ possible for good performance."
t (c-make-bare-char-alt (c-lang-const c-block-prefix-disallowed-chars) t))
(c-lang-defvar c-block-prefix-charset (c-lang-const c-block-prefix-charset))
(c-lang-defconst c-type-decl-prefix-key
"Regexp matching any declarator operator that might precede the
identifier in a declaration, e.g. the \"*\" in \"char *argv\". This
regexp should match \"(\" if parentheses are valid in declarators.
The end of the first submatch is taken as the end of the operator.
Identifier syntax is in effect when this is matched (see
`c-identifier-syntax-table')."
(c-lang-defconst c-type-decl-prefix-keywords-key
;; Regexp matching any keyword operator that might precede the identifier in
;; a declaration, e.g. "const" or nil. It doesn't test there is no "_"
;; following the keyword.
t (if (or (c-lang-const c-type-modifier-kwds) (c-lang-const c-modifier-kwds))
(concat
(concat
(regexp-opt (c--delete-duplicates
(append (c-lang-const c-type-modifier-kwds)
(c-lang-const c-modifier-kwds))
:test 'string-equal)
t)
"\\>")
;; Default to a regexp that never matches.
regexp-unmatchable)
"\\>")))
(c-lang-defconst c-type-decl-prefix-key
"Regexp matching any declarator operator that might precede the
identifier in a declaration, e.g. the \"*\" in \"char *argv\". This
regexp should match \"(\" if parentheses are valid in declarators.
The operator found is either the first submatch (if it is not a
keyword) or the second submatch (if it is)."
t (if (c-lang-const c-type-decl-prefix-keywords-key)
(concat "\\(\\`a\\`\\)\\|" ; 1 - will never match.
(c-lang-const c-type-decl-prefix-keywords-key) ; 2
"\\([^_]\\|$\\)") ; 3
"\\`a\\`") ;; Default to a regexp that never matches.
;; Check that there's no "=" afterwards to avoid matching tokens
;; like "*=".
(c objc) (concat "\\("
(c objc) (concat "\\(" ; 1
"[*(]"
"\\|"
(c-lang-const c-type-decl-prefix-key)
"\\)"
"\\([^=]\\|$\\)")
c++ (concat "\\("
"\\)\\|"
(c-lang-const c-type-decl-prefix-keywords-key) ; 2
"\\([^=_]\\|$\\)") ; 3
c++ (concat "\\(" ; 1
"&&"
"\\|"
"\\.\\.\\."
"\\|"
"[*(&~]"
"\\)\\|\\(" ; 2
(c-lang-const c-type-decl-prefix-keywords-key) ; 3
"\\|"
(c-lang-const c-type-decl-prefix-key)
"\\|"
(concat "\\(" ; 3
(concat "\\(" ; 4
;; If this matches there's special treatment in
;; `c-font-lock-declarators' and
;; `c-font-lock-declarations' that check for a
@ -3475,8 +3481,9 @@ Identifier syntax is in effect when this is matched (see
(c-lang-const c-identifier-start)
"\\)")
"\\)"
"\\([^=]\\|$\\)")
"\\([^=_]\\|$\\)") ; 5
pike "\\(\\*\\)\\([^=]\\|$\\)")
(c-lang-defvar c-type-decl-prefix-key (c-lang-const c-type-decl-prefix-key)
'dont-doc)