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