[clang] 3787aa1 - [analyzer] Suppress core.FixedAddressDereference reports with volatile pointee (#181644)

via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 17 07:47:04 PST 2026


Author: Balázs Benics
Date: 2026-02-17T15:46:58Z
New Revision: 3787aa12c5b37d3073276e009ec211a0c1006843

URL: https://github.com/llvm/llvm-project/commit/3787aa12c5b37d3073276e009ec211a0c1006843
DIFF: https://github.com/llvm/llvm-project/commit/3787aa12c5b37d3073276e009ec211a0c1006843.diff

LOG: [analyzer] Suppress core.FixedAddressDereference reports with volatile pointee (#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

rdar://170466245

Added: 
    

Modified: 
    clang/docs/analyzer/checkers.rst
    clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
    clang/test/Analysis/fixed-address-notes.c
    clang/test/Analysis/suppress-dereferences-from-any-address-space.c

Removed: 
    


################################################################################
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 at -1 {{Dereference of null pointer [core.NullDereference]}}
+  // expected-note at -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)
 


        


More information about the cfe-commits mailing list