[v2] analyzer: follow macro aliases for named constant [PR125265]

Message ID bmm.hmv4y5tlcc.gcc.gcc.azoff.226.2.0@forge-stage.sourceware.org
State New
Headers
Series [v2] analyzer: follow macro aliases for named constant [PR125265] |

Commit Message

Torbjörn Svensson via Sourceware Forge Oct. 3, 2026, 10:35 a.m. UTC
  From: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>

Newlib, picolibc, and probably other libc implementations, use

  #define O_CREAT  _FCREAT
  #define O_TRUNC  _FTRUNC
  #define O_EXCL   _FEXCL

In r17-177-g9a5f89005dc49d, support was added to identify redundant
flags, but the implementation requires that the value of the macros
O_CREAT, O_EXCL, O_RDWR to be a number.  This patch extends the support
to also allow macro aliases.  The maximum followed levels is by default
8 levels, but can be tuned via --param=analyzer-max-macro-alias-depth=n.

This change fixes

FAIL: gcc.dg/analyzer/mkostemp-1.c  (test for warnings, line 109)
FAIL: gcc.dg/analyzer/mkostemp-1.c  (test for warnings, line 115)
FAIL: gcc.dg/analyzer/mkostemps-1.c  (test for warnings, line 115)
FAIL: gcc.dg/analyzer/mkostemps-1.c  (test for warnings, line 121)

Regtested with arm-none-eabi (with newlib) on r17-3738-gaaa0f6b1e87bc6.

gcc/ChangeLog:

	PR analyzer/125265
	* params.opt: Define --param=analyzer-max-macro-alias-depth=.

gcc/c/ChangeLog:

	PR analyzer/125265
	* c-parser.cc: Follow macro alias to get the value for a named
	constant.

Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
---
Ok for trunk?

I'm unsure if this should also go into releases/gcc-16, WDYT?

--



This is a forge pull request published on the gcc-patches mailing list mailing list
as requested by Torbjörn Svensson via Sourceware Forge <forge-bot+azoff@forge-stage.sourceware.org>.
Forge discussion: https://forge.sourceware.org/gcc/gcc/pulls/226

Get it locally using:
```
git fetch forge-upstream "+refs/versioned_pull/226/*:refs/versioned_pull/226/*"
git switch -c "pr-226-v2" "refs/versioned_pull/226/2/head"
```
Or, download the patch at: https://forge.sourceware.org/gcc/gcc/pulls/226.diff
Created on: 2026-08-31 06:26:23+00:00
Latest update: 2026-10-03 10:35:40+00:00
Changes: 2 changed files, 23 additions, 3 deletions
Head revision: azoff/gcc ref pr/macro-aliases commit 8ac305a10b5089b38f36eca1d1bc66132e95545f 
Base revision: gcc/gcc ref trunk commit aaa0f6b1e87bc62ea15da6eab431af6dcebf6414 r17-3738-gaaa0f6b1e87bc6
Merge base: aaa0f6b1e87bc62ea15da6eab431af6dcebf6414
Requested Reviewers: dmalcolm

Changed files:
- M: gcc/c/c-parser.cc
- M: gcc/params.opt

 gcc/c/c-parser.cc | 22 +++++++++++++++++++---
 gcc/params.opt    |  4 ++++
 2 files changed, 23 insertions(+), 3 deletions(-)


