https://github.com/steakhal created https://github.com/llvm/llvm-project/pull/181644
In short, those who use `volatile` probably know better their own hardware, so let's not bother them with FPs. Note that dereferencing NULL pointers will still be reported, because that's the core.NullDereference checker's responsibility. See the discussion motivating this change: https://discourse.llvm.org/t/what-are-the-precise-semantics-of-the-address-space-attribute/89752/9 Also relates to https://github.com/llvm/llvm-project/pull/132404#issuecomment-3816874305 From 3622b3d729ccd013253a0c7a436ff7a2fab6b202 Mon Sep 17 00:00:00 2001 From: Balazs Benics <[email protected]> Date: Mon, 16 Feb 2026 12:52:39 +0100 Subject: [PATCH] [analyzer] Suppress core.FixedAddressDereference reports with volatile pointee In short, those who use `volatile` probably know better their own hardware, so let's not bother them with FPs. Note that dereferencing NULL pointers will still be reported, because that's the core.NullDereference checker's responsibility. See the discussion motivating this change: https://discourse.llvm.org/t/what-are-the-precise-semantics-of-the-address-space-attribute/89752/9 --- clang/docs/analyzer/checkers.rst | 14 ++++++++++++++ .../Checkers/DereferenceChecker.cpp | 3 ++- clang/test/Analysis/fixed-address-notes.c | 18 ++++++++++++++++++ ...press-dereferences-from-any-address-space.c | 3 ++- 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index 499b78895392b..7ff55bc9d77a7 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -167,6 +167,20 @@ numerical value. 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 diff --git a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp index 37f5ec3557400..be61eceeb62e7 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp @@ -315,7 +315,8 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S, if (location.isConstant()) { const Expr *DerefExpr = getDereferenceExpr(S, isLoad); - if (!suppressReport(C, DerefExpr)) + if (!DerefExpr->getType().isVolatileQualified() && + !suppressReport(C, DerefExpr)) reportDerefBug(FixedAddressBug, notNullState, DerefExpr, C); return; } diff --git a/clang/test/Analysis/fixed-address-notes.c b/clang/test/Analysis/fixed-address-notes.c index 59b417eed38f1..e246ee5a464b0 100644 --- a/clang/test/Analysis/fixed-address-notes.c +++ b/clang/test/Analysis/fixed-address-notes.c @@ -50,3 +50,21 @@ void test4() { *x = 3; // expected-warning{{Dereference of a fixed address (loaded from variable 'x')}} \ // expected-note{{Dereference of a fixed address (loaded from variable 'x')}} } + +void suppress_volatile_pointee(void) { + *(volatile int *)0x00011100 = 4; // no-warning: volatile pointees are suppressed +} + +void suppress_volatile_pointee_using_subscript(void) { + ((volatile int *)0x00011100)[0] = 4; // no-warning: volatile pointees are suppressed +} + +void suppress_ptr_to_100element_volatile_array(void) { + ((volatile int (*)[100])0x00011100)[2][0] = 4; // no-warning: volatile pointees are suppressed +} + +void deref_volatile_nullptr(void) { + *(volatile int *)0 = 1; // core.NullDereference still warns about this + // expected-warning@-1 {{Dereference of null pointer [core.NullDereference]}} + // expected-note@-2 {{Dereference of null pointer}} +} 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 c1cb227994e05..5b42262c87223 100644 --- a/clang/test/Analysis/suppress-dereferences-from-any-address-space.c +++ b/clang/test/Analysis/suppress-dereferences-from-any-address-space.c @@ -3,7 +3,8 @@ // 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 -#define AS_ATTRIBUTE(_X) volatile __attribute__((address_space(_X))) +// Address-space attributes suppress the report even if the pointees are not marked `volatile`. +#define AS_ATTRIBUTE(_X) __attribute__((address_space(_X))) #define _get_base() ((void * AS_ATTRIBUTE(256) *)0) _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
