Skip to content

Conversation

@YexuanXiao
Copy link
Contributor

@YexuanXiao YexuanXiao commented Aug 29, 2025

Previously, I made the sizeof expression return the __size_t type instead of unsigned int/long/long long (#143653). However, the types of the predefined macros __SIZE_TYPE__ and __PTRDIFF_TYPE__ obtained from TargetInfo are still unsigned int/long/long long. This causes the common sugar type for evaluating size_t(0) and sizeof(0) to be unsigned int/long/long long instead of __size_t when using glibc/llvm-libc/libc++ because both glibc and clang use typedef __SIZE_TYPE__ size_t;.

clangd-screenshot

Tests for macros can be replaced with _Static_assert(__builtin_types_compatible_p(__SIZE_TYPE__, standard integer type), "");. Clang supports it in any mode but I'm not sure how to add it in a proper way.

@llvmbot llvmbot added clang Clang issues not falling into any other category backend:MIPS labels Aug 29, 2025
@llvmbot
Copy link
Member

llvmbot commented Aug 29, 2025

@llvm/pr-subscribers-clang-static-analyzer-1
@llvm/pr-subscribers-backend-mips

@llvm/pr-subscribers-clang

Author: None (YexuanXiao)

Changes

Previously, I made the sizeof expression return the __size_t type instead of unsigned int/long/long long (#143653). However, the types of the predefined macros __SIZE_TYPE__ and __PTRDIFF_TYPE__ obtained from TargetInfo are still unsigned int/long/long long. This causes the common sugar type for evaluating size_t(0) and sizeof(0) to be unsigned int/long/long long instead of __size_t when using glibc/llvm-libc/libc++.


Patch is 50.04 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/155979.diff

15 Files Affected:

  • (modified) clang/lib/Frontend/InitPreprocessor.cpp (+6-4)
  • (modified) clang/test/Preprocessor/init-aarch64.c (+7-7)
  • (modified) clang/test/Preprocessor/init-arm.c (+16-16)
  • (modified) clang/test/Preprocessor/init-csky.c (+2-2)
  • (modified) clang/test/Preprocessor/init-loongarch.c (+4-4)
  • (modified) clang/test/Preprocessor/init-mips.c (+12-12)
  • (modified) clang/test/Preprocessor/init-ppc.c (+8-8)
  • (modified) clang/test/Preprocessor/init-ppc64.c (+8-8)
  • (modified) clang/test/Preprocessor/init-s390x.c (+2-2)
  • (modified) clang/test/Preprocessor/init-v7k-compat.c (+2-2)
  • (modified) clang/test/Preprocessor/init-ve.c (+2-2)
  • (modified) clang/test/Preprocessor/init-x86.c (+18-18)
  • (modified) clang/test/Preprocessor/init.c (+46-46)
  • (modified) clang/test/Preprocessor/woa-defaults.c (+2-2)
  • (modified) clang/test/Sema/warn-bad-function-cast.c (+5-2)
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 4865c0b889044..5183afe6618b9 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -1175,13 +1175,15 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
   Builder.defineMacro("__UINTMAX_C_SUFFIX__", ConstSuffix);
   Builder.defineMacro("__UINTMAX_C(c)",
                       ConstSuffix.size() ? Twine("c##") + ConstSuffix : "c");
-  DefineType("__PTRDIFF_TYPE__", TI.getPtrDiffType(LangAS::Default), Builder);
-  DefineFmt(LangOpts, "__PTRDIFF", TI.getPtrDiffType(LangAS::Default), TI,
-            Builder);
   DefineType("__INTPTR_TYPE__", TI.getIntPtrType(), Builder);
   DefineFmt(LangOpts, "__INTPTR", TI.getIntPtrType(), TI, Builder);
-  DefineType("__SIZE_TYPE__", TI.getSizeType(), Builder);
+  // Use deduction to obtain the built-in __size_t and __ptrdiff_t types instead
+  // of standard integer types
+  Builder.defineMacro("__SIZE_TYPE__", "__typeof(sizeof(0))");
   DefineFmt(LangOpts, "__SIZE", TI.getSizeType(), TI, Builder);
+  Builder.defineMacro("__PTRDIFF_TYPE__", "__typeof((int*)0-(int*)0)");
+  DefineFmt(LangOpts, "__PTRDIFF", TI.getPtrDiffType(LangAS::Default), TI,
+            Builder);
   DefineType("__WCHAR_TYPE__", TI.getWCharType(), Builder);
   DefineType("__WINT_TYPE__", TI.getWIntType(), Builder);
   DefineTypeSizeAndWidth("__SIG_ATOMIC", TI.getSigAtomicType(), TI, Builder);
diff --git a/clang/test/Preprocessor/init-aarch64.c b/clang/test/Preprocessor/init-aarch64.c
index 3036b496db25d..91e1e502e5256 100644
--- a/clang/test/Preprocessor/init-aarch64.c
+++ b/clang/test/Preprocessor/init-aarch64.c
@@ -255,7 +255,7 @@
 // AARCH64-NEXT: #define __PTRDIFF_FMTd__ "ld"
 // AARCH64-NEXT: #define __PTRDIFF_FMTi__ "li"
 // AARCH64-NEXT: #define __PTRDIFF_MAX__ 9223372036854775807L
-// AARCH64-NEXT: #define __PTRDIFF_TYPE__ long int
+// AARCH64-NEXT: #define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // AARCH64-NEXT: #define __PTRDIFF_WIDTH__ 64
 // AARCH64-NEXT: #define __SCHAR_MAX__ 127
 // AARCH64-NEXT: #define __SHRT_MAX__ 32767
@@ -280,7 +280,7 @@
 // AARCH64-NEXT: #define __SIZE_FMTu__ "lu"
 // AARCH64-NEXT: #define __SIZE_FMTx__ "lx"
 // AARCH64-NEXT: #define __SIZE_MAX__ 18446744073709551615UL
-// AARCH64-NEXT: #define __SIZE_TYPE__ long unsigned int
+// AARCH64-NEXT: #define __SIZE_TYPE__ __typeof(sizeof(0))
 // AARCH64-NEXT: #define __SIZE_WIDTH__ 64
 // AARCH64_CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL
 // AARCH64_CXX: #define __STDCPP_THREADS__ 1
@@ -531,7 +531,7 @@
 // AARCH64-DARWIN: #define __LONG_MAX__ 9223372036854775807L
 // AARCH64-DARWIN: #define __LP64__ 1
 // AARCH64-DARWIN: #define __POINTER_WIDTH__ 64
-// AARCH64-DARWIN: #define __PTRDIFF_TYPE__ long int
+// AARCH64-DARWIN: #define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // AARCH64-DARWIN: #define __PTRDIFF_WIDTH__ 64
 // AARCH64-DARWIN: #define __SCHAR_MAX__ 127
 // AARCH64-DARWIN: #define __SHRT_MAX__ 32767
@@ -551,7 +551,7 @@
 // AARCH64-DARWIN: #define __SIZEOF_WCHAR_T__ 4
 // AARCH64-DARWIN: #define __SIZEOF_WINT_T__ 4
 // AARCH64-DARWIN: #define __SIZE_MAX__ 18446744073709551615UL
-// AARCH64-DARWIN: #define __SIZE_TYPE__ long unsigned int
+// AARCH64-DARWIN: #define __SIZE_TYPE__ __typeof(sizeof(0))
 // AARCH64-DARWIN: #define __SIZE_WIDTH__ 64
 // AARCH64-DARWIN: #define __UINT16_C(c) c
 // AARCH64-DARWIN: #define __UINT16_C_SUFFIX__
@@ -716,7 +716,7 @@
 // AARCH64-MSVC: #define __SIZEOF_WCHAR_T__ 2
 // AARCH64-MSVC: #define __SIZEOF_WINT_T__ 2
 // AARCH64-MSVC: #define __SIZE_MAX__ 18446744073709551615ULL
-// AARCH64-MSVC: #define __SIZE_TYPE__ long long unsigned int
+// AARCH64-MSVC: #define __SIZE_TYPE__ __typeof(sizeof(0))
 // AARCH64-MSVC: #define __SIZE_WIDTH__ 64
 // AARCH64-MSVC: #define __STDC_HOSTED__ 0
 // AARCH64-MSVC: #define __STDC_UTF_16__ 1
@@ -1010,7 +1010,7 @@
 // ARM64EC-MSVC: #define __PTRDIFF_FMTd__ "lld"
 // ARM64EC-MSVC: #define __PTRDIFF_FMTi__ "lli"
 // ARM64EC-MSVC: #define __PTRDIFF_MAX__ 9223372036854775807LL
-// ARM64EC-MSVC: #define __PTRDIFF_TYPE__ long long int
+// ARM64EC-MSVC: #define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // ARM64EC-MSVC: #define __PTRDIFF_WIDTH__ 64
 // ARM64EC-MSVC: #define __SCHAR_MAX__ 127
 // ARM64EC-MSVC: #define __SHRT_MAX__ 32767
@@ -1035,7 +1035,7 @@
 // ARM64EC-MSVC: #define __SIZE_FMTu__ "llu"
 // ARM64EC-MSVC: #define __SIZE_FMTx__ "llx"
 // ARM64EC-MSVC: #define __SIZE_MAX__ 18446744073709551615ULL
-// ARM64EC-MSVC: #define __SIZE_TYPE__ long long unsigned int
+// ARM64EC-MSVC: #define __SIZE_TYPE__ __typeof(sizeof(0))
 // ARM64EC-MSVC: #define __SIZE_WIDTH__ 64
 // ARM64EC-MSVC: #define __STDC_HOSTED__ 0
 // ARM64EC-MSVC: #define __STDC_NO_THREADS__ 1
diff --git a/clang/test/Preprocessor/init-arm.c b/clang/test/Preprocessor/init-arm.c
index d2fcfe94bcd3d..50b199a38cbb0 100644
--- a/clang/test/Preprocessor/init-arm.c
+++ b/clang/test/Preprocessor/init-arm.c
@@ -133,7 +133,7 @@
 // ARM:#define __LONG_MAX__ 2147483647L
 // ARM-NOT:#define __LP64__
 // ARM:#define __POINTER_WIDTH__ 32
-// ARM:#define __PTRDIFF_TYPE__ int
+// ARM:#define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // ARM:#define __PTRDIFF_WIDTH__ 32
 // ARM:#define __REGISTER_PREFIX__
 // ARM:#define __SCHAR_MAX__ 127
@@ -153,7 +153,7 @@
 // ARM:#define __SIZEOF_WCHAR_T__ 4
 // ARM:#define __SIZEOF_WINT_T__ 4
 // ARM:#define __SIZE_MAX__ 4294967295U
-// ARM:#define __SIZE_TYPE__ unsigned int
+// ARM:#define __SIZE_TYPE__ __typeof(sizeof(0))
 // ARM:#define __SIZE_WIDTH__ 32
 // ARM-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 8U
 // ARM:#define __UINT16_C(c) c
@@ -213,8 +213,8 @@
 
 // RUN: %clang_cc1 -dM -ffreestanding -triple arm-none-none -target-abi apcs-gnu -E /dev/null -o - | FileCheck -match-full-lines -check-prefix ARM-APCS-GNU %s
 // ARM-APCS-GNU: #define __INTPTR_TYPE__ int
-// ARM-APCS-GNU: #define __PTRDIFF_TYPE__ int
-// ARM-APCS-GNU: #define __SIZE_TYPE__ unsigned int
+// ARM-APCS-GNU: #define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
+// ARM-APCS-GNU: #define __SIZE_TYPE__ __typeof(sizeof(0))
 
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=armeb-none-none < /dev/null | FileCheck -match-full-lines -check-prefix ARM-BE %s
 //
@@ -344,7 +344,7 @@
 // ARM-BE:#define __LONG_MAX__ 2147483647L
 // ARM-BE-NOT:#define __LP64__
 // ARM-BE:#define __POINTER_WIDTH__ 32
-// ARM-BE:#define __PTRDIFF_TYPE__ int
+// ARM-BE:#define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // ARM-BE:#define __PTRDIFF_WIDTH__ 32
 // ARM-BE:#define __REGISTER_PREFIX__
 // ARM-BE:#define __SCHAR_MAX__ 127
@@ -364,7 +364,7 @@
 // ARM-BE:#define __SIZEOF_WCHAR_T__ 4
 // ARM-BE:#define __SIZEOF_WINT_T__ 4
 // ARM-BE:#define __SIZE_MAX__ 4294967295U
-// ARM-BE:#define __SIZE_TYPE__ unsigned int
+// ARM-BE:#define __SIZE_TYPE__ __typeof(sizeof(0))
 // ARM-BE:#define __SIZE_WIDTH__ 32
 // ARM-BE:#define __UINT16_C(c) c
 // ARM-BE:#define __UINT16_C_SUFFIX__
@@ -547,7 +547,7 @@
 // ARMEABISOFT:#define __LONG_MAX__ 2147483647L
 // ARMEABISOFT-NOT:#define __LP64__
 // ARMEABISOFT:#define __POINTER_WIDTH__ 32
-// ARMEABISOFT:#define __PTRDIFF_TYPE__ int
+// ARMEABISOFT:#define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // ARMEABISOFT:#define __PTRDIFF_WIDTH__ 32
 // ARMEABISOFT:#define __REGISTER_PREFIX__
 // ARMEABISOFT:#define __SCHAR_MAX__ 127
@@ -567,7 +567,7 @@
 // ARMEABISOFT:#define __SIZEOF_WCHAR_T__ 4
 // ARMEABISOFT:#define __SIZEOF_WINT_T__ 4
 // ARMEABISOFT:#define __SIZE_MAX__ 4294967295U
-// ARMEABISOFT:#define __SIZE_TYPE__ unsigned int
+// ARMEABISOFT:#define __SIZE_TYPE__ __typeof(sizeof(0))
 // ARMEABISOFT:#define __SIZE_WIDTH__ 32
 // ARMEABISOFT:#define __SOFTFP__ 1
 // ARMEABISOFT:#define __UINT16_C(c) c
@@ -757,7 +757,7 @@
 // ARMEABISOFTFP_NOFP:#define __LONG_MAX__ 2147483647L
 // ARMEABISOFTFP_NOFP-NOT:#define __LP64__
 // ARMEABISOFTFP_NOFP:#define __POINTER_WIDTH__ 32
-// ARMEABISOFTFP_NOFP:#define __PTRDIFF_TYPE__ int
+// ARMEABISOFTFP_NOFP:#define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // ARMEABISOFTFP_NOFP:#define __PTRDIFF_WIDTH__ 32
 // ARMEABISOFTFP_NOFP:#define __REGISTER_PREFIX__
 // ARMEABISOFTFP_NOFP:#define __SCHAR_MAX__ 127
@@ -777,7 +777,7 @@
 // ARMEABISOFTFP_NOFP:#define __SIZEOF_WCHAR_T__ 4
 // ARMEABISOFTFP_NOFP:#define __SIZEOF_WINT_T__ 4
 // ARMEABISOFTFP_NOFP:#define __SIZE_MAX__ 4294967295U
-// ARMEABISOFTFP_NOFP:#define __SIZE_TYPE__ unsigned int
+// ARMEABISOFTFP_NOFP:#define __SIZE_TYPE__ __typeof(sizeof(0))
 // ARMEABISOFTFP_NOFP:#define __SIZE_WIDTH__ 32
 // ARMEABISOFTFP_NOFP:#define __SOFTFP__ 1
 // ARMEABISOFTFP_NOFP:#define __UINT16_C(c) c
@@ -961,7 +961,7 @@
 // ARMEABISOFTFP_FP:#define __LONG_MAX__ 2147483647L
 // ARMEABISOFTFP_FP-NOT:#define __LP64__
 // ARMEABISOFTFP_FP:#define __POINTER_WIDTH__ 32
-// ARMEABISOFTFP_FP:#define __PTRDIFF_TYPE__ int
+// ARMEABISOFTFP_FP:#define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // ARMEABISOFTFP_FP:#define __PTRDIFF_WIDTH__ 32
 // ARMEABISOFTFP_FP:#define __REGISTER_PREFIX__
 // ARMEABISOFTFP_FP:#define __SCHAR_MAX__ 127
@@ -981,7 +981,7 @@
 // ARMEABISOFTFP_FP:#define __SIZEOF_WCHAR_T__ 4
 // ARMEABISOFTFP_FP:#define __SIZEOF_WINT_T__ 4
 // ARMEABISOFTFP_FP:#define __SIZE_MAX__ 4294967295U
-// ARMEABISOFTFP_FP:#define __SIZE_TYPE__ unsigned int
+// ARMEABISOFTFP_FP:#define __SIZE_TYPE__ __typeof(sizeof(0))
 // ARMEABISOFTFP_FP:#define __SIZE_WIDTH__ 32
 // ARMEABISOFTFP_FP-NOT:#define __SOFTFP__ 1
 // ARMEABISOFTFP_FP:#define __UINT16_C(c) c
@@ -1165,7 +1165,7 @@
 // ARMEABIHARDFP:#define __LONG_MAX__ 2147483647L
 // ARMEABIHARDFP-NOT:#define __LP64__
 // ARMEABIHARDFP:#define __POINTER_WIDTH__ 32
-// ARMEABIHARDFP:#define __PTRDIFF_TYPE__ int
+// ARMEABIHARDFP:#define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // ARMEABIHARDFP:#define __PTRDIFF_WIDTH__ 32
 // ARMEABIHARDFP:#define __REGISTER_PREFIX__
 // ARMEABIHARDFP:#define __SCHAR_MAX__ 127
@@ -1185,7 +1185,7 @@
 // ARMEABIHARDFP:#define __SIZEOF_WCHAR_T__ 4
 // ARMEABIHARDFP:#define __SIZEOF_WINT_T__ 4
 // ARMEABIHARDFP:#define __SIZE_MAX__ 4294967295U
-// ARMEABIHARDFP:#define __SIZE_TYPE__ unsigned int
+// ARMEABIHARDFP:#define __SIZE_TYPE__ __typeof(sizeof(0))
 // ARMEABIHARDFP:#define __SIZE_WIDTH__ 32
 // ARMEABIHARDFP-NOT:#define __SOFTFP__ 1
 // ARMEABIHARDFP:#define __UINT16_C(c) c
@@ -1367,7 +1367,7 @@
 // ARM-NETBSD:#define __LONG_MAX__ 2147483647L
 // ARM-NETBSD-NOT:#define __LP64__
 // ARM-NETBSD:#define __POINTER_WIDTH__ 32
-// ARM-NETBSD:#define __PTRDIFF_TYPE__ long int
+// ARM-NETBSD:#define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // ARM-NETBSD:#define __PTRDIFF_WIDTH__ 32
 // ARM-NETBSD:#define __REGISTER_PREFIX__
 // ARM-NETBSD:#define __SCHAR_MAX__ 127
@@ -1387,7 +1387,7 @@
 // ARM-NETBSD:#define __SIZEOF_WCHAR_T__ 4
 // ARM-NETBSD:#define __SIZEOF_WINT_T__ 4
 // ARM-NETBSD:#define __SIZE_MAX__ 4294967295UL
-// ARM-NETBSD:#define __SIZE_TYPE__ long unsigned int
+// ARM-NETBSD:#define __SIZE_TYPE__ __typeof(sizeof(0))
 // ARM-NETBSD:#define __SIZE_WIDTH__ 32
 // ARM-NETBSD:#define __SOFTFP__ 1
 // ARM-NETBSD:#define __UINT16_C(c) c
diff --git a/clang/test/Preprocessor/init-csky.c b/clang/test/Preprocessor/init-csky.c
index 99c5ad1010edb..da0b11e055d1e 100644
--- a/clang/test/Preprocessor/init-csky.c
+++ b/clang/test/Preprocessor/init-csky.c
@@ -130,7 +130,7 @@
 // CSKY: #define __POINTER_WIDTH__ 32
 // CSKY: #define __PRAGMA_REDEFINE_EXTNAME 1
 // CSKY: #define __PTRDIFF_MAX__ 2147483647
-// CSKY: #define __PTRDIFF_TYPE__ int
+// CSKY: #define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // CSKY: #define __PTRDIFF_WIDTH__ 32
 // CSKY: #define __SCHAR_MAX__ 127
 // CSKY: #define __SHRT_MAX__ 32767
@@ -150,7 +150,7 @@
 // CSKY: #define __SIZEOF_WCHAR_T__ 4
 // CSKY: #define __SIZEOF_WINT_T__ 4
 // CSKY: #define __SIZE_MAX__ 4294967295U
-// CSKY: #define __SIZE_TYPE__ unsigned int
+// CSKY: #define __SIZE_TYPE__ __typeof(sizeof(0))
 // CSKY: #define __SIZE_WIDTH__ 32
 // CSKY: #define __STDC_HOSTED__ 0
 // CSKY: #define __STDC_UTF_16__ 1
diff --git a/clang/test/Preprocessor/init-loongarch.c b/clang/test/Preprocessor/init-loongarch.c
index 71a266b8a9157..9907a99166371 100644
--- a/clang/test/Preprocessor/init-loongarch.c
+++ b/clang/test/Preprocessor/init-loongarch.c
@@ -200,7 +200,7 @@
 // LA32: #define __PTRDIFF_FMTd__ "d"
 // LA32: #define __PTRDIFF_FMTi__ "i"
 // LA32: #define __PTRDIFF_MAX__ 2147483647
-// LA32: #define __PTRDIFF_TYPE__ int
+// LA32: #define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // LA32: #define __PTRDIFF_WIDTH__ 32
 // LA32: #define __SCHAR_MAX__ 127
 // LA32: #define __SHRT_MAX__ 32767
@@ -225,7 +225,7 @@
 // LA32: #define __SIZE_FMTu__ "u"
 // LA32: #define __SIZE_FMTx__ "x"
 // LA32: #define __SIZE_MAX__ 4294967295U
-// LA32: #define __SIZE_TYPE__ unsigned int
+// LA32: #define __SIZE_TYPE__ __typeof(sizeof(0))
 // LA32: #define __SIZE_WIDTH__ 32
 // LA32: #define __STDC_HOSTED__ 0
 // LA32: #define __STDC_UTF_16__ 1
@@ -532,7 +532,7 @@
 // LA64: #define __PTRDIFF_FMTd__ "ld"
 // LA64: #define __PTRDIFF_FMTi__ "li"
 // LA64: #define __PTRDIFF_MAX__ 9223372036854775807L
-// LA64: #define __PTRDIFF_TYPE__ long int
+// LA64: #define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // LA64: #define __PTRDIFF_WIDTH__ 64
 // LA64: #define __SCHAR_MAX__ 127
 // LA64: #define __SHRT_MAX__ 32767
@@ -557,7 +557,7 @@
 // LA64: #define __SIZE_FMTu__ "lu"
 // LA64: #define __SIZE_FMTx__ "lx"
 // LA64: #define __SIZE_MAX__ 18446744073709551615UL
-// LA64: #define __SIZE_TYPE__ long unsigned int
+// LA64: #define __SIZE_TYPE__ __typeof(sizeof(0))
 // LA64: #define __SIZE_WIDTH__ 64
 // LA64: #define __STDC_HOSTED__ 0
 // LA64: #define __STDC_UTF_16__ 1
diff --git a/clang/test/Preprocessor/init-mips.c b/clang/test/Preprocessor/init-mips.c
index 125872a001bac..46b25f07852f2 100644
--- a/clang/test/Preprocessor/init-mips.c
+++ b/clang/test/Preprocessor/init-mips.c
@@ -138,7 +138,7 @@
 // MIPS32BE:#define __MIPSEB__ 1
 // MIPS32BE:#define __POINTER_WIDTH__ 32
 // MIPS32BE:#define __PRAGMA_REDEFINE_EXTNAME 1
-// MIPS32BE:#define __PTRDIFF_TYPE__ int
+// MIPS32BE:#define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // MIPS32BE:#define __PTRDIFF_WIDTH__ 32
 // MIPS32BE:#define __REGISTER_PREFIX__
 // MIPS32BE:#define __SCHAR_MAX__ 127
@@ -158,7 +158,7 @@
 // MIPS32BE:#define __SIZEOF_WCHAR_T__ 4
 // MIPS32BE:#define __SIZEOF_WINT_T__ 4
 // MIPS32BE:#define __SIZE_MAX__ 4294967295U
-// MIPS32BE:#define __SIZE_TYPE__ unsigned int
+// MIPS32BE:#define __SIZE_TYPE__ __typeof(sizeof(0))
 // MIPS32BE:#define __SIZE_WIDTH__ 32
 // MIPS32BE-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 8U
 // MIPS32BE:#define __STDC_HOSTED__ 0
@@ -359,7 +359,7 @@
 // MIPS32EL:#define __MIPSEL__ 1
 // MIPS32EL:#define __POINTER_WIDTH__ 32
 // MIPS32EL:#define __PRAGMA_REDEFINE_EXTNAME 1
-// MIPS32EL:#define __PTRDIFF_TYPE__ int
+// MIPS32EL:#define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // MIPS32EL:#define __PTRDIFF_WIDTH__ 32
 // MIPS32EL:#define __REGISTER_PREFIX__
 // MIPS32EL:#define __SCHAR_MAX__ 127
@@ -379,7 +379,7 @@
 // MIPS32EL:#define __SIZEOF_WCHAR_T__ 4
 // MIPS32EL:#define __SIZEOF_WINT_T__ 4
 // MIPS32EL:#define __SIZE_MAX__ 4294967295U
-// MIPS32EL:#define __SIZE_TYPE__ unsigned int
+// MIPS32EL:#define __SIZE_TYPE__ __typeof(sizeof(0))
 // MIPS32EL:#define __SIZE_WIDTH__ 32
 // MIPS32EL:#define __UINT16_C(c) c
 // MIPS32EL:#define __UINT16_C_SUFFIX__
@@ -611,7 +611,7 @@
 // MIPSN32BE: #define __PTRDIFF_FMTd__ "d"
 // MIPSN32BE: #define __PTRDIFF_FMTi__ "i"
 // MIPSN32BE: #define __PTRDIFF_MAX__ 2147483647
-// MIPSN32BE: #define __PTRDIFF_TYPE__ int
+// MIPSN32BE: #define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // MIPSN32BE: #define __PTRDIFF_WIDTH__ 32
 // MIPSN32BE: #define __REGISTER_PREFIX__
 // MIPSN32BE: #define __SCHAR_MAX__ 127
@@ -635,7 +635,7 @@
 // MIPSN32BE: #define __SIZE_FMTu__ "u"
 // MIPSN32BE: #define __SIZE_FMTx__ "x"
 // MIPSN32BE: #define __SIZE_MAX__ 4294967295U
-// MIPSN32BE: #define __SIZE_TYPE__ unsigned int
+// MIPSN32BE: #define __SIZE_TYPE__ __typeof(sizeof(0))
 // MIPSN32BE: #define __SIZE_WIDTH__ 32
 // MIPSN32BE-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16U
 // MIPSN32BE: #define __STDC_HOSTED__ 0
@@ -929,7 +929,7 @@
 // MIPSN32EL: #define __PTRDIFF_FMTd__ "d"
 // MIPSN32EL: #define __PTRDIFF_FMTi__ "i"
 // MIPSN32EL: #define __PTRDIFF_MAX__ 2147483647
-// MIPSN32EL: #define __PTRDIFF_TYPE__ int
+// MIPSN32EL: #define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // MIPSN32EL: #define __PTRDIFF_WIDTH__ 32
 // MIPSN32EL: #define __REGISTER_PREFIX__
 // MIPSN32EL: #define __SCHAR_MAX__ 127
@@ -953,7 +953,7 @@
 // MIPSN32EL: #define __SIZE_FMTu__ "u"
 // MIPSN32EL: #define __SIZE_FMTx__ "x"
 // MIPSN32EL: #define __SIZE_MAX__ 4294967295U
-// MIPSN32EL: #define __SIZE_TYPE__ unsigned int
+// MIPSN32EL: #define __SIZE_TYPE__ __typeof(sizeof(0))
 // MIPSN32EL: #define __SIZE_WIDTH__ 32
 // MIPSN32EL: #define __STDC_HOSTED__ 0
 // MIPSN32EL: #define __STDC_UTF_16__ 1
@@ -1215,7 +1215,7 @@
 // MIPS64BE:#define __MIPSEB__ 1
 // MIPS64BE:#define __POINTER_WIDTH__ 64
 // MIPS64BE:#define __PRAGMA_REDEFINE_EXTNAME 1
-// MIPS64BE:#define __PTRDIFF_TYPE__ long int
+// MIPS64BE:#define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // MIPS64BE:#define __PTRDIFF_WIDTH__ 64
 // MIPS64BE:#define __REGISTER_PREFIX__
 // MIPS64BE:#define __SCHAR_MAX__ 127
@@ -1236,7 +1236,7 @@
 // MIPS64BE:#define __SIZEOF_WCHAR_T__ 4
 // MIPS64BE:#define __SIZEOF_WINT_T__ 4
 // MIPS64BE:#define __SIZE_MAX__ 18446744073709551615UL
-// MIPS64BE:#define __SIZE_TYPE__ long unsigned int
+// MIPS64BE:#define __SIZE_TYPE__ __typeof(sizeof(0))
 // MIPS64BE:#define __SIZE_WIDTH__ 64
 // MIPS64BE-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL
 // MIPS64BE:#define __UINT16_C(c) c
@@ -1436,7 +1436,7 @@
 // MIPS64EL:#define __MIPSEL__ 1
 // MIPS64EL:#define __POINTER_WIDTH__ 64
 // MIPS64EL:#define __PRAGMA_REDEFINE_EXTNAME 1
-// MIPS64EL:#define __PTRDIFF_TYPE__ long int
+// MIPS64EL:#define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // MIPS64EL:#define __PTRDIFF_WIDTH__ 64
 // MIPS64EL:#define __REGISTER_PREFIX__
 // MIPS64EL:#define __SCHAR_MAX__ 127
@@ -1457,7 +1457,7 @@
 // MIPS64EL:#define __SIZEOF_WCHAR_T__ 4
 // MIPS64EL:#define __SIZEOF_WINT_T__ 4
 // MIPS64EL:#define __SIZE_MAX__ 18446744073709551615UL
-// MIPS64EL:#define __SIZE_TYPE__ long unsigned int
+// MIPS64EL:#define __SIZE_TYPE__ __typeof(sizeof(0))
 // MIPS64EL:#define __SIZE_WIDTH__ 64
 // MIPS64EL:#define __UINT16_C(c) c
 // MIPS64EL:#define __UINT16_C_SUFFIX__
diff --git a/clang/test/Preprocessor/init-ppc.c b/clang/test/Preprocessor/init-ppc.c
index 6b7eceda9b97b..2f73133cf6bd9 100644
--- a/clang/test/Preprocessor/init-ppc.c
+++ b/clang/test/Preprocessor/init-ppc.c
@@ -132,7 +132,7 @@
 // PPC603E:#define __POINTER_WIDTH__ 32
 // PPC603E:#define __POWERPC__ 1
 // PPC603E:#define __PPC__ 1
-// PPC603E:#define __PTRDIFF_TYPE__ long int
+// PPC603E:#define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // PPC603E:#define __PTRDIFF_WIDTH__ 32
 // PPC603E:#define __REGISTER_PREFIX__
 // PPC603E:#define __SCHAR_MAX__ 127
@@ -152,7 +152,7 @@
 // PPC603E:#define __SIZEOF_WCHAR_T__ 4
 // PPC603E:#define __SIZEOF_WINT_T__ 4
 // PPC603E:#define __SIZE_MAX__ 4294967295UL
-// PPC603E:#define __SIZE_TYPE__ long unsigned int
+// PPC603E:#define __SIZE_TYPE__ __typeof(sizeof(0))
 // PPC603E:#define __SIZE_WIDTH__ 32
 // PPC603E-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL
 // PPC603E:#define __UINT16_C(c) c
@@ -337,7 +337,7 @@
 // PPC:#define __POWERPC__ 1
 // PPC-NOT:#define __PPC 1
 // PPC:#define __PPC__ 1
-// PPC:#define __PTRDIFF_TYPE__ long int
+// PPC:#define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // PPC:#define __PTRDIFF_WIDTH__ 32
 // PPC:#define __REGISTER_PREFIX__
 // PPC:#define __SCHAR_MAX__ 127
@@ -357,7 +357,7 @@
 // PPC:#define __SIZEOF_WCHAR_T__ 4
 // PPC:#define __SIZEOF_WINT_T__ 4
 // PPC:#define __SIZE_MAX__ 4294967295UL
-// PPC:#define __SIZE_TYPE__ long unsigned int
+// PPC:#define __SIZE_TYPE__ __typeof(sizeof(0))
 // PPC:#define __SIZE_WIDTH__ 32
 // PPC:#define __UINT16_C(c) c
 // PPC:#define __UINT16_C_SUFFIX__
@@ -546,7 +546,7 @@
 // PPC-AIX:#define __POWERPC__ 1
 // PPC-AIX:#define __PPC 1
 // PPC-AIX:#define __PPC__ 1
-// PPC-AIX:#define __PTRDIFF_TYPE__ long int
+// PPC-AIX:#define __PTRDIFF_TYPE__ __typeof((int*)0-(int*)0)
 // PPC-AIX:#define __PTRDIFF_WIDTH__ 32
 // PPC-AIX:#define __REGISTER_PREFIX__
 // PPC-AIX:#define __SCHAR_MAX__ 127
@@ -566,7 +566,...
[truncated]

@jrtc27
Copy link
Collaborator

jrtc27 commented Aug 29, 2025

If you want __size_t you should just set it to __size_t. I don't see what the point of this approach is other than risking causing issues due to it not just being a plain specifier qualifier list.

@zwuis zwuis requested a review from mizvekov August 29, 2025 06:14
@YexuanXiao
Copy link
Contributor Author

If you want __size_t you should just set it to __size_t. I don't see what the point of this approach is other than risking causing issues due to it not just being a plain specifier qualifier list.

Because __size_t is not a keyword, it cannot be directly accessed through user code.

@jrtc27
Copy link
Collaborator

jrtc27 commented Aug 29, 2025

If you want __size_t you should just set it to __size_t. I don't see what the point of this approach is other than risking causing issues due to it not just being a plain specifier qualifier list.

Because __size_t is not a keyword, it cannot be directly accessed through user code.

So we're making __SIZE_TYPE__ be some magic type that you cannot name, only procure out of thin air through using sizeof? That doesn't seem like a good idea to me.

@YexuanXiao
Copy link
Contributor Author

YexuanXiao commented Aug 29, 2025

So we're making __SIZE_TYPE__ be some magic type that you cannot name, only procure out of thin air through using sizeof? That doesn't seem like a good idea to me.

Within standard scope, it generally does not pose any risks unless X-macros are used. I have actually suggested a similar change to MSVC and MSVC STL microsoft/STL#5699, although they do not provide __SIZE_TYPE__.

Actually, the impact of this patch is very minimal. It easily passed the vast majority of tests, and aside from one, all the failed tests were related to text comparison.

__size_t has been in Clang for over a month and has worked very well. This change makes size_t and __size_t behave more consistent.

@YexuanXiao
Copy link
Contributor Author

YexuanXiao commented Aug 29, 2025

@Szelethus @Xazax-hun Could you help me investigate why the test std-c-library-functions-arg-constraints.c is failed? It was introduced by https://reviews.llvm.org/D77148, and I don't understand why this change would cause a shift in static analysis behavior. All other tests in check-clang have passed. The error log is as follows:

2025-08-29T06:07:58.7461382Z /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang -cc1 -internal-isystem /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/clang/22/include -nostdsysteminc -analyze -setup-static-analyzer /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/Analysis/std-c-library-functions-arg-constraints.c -analyzer-checker=core -analyzer-checker=unix.StdCLibraryFunctions -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true -analyzer-checker=debug.StdCLibraryFunctionsTester -analyzer-checker=debug.ExprInspection -triple x86_64-unknown-linux-gnu -verify=report # RUN: at line 2
2025-08-29T06:07:58.7469149Z + /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang -cc1 -internal-isystem /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/clang/22/include -nostdsysteminc -analyze -setup-static-analyzer /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/Analysis/std-c-library-functions-arg-constraints.c -analyzer-checker=core -analyzer-checker=unix.StdCLibraryFunctions -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true -analyzer-checker=debug.StdCLibraryFunctionsTester -analyzer-checker=debug.ExprInspection -triple x86_64-unknown-linux-gnu -verify=report
2025-08-29T06:07:58.7473402Z error: 'report-warning' diagnostics seen but not expected:
2025-08-29T06:07:58.7474819Z File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/Analysis/std-c-library-functions-arg-constraints.c Line 326: FALSE [debug.ExprInspection]
2025-08-29T06:07:58.7476744Z File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/Analysis/std-c-library-functions-arg-constraints.c Line 334: FALSE [debug.ExprInspection]
2025-08-29T06:07:58.7478319Z 2 errors generated.

int __buf_size_arg_constraint_mul(const void *, size_t, size_t);
void test_buf_size_concrete_with_multiplication(void) {
short buf[3]; // bugpath-note{{'buf' initialized here}}
__buf_size_arg_constraint_mul(buf, 4, sizeof(short)); // \
// report-warning{{The 1st argument to '__buf_size_arg_constraint_mul' is a buffer with size 6 but should be a buffer with size equal to or greater than the value of the 2nd argument (which is 4) times the 3rd argument (which is 2)}} \
// bugpath-warning{{The 1st argument to '__buf_size_arg_constraint_mul' is a buffer with size 6 but should be a buffer with size equal to or greater than the value of the 2nd argument (which is 4) times the 3rd argument (which is 2)}} \
// bugpath-note{{The 1st argument to '__buf_size_arg_constraint_mul' is a buffer with size 6 but should be a buffer with size equal to or greater than the value of the 2nd argument (which is 4) times the 3rd argument (which is 2)}}
}
void test_buf_size_symbolic_with_multiplication(size_t s) {
short buf[3];
__buf_size_arg_constraint_mul(buf, s, sizeof(short));
clang_analyzer_eval(s * sizeof(short) <= 6); // \
// report-warning{{TRUE}} \
// bugpath-warning{{TRUE}} \
// bugpath-note{{TRUE}}
}
void test_buf_size_symbolic_and_offset_with_multiplication(size_t s) {
short buf[3];
__buf_size_arg_constraint_mul(buf + 1, s, sizeof(short));
clang_analyzer_eval(s * sizeof(short) <= 4); // \
// report-warning{{TRUE}} \
// bugpath-warning{{TRUE}} \
// bugpath-note{{TRUE}}
}

@YexuanXiao
Copy link
Contributor Author

CC @ldionne

@mizvekov
Copy link
Contributor

You could include your opening snippet as a test case within the patch. Or even a simple AST dump test case showing these types contain __size_t et al as bottom-level sugar.

@YexuanXiao
Copy link
Contributor Author

You could include your opening snippet as a test case within the patch. Or even a simple AST dump test case showing these types contain __size_t et al as bottom-level sugar.

Which file is appropriate to add it to? Or should I create a new file?

@mizvekov
Copy link
Contributor

Which file is appropriate to add it to? Or should I create a new file?

For common-type concerns, you can add it to Sema/sugar-common-types.c for C code, or clang/test/SemaCXX/sugar-common-types.cpp for C++.

For AST dumps, I don't see a great fit anywhere, so if you created a new one that would be ok.

@YexuanXiao YexuanXiao force-pushed the size_t-ptrdiff_t_macro branch 2 times, most recently from 6a6786b to b5390a3 Compare August 30, 2025 12:09
@YexuanXiao
Copy link
Contributor Author

@mizvekov The ast-dump test I added passes locally, but the CI is failing to match the string. How do I resolve this?

@mizvekov
Copy link
Contributor

@mizvekov The ast-dump test I added passes locally, but the CI is failing to match the string. How do I resolve this?

I would guess that kind of problem is due to line ending differences.

But in any case, I was thinking more about doing text-mode ast-dump tests.

If you want to do json only, that's fine as well, but then you could put them in clang/test/AST/ast-dump-types-json.cpp.

I don't think separate C and C++ tests are necessary, due to there not being any language mode differentiation on the implementation.

I would prefer for these tests to not depend on any external includes.

@YexuanXiao YexuanXiao force-pushed the size_t-ptrdiff_t_macro branch from b5390a3 to 085cf65 Compare August 31, 2025 02:57
@YexuanXiao
Copy link
Contributor Author

YexuanXiao commented Aug 31, 2025

ast-dump-types-json.cpp

After moving the test to ast-dump-types-json.cpp, the option -ast-dump-filter removes the extraneous information, and now the CI can pass successfully.

DefineType("__SIZE_TYPE__", TI.getSizeType(), Builder);
// Use deduction to obtain the built-in __size_t and __ptrdiff_t types instead
// of standard integer types
Builder.defineMacro("__SIZE_TYPE__", "__typeof(sizeof(0))");
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't have a good hold on whether this is a good idea or not. We should probably have an RFC for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I enhanced the check for the %zu format specifier in #143653, but some people reported that it generated a lot of false positives. As a result, the check was eventually removed. The reason was that calculating skb->len - sizeof(_arph) loses all the sugar types. If the PR gets accepted, I can add a new option to enable this enhanced check (under the condition that the libc defines size_t in this way).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend:MIPS clang:static analyzer clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants