Skip to content

Fix: Limit scope of macro redefinitions in _ctype.h #366

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

rkarahan80
Copy link

@rkarahan80 rkarahan80 commented Jun 12, 2025

The macros static and __inline were being redefined to empty when _EXTERNALIZE_CTYPE_INLINES_ was defined. However, these redefinitions were not scoped, leading to potential conflicts with other headers or your code that relies on the standard behavior of these keywords.

This change ensures that static and __inline are undefined (using #undef) immediately after the block of code where their redefinition is necessary for generating externalized function prototypes. This restores their standard keyword meaning for any subsequent code, preventing unintended side-effects and improving standards compliance.

A targeted verification was created to confirm that the macros are correctly undefined and that standard static and __inline usage is unaffected after the modified block.

Summary by Sourcery

Ensure that static and __inline macros in _ctype.h are strictly scoped and undefined after use to prevent keyword conflicts; replace direct imports of internal type headers with <sys/types.h> and guarded compiler-based typedefs for __rune_t, __size_t, __off_t, and __va_list; update stddef.h to leverage compiler intrinsic type macros; remove __pure attributes from internal ctype function declarations; swap <sys/_endian.h> for <endian.h>; and add targeted tests to verify macro cleanup and standard keyword behavior.

Bug Fixes:

  • Scope and undefine static and __inline redefinitions in _ctype.h to restore their standard meanings.

Enhancements:

  • Replace <sys/_types.h> and <sys/_null.h> with <sys/types.h> and introduce guarded typedefs for internal types (__rune_t, __size_t, __off_t, __va_list).
  • Update stddef.h to use compiler intrinsic type macros (__PTRDIFF_TYPE__, __SIZE_TYPE__, __WCHAR_TYPE__).
  • Remove __pure attributes from internal ___runetype, ___tolower, and ___toupper declarations.
  • Change endian header include from <sys/_endian.h> to <endian.h>.

Tests:

  • Add macro_verification_test.c and verification_test.c to confirm macro undefinition behavior and ensure normal static/__inline and ctype.h functionality.

The macros `static` and `__inline` were being redefined to empty
when `_EXTERNALIZE_CTYPE_INLINES_` was defined. However, these
redefinitions were not scoped, leading to potential conflicts with
other headers or your code that relies on the standard behavior of
these keywords.

This change ensures that `static` and `__inline` are undefined
(using `#undef`) immediately after the block of code where their
redefinition is necessary for generating externalized function
prototypes. This restores their standard keyword meaning for any
subsequent code, preventing unintended side-effects and improving
standards compliance.

A targeted verification was created to confirm that the macros
are correctly undefined and that standard `static` and `__inline`
usage is unaffected after the modified block.
@rkarahan80 rkarahan80 requested review from a team as code owners June 12, 2025 09:42
@ghostbsd-bot
Copy link

Can one of the admins verify this patch?

Copy link

sourcery-ai bot commented Jun 12, 2025

Reviewer's Guide

This PR refines the scoping of macro redefinitions in _ctype.h by undefining static and __inline post-inline block, standardizes header includes and type definitions across key headers, updates the endian.h inclusion, and adds targeted verification tests to ensure no regressions.

File-Level Changes

Change Details Files
Refactor _ctype.h for scoped macro definitions and prototype cleanup
  • Replaced <sys/_types.h> with <sys/types.h> and included <runetype.h>
  • Removed __pure from external function prototypes
  • Added #undef static and #undef __inline immediately after the externalization block
include/_ctype.h
Standardize header includes and type definitions across stddef.h, runetype.h, and stdio.h
  • Replaced <sys/_types.h> and <sys/_null.h> with <sys/types.h> in multiple headers
  • Added include guards and fallback typedefs for __rune_t and __size_t in runetype.h
  • Updated ptrdiff_t, size_t, and wchar_t typedefs in stddef.h to use PTRDIFF_TYPE, SIZE_TYPE, and WCHAR_TYPE
  • Defined __off_t and __va_list fallbacks in stdio.h
include/stddef.h
include/runetype.h
include/stdio.h
Update endian.h to include the correct header
  • Changed include from <sys/_endian.h> to <endian.h>
include/endian.h
Add verification tests for macro scoping and keyword behavior
  • Introduced macro_verification_test.c to validate scoped macro redefinitions
  • Introduced verification_test.c to ensure standard static and __inline usage post-block
macro_verification_test.c
verification_test.c

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

The macros `static` and `__inline` were being redefined to empty
when `_EXTERNALIZE_CTYPE_INLINES_` was defined. However, these
redefinitions were not scoped, leading to potential conflicts with
other headers or your code that relies on the standard behavior of
these keywords.

This change ensures that `static` and `__inline` are undefined
(using `#undef`) immediately after the block of code where their
redefinition is necessary for generating externalized function
prototypes. This restores their standard keyword meaning for any
subsequent code, preventing unintended side-effects and improving
standards compliance.

A targeted verification was created to confirm that the macros
are correctly undefined and that standard `static` and `__inline`
usage is unaffected after the modified block.
@rkarahan80
Copy link
Author

rkarahan80 commented Jun 12, 2025 via email

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @rkarahan80 - I've reviewed your changes - here's some feedback:

  • Rather than manually #undef-ing static and __inline, consider using #pragma push_macro/pop_macro to scope and restore the original definitions in a more robust, maintainable way.
  • The fallback typedefs for __rune_t and __size_t may not match platform ABI types—consider pulling these from existing system headers or adding static assertions to ensure they’re consistent with the real definitions.
  • Your custom include-guard macros (__RUNE_T_DEFINED_IN_RUNETYPE_H, etc.) could collide with other headers—align them with the platform’s naming convention or namespace them more uniquely to avoid accidental redefinition.
Here's what I looked at during the review
  • 🟡 General issues: 2 issues found
  • 🟢 Security: all looks good
  • 🟡 Testing: 1 issue found
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.


/* Define __ct_rune_t based on __rune_t, which should be defined via stddef.h->sys/types.h */
/* stddef.h is included via sys/types.h which is included from ctype.h/_ctype.h */
#if __BSD_VISIBLE /* Matches guard in stddef.h for rune_t */
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Guard feature macro with defined() check

Use '#if defined(__BSD_VISIBLE) && __BSD_VISIBLE' to avoid preprocessor errors if __BSD_VISIBLE is not defined.

Suggested change
#if __BSD_VISIBLE /* Matches guard in stddef.h for rune_t */
#if defined(__BSD_VISIBLE) && __BSD_VISIBLE /* Matches guard in stddef.h for rune_t */

Comment on lines 41 to 44
#ifndef _PTRDIFF_T_DECLARED
typedef __ptrdiff_t ptrdiff_t;
typedef __PTRDIFF_TYPE__ ptrdiff_t;
#define _PTRDIFF_T_DECLARED
#endif
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Using PTRDIFF_TYPE is compiler-specific

Add a guard or fallback for compilers that do not support PTRDIFF_TYPE, such as using __ptrdiff_t as an alternative.

Suggested change
#ifndef _PTRDIFF_T_DECLARED
typedef __ptrdiff_t ptrdiff_t;
typedef __PTRDIFF_TYPE__ ptrdiff_t;
#define _PTRDIFF_T_DECLARED
#endif
#ifndef _PTRDIFF_T_DECLARED
#if defined(__PTRDIFF_TYPE__)
typedef __PTRDIFF_TYPE__ ptrdiff_t;
#else
typedef __ptrdiff_t ptrdiff_t;
#endif
#define _PTRDIFF_T_DECLARED
#endif

Comment on lines +52 to +53
// rA3 (my_inline_func_A) and rB1 (normal_inline_func_B) are harder to test for "inlineness"
// without inspecting assembly, but compilation success is key.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (testing): Assert return values for my_inline_func_A and normal_inline_func_B.

Please add assertions for rA3 and rB1 to verify their return values, as is done for rA1 and rA2. This will help ensure the functions return the expected results.

@rkarahan80
Copy link
Author

rkarahan80 commented Jun 12, 2025 via email

@xcrsz
Copy link

xcrsz commented Jun 12, 2025

I understand your changes, but this should be done upstream on FreeBSD's FreeBSD-src.

@rkarahan80
Copy link
Author

rkarahan80 commented Jun 12, 2025 via email

@rkarahan80 rkarahan80 closed this by deleting the head repository Jun 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: In Review
Development

Successfully merging this pull request may close these issues.

3 participants