From: Torbjörn SVENSSON <[email protected]>

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.

        PR analyzer/125265

gcc/ChangeLog:

        * doc/params.texi (analyzer-max-macro-alias-depth): Document.
        * params.opt (-param=analyzer-max-macro-alias-depth=): New.

gcc/c/ChangeLog:

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

gcc/testsuite/ChangeLog:

        * gcc.dg/analyzer/named-constants-via-macros-alias.c: New test.

Signed-off-by: Torbjörn SVENSSON <[email protected]>
---
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 
<[email protected]>.
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-v3" "refs/versioned_pull/226/3/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-06 16:50:51+00:00
Changes: 4 changed files, 42 additions, 3 deletions
Head revision: azoff/gcc ref pr/macro-aliases commit 
f5ef3a0b9d507945c14f74d41fb711dd74f7416a 
Base revision: gcc/gcc ref trunk commit 
aaa0f6b1e87bc62ea15da6eab431af6dcebf6414 r17-3738-gaaa0f6b1e87bc6
Merge base: aaa0f6b1e87bc62ea15da6eab431af6dcebf6414
Requested Reviewers: dmalcolm

Changed files:
- A: gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-alias.c
- M: gcc/c/c-parser.cc
- M: gcc/doc/params.texi
- M: gcc/params.opt

 gcc/c/c-parser.cc                             | 22 ++++++++++++++++---
 gcc/doc/params.texi                           |  5 +++++
 gcc/params.opt                                |  4 ++++
 .../named-constants-via-macros-alias.c        | 14 ++++++++++++
 4 files changed, 42 insertions(+), 3 deletions(-)
 create mode 100644 
gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-alias.c

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/doc/params.texi b/gcc/doc/params.texi
index e69be2d2923e4..ba46391d00c35 100644
--- a/gcc/doc/params.texi
+++ b/gcc/doc/params.texi
@@ -1884,6 +1884,11 @@ the value as unknown.
 The maximum number of infeasible edges to reject before declaring
 a diagnostic as infeasible.
 
+@paindex analyzer-max-macro-alias-depth
+@item analyzer-max-macro-alias-depth
+The maximum number of macro aliases to follow when resolving named constants
+in the analyzer.
+
 @paindex gimple-fe-computed-hot-bb-threshold
 @item gimple-fe-computed-hot-bb-threshold
 The number of executions of a basic block that is considered hot.
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.
diff --git a/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-alias.c 
b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-alias.c
new file mode 100644
index 0000000000000..d74eb12958d94
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-alias.c
@@ -0,0 +1,14 @@
+/* { dg-additional-options "--param=analyzer-max-macro-alias-depth=1" } */
+
+#include "analyzer-decls.h"
+
+#define O_CREAT 42     /* 0 aliases.  */
+#define O_EXCL O_CREAT /* 1 alias.    */
+#define O_RDWR O_EXCL  /* 2 aliases.  */
+
+void test_macro_aliases (void)
+{
+  __analyzer_dump_named_constant ("O_CREAT"); /* { dg-warning "named constant 
'O_CREAT' has value '42'" } */
+  __analyzer_dump_named_constant ("O_EXCL"); /* { dg-warning "named constant 
'O_EXCL' has value '42'" } */
+  __analyzer_dump_named_constant ("O_RDWR"); /* { dg-warning "named constant 
'O_RDWR' has unknown value" } */
+}

Range-diff against v2:
1:  8ac305a10b508 ! 1:  f5ef3a0b9d507 analyzer: follow macro aliases for named 
constant [PR125265]
    @@ Commit message
     
         Regtested with arm-none-eabi (with newlib) on r17-3738-gaaa0f6b1e87bc6.
     
    +            PR analyzer/125265
    +
         gcc/ChangeLog:
     
    -            PR analyzer/125265
    -            * params.opt: Define --param=analyzer-max-macro-alias-depth=.
    +            * doc/params.texi (analyzer-max-macro-alias-depth): Document.
    +            * params.opt (-param=analyzer-max-macro-alias-depth=): New.
     
         gcc/c/ChangeLog:
     
    -            PR analyzer/125265
                 * c-parser.cc: Follow macro alias to get the value for a named
                 constant.
     
    +    gcc/testsuite/ChangeLog:
    +
    +            * gcc.dg/analyzer/named-constants-via-macros-alias.c: New test.
    +
         Signed-off-by: Torbjörn SVENSSON <[email protected]>
     
      ## gcc/c/c-parser.cc ##
    @@ gcc/c/c-parser.cc: private:
      
          cpp_reader *old_parse_in = parse_in;
     
    + ## gcc/doc/params.texi ##
    +@@ gcc/doc/params.texi: the value as unknown.
    + The maximum number of infeasible edges to reject before declaring
    + a diagnostic as infeasible.
    + 
    ++@paindex analyzer-max-macro-alias-depth
    ++@item analyzer-max-macro-alias-depth
    ++The maximum number of macro aliases to follow when resolving named 
constants
    ++in the analyzer.
    ++
    + @paindex gimple-fe-computed-hot-bb-threshold
    + @item gimple-fe-computed-hot-bb-threshold
    + The number of executions of a basic block that is considered hot.
    +
      ## 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
    @@ gcc/params.opt: Loops iterating at least selected number of iterations 
get loop
      -param=asan-globals=
      Common Joined UInteger Var(param_asan_globals) Init(1) IntegerRange(0, 1) 
Param
      Enable asan globals protection.
    +
    + ## gcc/testsuite/gcc.dg/analyzer/named-constants-via-macros-alias.c (new) 
##
    +@@
    ++/* { dg-additional-options "--param=analyzer-max-macro-alias-depth=1" } */
    ++
    ++#include "analyzer-decls.h"
    ++
    ++#define O_CREAT 42        /* 0 aliases.  */
    ++#define O_EXCL O_CREAT    /* 1 alias.    */
    ++#define O_RDWR O_EXCL     /* 2 aliases.  */
    ++
    ++void test_macro_aliases (void)
    ++{
    ++  __analyzer_dump_named_constant ("O_CREAT"); /* { dg-warning "named 
constant 'O_CREAT' has value '42'" } */
    ++  __analyzer_dump_named_constant ("O_EXCL"); /* { dg-warning "named 
constant 'O_EXCL' has value '42'" } */
    ++  __analyzer_dump_named_constant ("O_RDWR"); /* { dg-warning "named 
constant 'O_RDWR' has unknown value" } */
    ++}
-- 
2.54.0

Reply via email to