https://github.com/steakhal created https://github.com/llvm/llvm-project/pull/181858
This was prompted by these upstream discussions: https://github.com/llvm/llvm-project/pull/132404#issuecomment-3816874305 https://discourse.llvm.org/t/what-are-the-precise-semantics-of-the-address-space-attribute/89752/10?u=steakhal This also relates to #181644 rdar://170554765 From 03b7b32efd9541d69340e0aa994bc95e901b2196 Mon Sep 17 00:00:00 2001 From: Balazs Benics <[email protected]> Date: Tue, 17 Feb 2026 17:39:46 +0100 Subject: [PATCH] [analyzer] Move the core.FixedAddressDereference checker to optin.core This was prompted by these upstream discussions: https://github.com/llvm/llvm-project/pull/132404#issuecomment-3816874305 https://discourse.llvm.org/t/what-are-the-precise-semantics-of-the-address-space-attribute/89752/10?u=steakhal This also relates to #181644 rdar://170554765 --- clang/docs/analyzer/checkers.rst | 98 +++++++++---------- .../clang/StaticAnalyzer/Checkers/Checkers.td | 10 +- .../test/Analysis/analyzer-enabled-checkers.c | 1 - clang/test/Analysis/builtin_bitcast.cpp | 2 +- clang/test/Analysis/concrete-address.c | 2 +- clang/test/Analysis/dtor.cpp | 2 +- clang/test/Analysis/fixed-address-notes.c | 2 +- clang/test/Analysis/misc-ps.m | 4 +- clang/test/Analysis/pr22954.c | 2 +- ...c-library-functions-arg-enabled-checkers.c | 1 - ...ress-dereferences-from-any-address-space.c | 8 +- 11 files changed, 65 insertions(+), 67 deletions(-) diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index 7ff55bc9d77a7..e51015655de65 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -139,55 +139,6 @@ core.DivideZero (C, C++, ObjC) .. literalinclude:: checkers/dividezero_example.c :language: c -.. _core-FixedAddressDereference: - -core.FixedAddressDereference (C, C++, ObjC) -""""""""""""""""""""""""""""""""""""""""""" -Check for dereferences of fixed addresses. - -A pointer contains a fixed address if it was set to a hard-coded value or it -becomes otherwise obvious that at that point it can have only a single fixed -numerical value. - -.. code-block:: c - - void test1() { - int *p = (int *)0x020; - int x = p[0]; // warn - } - - void test2(int *p) { - if (p == (int *)-1) - *p = 0; // warn - } - - void test3() { - int (*p_function)(char, char); - p_function = (int (*)(char, char))0x04080; - int x = (*p_function)('x', 'y'); // NO warning yet at functon pointer calls - } - - void volatile_pointee() { - *(volatile int *)0x404 = 1; // no warning: constant non-null "volatile" pointee, you must know what you are doing - } - - void deref_volatile_nullptr() { - *(volatile int *)0 = 1; // core.NullDereference still warns about this - } - -If your project is low-level (e.g., firmware), or deals with hardware interop with a lot of genuine constant addresses, then consider disabling this checker. -The checker automatically suppresses issues if the type of the pointee of the address is ``volatile``. -You probably already need this to be ``volatile`` for legitimate access, so the checker suppresses such issues to avoid false-positives. -Note that null pointers will still be reported by :ref:`core.NullDereference <core-NullDereference>` -regardless if the pointee is ``volatile`` or not. - -If the analyzer option ``suppress-dereferences-from-any-address-space`` is set -to true (the default value), then this checker never reports dereference of -pointers with a specified address space. If the option is set to false, then -reports from the specific x86 address spaces 256, 257 and 258 are still -suppressed, but fixed address dereferences from other address spaces are -reported. - .. _core-NonNullParamChecker: core.NonNullParamChecker (C, C++, ObjC) @@ -898,6 +849,55 @@ of this Clang attribute. Projects that use this pattern should not enable this optin checker. +.. _optin-core-FixedAddressDereference: + +optin.core.FixedAddressDereference (C, C++, ObjC) +""""""""""""""""""""""""""""""""""""""""""""""""" +Check for dereferences of fixed addresses. + +A pointer contains a fixed address if it was set to a hard-coded value or it +becomes otherwise obvious that at that point it can have only a single fixed +numerical value. + +.. code-block:: c + + void test1() { + int *p = (int *)0x020; + int x = p[0]; // warn + } + + void test2(int *p) { + if (p == (int *)-1) + *p = 0; // warn + } + + void test3() { + int (*p_function)(char, char); + p_function = (int (*)(char, char))0x04080; + int x = (*p_function)('x', 'y'); // NO warning yet at functon pointer calls + } + + void volatile_pointee() { + *(volatile int *)0x404 = 1; // no warning: constant non-null "volatile" pointee, you must know what you are doing + } + + void deref_volatile_nullptr() { + *(volatile int *)0 = 1; // core.NullDereference still warns about this + } + +If your project is low-level (e.g., firmware), or deals with hardware interop with a lot of genuine constant addresses, then consider disabling this checker. +The checker automatically suppresses issues if the type of the pointee of the address is ``volatile``. +You probably already need this to be ``volatile`` for legitimate access, so the checker suppresses such issues to avoid false-positives. +Note that null pointers will still be reported by :ref:`core.NullDereference <core-NullDereference>` +regardless if the pointee is ``volatile`` or not. + +If the analyzer option ``suppress-dereferences-from-any-address-space`` is set +to true (the default value), then this checker never reports dereference of +pointers with a specified address space. If the option is set to false, then +reports from the specific x86 address spaces 256, 257 and 258 are still +suppressed, but fixed address dereferences from other address spaces are +reported. + .. _optin-cplusplus-UninitializedObject: optin.cplusplus.UninitializedObject (C++) diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index 58e785d5ca36f..35d2f9c1d5ef1 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -188,11 +188,6 @@ def CallAndMessageChecker ]>, Documentation<HasDocumentation>; -def FixedAddressDereferenceChecker - : Checker<"FixedAddressDereference">, - HelpText<"Check for dereferences of fixed addresses">, - Documentation<HasDocumentation>; - def NullDereferenceChecker : Checker<"NullDereference">, HelpText<"Check for dereferences of null pointers">, @@ -426,6 +421,11 @@ def EnumCastOutOfRangeChecker : Checker<"EnumCastOutOfRange">, HelpText<"Check integer to enumeration casts for out of range values">, Documentation<HasDocumentation>; +def FixedAddressDereferenceChecker + : Checker<"FixedAddressDereference">, + HelpText<"Check for dereferences of fixed addresses">, + Documentation<HasDocumentation>; + } // end "optin.core" //===----------------------------------------------------------------------===// diff --git a/clang/test/Analysis/analyzer-enabled-checkers.c b/clang/test/Analysis/analyzer-enabled-checkers.c index bfe418b112a9d..c1ed882069073 100644 --- a/clang/test/Analysis/analyzer-enabled-checkers.c +++ b/clang/test/Analysis/analyzer-enabled-checkers.c @@ -15,7 +15,6 @@ // CHECK-NEXT: core.CallAndMessage // CHECK-NEXT: core.DivideZero // CHECK-NEXT: core.DynamicTypePropagation -// CHECK-NEXT: core.FixedAddressDereference // CHECK-NEXT: core.NonNullParamChecker // CHECK-NEXT: core.NonnilStringConstants // CHECK-NEXT: core.NullDereference diff --git a/clang/test/Analysis/builtin_bitcast.cpp b/clang/test/Analysis/builtin_bitcast.cpp index 2ba32ec6d23d2..bcaec9ecc3096 100644 --- a/clang/test/Analysis/builtin_bitcast.cpp +++ b/clang/test/Analysis/builtin_bitcast.cpp @@ -1,5 +1,5 @@ // RUN: %clang_analyze_cc1 -triple x86_64-unknown-unknown -verify %s \ -// RUN: -analyzer-checker=core,debug.ExprInspection -analyzer-disable-checker=core.FixedAddressDereference +// RUN: -analyzer-checker=core,debug.ExprInspection template <typename T> void clang_analyzer_dump(T); using size_t = decltype(sizeof(int)); diff --git a/clang/test/Analysis/concrete-address.c b/clang/test/Analysis/concrete-address.c index 683b7f29f4611..0822c8a0b7532 100644 --- a/clang/test/Analysis/concrete-address.c +++ b/clang/test/Analysis/concrete-address.c @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core.FixedAddr,optin.core.FixedAddressDereference -verify %s extern void __assert_fail (__const char *__assertion, __const char *__file, unsigned int __line, __const char *__function) diff --git a/clang/test/Analysis/dtor.cpp b/clang/test/Analysis/dtor.cpp index 9e00e937a7c29..ab46ff5ec5ecf 100644 --- a/clang/test/Analysis/dtor.cpp +++ b/clang/test/Analysis/dtor.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection,cplusplus -analyzer-disable-checker=core.FixedAddressDereference -analyzer-config c++-inlining=destructors -Wno-null-dereference -Wno-inaccessible-base -verify -analyzer-config eagerly-assume=false %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection,cplusplus -analyzer-config c++-inlining=destructors -Wno-null-dereference -Wno-inaccessible-base -verify -analyzer-config eagerly-assume=false %s void clang_analyzer_eval(bool); void clang_analyzer_checkInlined(bool); diff --git a/clang/test/Analysis/fixed-address-notes.c b/clang/test/Analysis/fixed-address-notes.c index e246ee5a464b0..537fa8cbb6463 100644 --- a/clang/test/Analysis/fixed-address-notes.c +++ b/clang/test/Analysis/fixed-address-notes.c @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.core.FixedAddressDereference -analyzer-output=text -verify %s extern char *something(); diff --git a/clang/test/Analysis/misc-ps.m b/clang/test/Analysis/misc-ps.m index 794d8bbceb459..c22e0dbb6137d 100644 --- a/clang/test/Analysis/misc-ps.m +++ b/clang/test/Analysis/misc-ps.m @@ -1,6 +1,6 @@ // NOTE: Use '-fobjc-gc' to test the analysis being run twice, and multiple reports are not issued. -// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,alpha.core,osx.cocoa.AtSync -analyzer-disable-checker=core.FixedAddressDereference -Wno-strict-prototypes -Wno-pointer-to-int-cast -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s -// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,alpha.core,osx.cocoa.AtSync -analyzer-disable-checker=core.FixedAddressDereference -Wno-strict-prototypes -Wno-pointer-to-int-cast -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s +// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,alpha.core,osx.cocoa.AtSync -Wno-strict-prototypes -Wno-pointer-to-int-cast -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s +// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,alpha.core,osx.cocoa.AtSync -Wno-strict-prototypes -Wno-pointer-to-int-cast -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s #ifndef __clang_analyzer__ #error __clang_analyzer__ not defined diff --git a/clang/test/Analysis/pr22954.c b/clang/test/Analysis/pr22954.c index b5f8aeb2a5ca6..3d1cac1972066 100644 --- a/clang/test/Analysis/pr22954.c +++ b/clang/test/Analysis/pr22954.c @@ -3,7 +3,7 @@ // At the moment the whole of the destination array content is invalidated. // If a.s1 region has a symbolic offset, the whole region of 'a' is invalidated. // Specific triple set to test structures of size 0. -// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-disable-checker=core.FixedAddressDereference -Wno-error=int-conversion -verify -analyzer-config eagerly-assume=false %s +// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,unix.Malloc,debug.ExprInspection -Wno-error=int-conversion -verify -analyzer-config eagerly-assume=false %s typedef __typeof(sizeof(int)) size_t; diff --git a/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c b/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c index 9b3296064981f..4de004e00687a 100644 --- a/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c +++ b/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c @@ -23,7 +23,6 @@ // CHECK-NEXT: core.CallAndMessage // CHECK-NEXT: core.DivideZero // CHECK-NEXT: core.DynamicTypePropagation -// CHECK-NEXT: core.FixedAddressDereference // CHECK-NEXT: core.NonNullParamChecker // CHECK-NEXT: core.NonnilStringConstants // CHECK-NEXT: core.NullDereference diff --git a/clang/test/Analysis/suppress-dereferences-from-any-address-space.c b/clang/test/Analysis/suppress-dereferences-from-any-address-space.c index 5b42262c87223..c14781876c4ef 100644 --- a/clang/test/Analysis/suppress-dereferences-from-any-address-space.c +++ b/clang/test/Analysis/suppress-dereferences-from-any-address-space.c @@ -1,7 +1,7 @@ -// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,alpha.core -std=gnu99 -analyzer-config suppress-dereferences-from-any-address-space=false -verify=x86-nosuppress,common %s -// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,alpha.core -std=gnu99 -verify=x86-suppress,common %s -// RUN: %clang_analyze_cc1 -triple arm-pc-linux-gnu -analyzer-checker=core,alpha.core -std=gnu99 -analyzer-config suppress-dereferences-from-any-address-space=false -verify=other-nosuppress,common %s -// RUN: %clang_analyze_cc1 -triple arm-pc-linux-gnu -analyzer-checker=core,alpha.core -std=gnu99 -verify=other-suppress,common %s +// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,optin.core.FixedAddressDereference -std=gnu99 -analyzer-config suppress-dereferences-from-any-address-space=false -verify=x86-nosuppress,common %s +// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,optin.core.FixedAddressDereference -std=gnu99 -verify=x86-suppress,common %s +// RUN: %clang_analyze_cc1 -triple arm-pc-linux-gnu -analyzer-checker=core,optin.core.FixedAddressDereference -std=gnu99 -analyzer-config suppress-dereferences-from-any-address-space=false -verify=other-nosuppress,common %s +// RUN: %clang_analyze_cc1 -triple arm-pc-linux-gnu -analyzer-checker=core,optin.core.FixedAddressDereference -std=gnu99 -verify=other-suppress,common %s // Address-space attributes suppress the report even if the pointees are not marked `volatile`. #define AS_ATTRIBUTE(_X) __attribute__((address_space(_X))) _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