Range-diff against v1:
1:  650c07cdb2805 ! 1:  8ac305a10b508 analyzer: follow macro aliases for named constant [PR125265]
    @@ Commit message
         In r17-177-g9a5f89005dc49d, support was added to identify redundant
         flags, but the implementation requires that the value of the macros
         O_CREAT, O_EXCL, O_RDWR to be a number.  This patch extends the support
    -    to also allow macro aliases.  It will follow up to 8 levels of macros in
    -    order to reach the number.
    +    to also allow macro aliases.  The maximum followed levels is by default
    +    8 levels, but can be tuned via --param=analyzer-max-macro-alias-depth=n.
     
         This change fixes
     
    @@ Commit message
     
         Regtested with arm-none-eabi (with newlib) on r17-3738-gaaa0f6b1e87bc6.
     
    +    gcc/ChangeLog:
    +
    +            PR analyzer/125265
    +            * params.opt: Define --param=analyzer-max-macro-alias-depth=.
    +
         gcc/c/ChangeLog:
     
                 PR analyzer/125265
    -            * c-parser.cc: Follow, up to eight, macro alias to get the value
    -            for a named constant.
    +            * c-parser.cc: Follow macro alias to get the value for a named
    +            constant.
     
         Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
     
    @@ gcc/c/c-parser.cc: private:
     +     following the chain of aliases up to MAX_ALIAS_DEPTH deep.  */
     +  tree consider_macro (cpp_macro *macro, unsigned int depth = 0) const
        {
    -+    const unsigned int MAX_ALIAS_DEPTH = 8;
          if (macro->paramc > 0)
            return NULL_TREE;
    -     if (macro->kind != cmk_macro)
     @@ gcc/c/c-parser.cc: private:
          if (macro->count != 1)
            return NULL_TREE;
    @@ gcc/c/c-parser.cc: private:
     +    if (tok.type == CPP_NAME)
     +      {
     +	/* Limit recursion.  */
    -+	if (depth >= MAX_ALIAS_DEPTH)
    ++	if (depth >= param_analyzer_max_macro_alias_depth)
     +	  return NULL_TREE;
     +
     +	cpp_hashnode *alias = tok.val.node.node;
    @@ gcc/c/c-parser.cc: private:
            return NULL_TREE;
      
          cpp_reader *old_parse_in = parse_in;
    +
    + ## gcc/params.opt ##
    +@@ gcc/params.opt: Loops iterating at least selected number of iterations get loop alignment.
    + Common Joined UInteger Var(param_align_threshold) Init(100) IntegerRange(1, 65536) Param Optimization
    + Select fraction of the maximal frequency of executions of basic block in function given basic block get alignment.
    + 
    ++-param=analyzer-max-macro-alias-depth=
    ++Common Joined UInteger Var(param_analyzer_max_macro_alias_depth) Init(8) IntegerRange(0, 255)
    ++Maximum number of macro aliases to follow when resolving named constants in the analyzer; zero disables alias following.
    ++
    + -param=asan-globals=
    + Common Joined UInteger Var(param_asan_globals) Init(1) IntegerRange(0, 1) Param
    + Enable asan globals protection.
  

Comments

David Malcolm via Sourceware Forge Oct. 5, 2026, 11:55 p.m. UTC | #1
David Malcolm (dmalcolm) <dmalcolm@gcc.gnu.org> requested changes to the code:


> +++ gcc/params.opt
> @@ -33,1 +34,4 @@
> +Common Joined UInteger Var(param_analyzer_max_macro_alias_depth) Init(8) IntegerRange(0, 255)
> +Maximum number of macro aliases to follow when resolving named constants in the analyzer; zero disables alias following.
> +
>  -param=asan-globals=
Thanks for adding the param.  Please can you add documentation for it to `gcc/doc/params.texi`.


--
https://forge.sourceware.org/gcc/gcc/pulls/226#issuecomment-7702
  

Patch

diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 9dc5ba1e3a13f..e03c06da9a233 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -2019,8 +2019,11 @@  private:
        #define NAME 42
      and other bases but not negative numbers, parentheses or e.g.
        #define NAME 1 << 7
-     as doing so would require a parser.  */
-  tree consider_macro (cpp_macro *macro) const
+     as doing so would require a parser.
+     Also handle the case where MACRO's definition is a single identifier
+     that is itself a macro name (e.g. "#define O_CREAT _FCREAT"), by
+     following the chain of aliases up to MAX_ALIAS_DEPTH deep.  */
+  tree consider_macro (cpp_macro *macro, unsigned int depth = 0) const
   {
     if (macro->paramc > 0)
       return NULL_TREE;
@@ -2029,7 +2032,20 @@  private:
     if (macro->count != 1)
       return NULL_TREE;
     const cpp_token &tok = macro->exp.tokens[0];
-    if (tok.type != CPP_NUMBER)
+    if (tok.type == CPP_NAME)
+      {
+	/* Limit recursion.  */
+	if (depth >= param_analyzer_max_macro_alias_depth)
+	  return NULL_TREE;
+
+	cpp_hashnode *alias = tok.val.node.node;
+	if (cpp_macro_p (alias))
+	  return consider_macro (alias->value.macro, depth + 1);
+
+	/* Not a simple alias.  */
+	return NULL_TREE;
+      }
+    else if (tok.type != CPP_NUMBER)
       return NULL_TREE;
 
     cpp_reader *old_parse_in = parse_in;
diff --git a/gcc/params.opt b/gcc/params.opt
index 0c6a3e5145749..6e3458ccb955e 100644
--- a/gcc/params.opt
+++ b/gcc/params.opt
@@ -30,6 +30,10 @@  Loops iterating at least selected number of iterations get loop alignment.
 Common Joined UInteger Var(param_align_threshold) Init(100) IntegerRange(1, 65536) Param Optimization
 Select fraction of the maximal frequency of executions of basic block in function given basic block get alignment.
 
+-param=analyzer-max-macro-alias-depth=
+Common Joined UInteger Var(param_analyzer_max_macro_alias_depth) Init(8) IntegerRange(0, 255)
+Maximum number of macro aliases to follow when resolving named constants in the analyzer; zero disables alias following.
+
 -param=asan-globals=
 Common Joined UInteger Var(param_asan_globals) Init(1) IntegerRange(0, 1) Param
 Enable asan globals protection.