[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:
parent
693548d9f7
commit
4f3ae6ea09
@ -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++)
|
||||
|
||||
@ -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"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user