[analyzer][NFCI] Move the core.FixedAddressDereference checker to optin.core (#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
This commit is contained in:
Balázs Benics 2026-02-18 14:39:54 +00:00 committed by GitHub
parent 693548d9f7
commit 4f3ae6ea09
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 65 additions and 67 deletions

View File

@ -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++)

View File

@ -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"
//===----------------------------------------------------------------------===//

View File

@ -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

View File

@ -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));

View File

@ -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)

View File

@ -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);

View File

@ -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();

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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)))