llvm-project/clang/lib/StaticAnalyzer/Checkers
Balazs Benics f8643a9b31 [analyzer] Prefer wrapping SymbolicRegions by ElementRegions
It turns out that in certain cases `SymbolRegions` are wrapped by
`ElementRegions`; in others, it's not. This discrepancy can cause the
analyzer not to recognize if the two regions are actually referring to
the same entity, which then can lead to unreachable paths discovered.

Consider this example:

```lang=C++
struct Node { int* ptr; };
void with_structs(Node* n1) {
  Node c = *n1; // copy
  Node* n2 = &c;
  clang_analyzer_dump(*n1); // lazy...
  clang_analyzer_dump(*n2); // lazy...
  clang_analyzer_dump(n1->ptr); // rval(n1->ptr): reg_$2<int * SymRegion{reg_$0<struct Node * n1>}.ptr>
  clang_analyzer_dump(n2->ptr); // rval(n2->ptr): reg_$1<int * Element{SymRegion{reg_$0<struct Node * n1>},0 S64b,struct Node}.ptr>
  clang_analyzer_eval(n1->ptr != n2->ptr); // UNKNOWN, bad!
  (void)(*n1);
  (void)(*n2);
}
```

The copy of `n1` will insert a new binding to the store; but for doing
that it actually must create a `TypedValueRegion` which it could pass to
the `LazyCompoundVal`. Since the memregion in question is a
`SymbolicRegion` - which is untyped, it needs to first wrap it into an
`ElementRegion` basically implementing this untyped -> typed conversion
for the sake of passing it to the `LazyCompoundVal`.
So, this is why we have `Element{SymRegion{.}, 0,struct Node}` for `n1`.

The problem appears if the analyzer evaluates a read from the expression
`n1->ptr`. The same logic won't apply for `SymbolRegionValues`, since
they accept raw `SubRegions`, hence the `SymbolicRegion` won't be
wrapped into an `ElementRegion` in that case.

Later when we arrive at the equality comparison, we cannot prove that
they are equal.

For more details check the corresponding thread on discourse:
https://discourse.llvm.org/t/are-symbolicregions-really-untyped/64406

---

In this patch, I'm eagerly wrapping each `SymbolicRegion` by an
`ElementRegion`; basically canonicalizing to this form.
It seems reasonable to do so since any object can be thought of as a single
array of that object; so this should not make much of a difference.

The tests also underpin this assumption, as only a few were broken by
this change; and actually fixed a FIXME along the way.

About the second example, which does the same copy operation - but on
the heap - it will be fixed by the next patch.

Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D132142
2022-09-13 08:58:46 +02:00
..
MPI-Checker [analyzer][NFC] Prefer using isa<> instead getAs<> in conditions 2022-06-15 16:58:13 +02:00
RetainCountChecker [clang] LLVM_FALLTHROUGH => [[fallthrough]]. NFC 2022-08-08 09:12:46 -07:00
UninitializedObject [clang] Remove redundant virtual specifies (NFC) 2022-07-24 22:02:58 -07:00
WebKit [clang] Qualify auto in range-based for loops (NFC) 2022-09-03 23:27:27 -07:00
cert [analyzer][NFC] Add partial specializations for ProgramStateTraits 2022-06-02 19:46:38 +02:00
AllocationState.h
AnalysisOrderChecker.cpp
AnalyzerStatsChecker.cpp [analyzer][NFC] Refactor llvm::isa<> usages in the StaticAnalyzer 2021-10-20 17:43:31 +02:00
ArrayBoundChecker.cpp [analyzer] Replace adjacent assumeInBound calls to assumeInBoundDual 2022-05-10 10:16:55 +02:00
ArrayBoundCheckerV2.cpp [analyzer][NFC] Prefer using isa<> instead getAs<> in conditions 2022-06-15 16:58:13 +02:00
BasicObjCFoundationChecks.cpp [clang] Use value instead of getValue (NFC) 2022-07-13 23:39:33 -07:00
BlockInCriticalSectionChecker.cpp [analyzer][NFC] Switch to using CallDescription::matches() instead of isCalled() 2021-11-19 18:32:13 +01:00
BoolAssignmentChecker.cpp [analyzer] Add taint to the BoolAssignmentChecker 2022-05-13 09:27:28 +02:00
BuiltinFunctionChecker.cpp [Clang] Add __builtin_function_start 2021-12-20 12:55:33 -08:00
CMakeLists.txt [analyzer] Warn if the size of the array in `new[]` is undefined 2022-09-04 23:06:58 +02:00
CStringChecker.cpp [clang][analyzer] Add more wide-character functions to CStringChecker 2022-08-05 10:32:53 +02:00
CStringSyntaxChecker.cpp
CXXSelfAssignmentChecker.cpp
CallAndMessageChecker.cpp [analyzer] Clean checker options from bool to DefaultBool (NFC) 2022-04-23 14:47:29 -05:00
CastSizeChecker.cpp [analyzer] DynamicSize: Rename 'size' to 'extent' 2021-04-05 19:20:43 +02:00
CastToStructChecker.cpp
CastValueChecker.cpp [analyzer] Fix null pointer deref in CastValueChecker 2022-06-07 13:34:06 -04:00
CheckObjCDealloc.cpp [clang] Don't use Optional::getValue (NFC) 2022-06-20 22:59:26 -07:00
CheckObjCInstMethSignature.cpp [clang] Add a raw_ostream operator<< overload for QualType 2022-04-20 22:09:05 +01:00
CheckPlacementNew.cpp [analyzer] DynamicSize: Rename 'size' to 'extent' 2021-04-05 19:20:43 +02:00
CheckSecuritySyntaxOnly.cpp [analyzer] Clean checker options from bool to DefaultBool (NFC) 2022-04-23 14:47:29 -05:00
CheckSizeofPointer.cpp
CheckerDocumentation.cpp
ChrootChecker.cpp [analyzer][NFC] Switch to using CallDescription::matches() instead of isCalled() 2021-11-19 18:32:13 +01:00
CloneChecker.cpp [analyzer] Clean checker options from bool to DefaultBool (NFC) 2022-04-23 14:47:29 -05:00
ContainerModeling.cpp [analyzer][NFC] Use enum for CallDescription flags 2021-11-19 18:32:13 +01:00
ConversionChecker.cpp [analyzer] Expand conversion check to check more expressions for overflow and underflow 2021-12-15 11:41:34 +01:00
DeadStoresChecker.cpp [analyzer] Deadstore static analysis: Fix false positive on C++17 assignments 2022-08-23 18:33:26 +02:00
DebugCheckers.cpp [clang] Use true/false instead of 1/0 (NFC) 2022-01-09 00:19:47 -08:00
DebugContainerModeling.cpp [analyzer][NFC] Use enum for CallDescription flags 2021-11-19 18:32:13 +01:00
DebugIteratorModeling.cpp [analyzer][NFC] Use enum for CallDescription flags 2021-11-19 18:32:13 +01:00
DeleteWithNonVirtualDtorChecker.cpp
DereferenceChecker.cpp [analyzer][NFC] Prefer using isa<> instead getAs<> in conditions 2022-06-15 16:58:13 +02:00
DirectIvarAssignment.cpp [Sema, StaticAnalyzer] Use StringRef::contains (NFC) 2021-10-20 08:02:36 -07:00
DivZeroChecker.cpp [analyzer] Expose Taint.h to plugins 2022-04-19 16:55:01 +02:00
DynamicTypeChecker.cpp
DynamicTypePropagation.cpp [analyzer][NFC] Remove dead code and modernize surroundings 2022-06-15 16:50:12 +02:00
EnumCastOutOfRangeChecker.cpp [clang][NFC] Inclusive terms: Replace uses of whitelist in clang/lib/StaticAnalyzer 2021-10-29 16:51:36 -04:00
ErrnoChecker.cpp [clang][analyzer] Add checker for bad use of 'errno'. 2022-06-20 10:07:31 +02:00
ErrnoModeling.cpp [clang][analyzer] Errno modeling code refactor (NFC). 2022-09-01 09:05:59 +02:00
ErrnoModeling.h [clang][analyzer] Errno modeling code refactor (NFC). 2022-09-01 09:05:59 +02:00
ErrnoTesterChecker.cpp [clang][analyzer] Add checker for bad use of 'errno'. 2022-06-20 10:07:31 +02:00
ExprInspectionChecker.cpp [analyzer] Prefer wrapping SymbolicRegions by ElementRegions 2022-09-13 08:58:46 +02:00
FixedAddressChecker.cpp
FuchsiaHandleChecker.cpp [analyzer][NFC] Remove dead code and modernize surroundings 2022-06-15 16:50:12 +02:00
GCDAntipatternChecker.cpp [clang] Rename StringRef _lower() method calls to _insensitive() 2021-06-25 00:22:01 +03:00
GTestChecker.cpp [clang] Don't use Optional::hasValue (NFC) 2022-06-25 22:26:24 -07:00
GenericTaintChecker.cpp [clang] Don't use Optional::getValue (NFC) 2022-06-20 22:59:26 -07:00
IdenticalExprChecker.cpp
InnerPointerChecker.cpp Remove redundaunt virtual specifiers (NFC) 2022-07-25 23:00:59 -07:00
InterCheckerAPI.h
InvalidatedIteratorChecker.cpp
Iterator.cpp [analyzer][NFC] Prefer using isa<> instead getAs<> in conditions 2022-06-15 16:58:13 +02:00
Iterator.h [analyzer][NFC] Remove dead code and modernize surroundings 2022-06-15 16:50:12 +02:00
IteratorModeling.cpp [analyzer][NFC] Prefer using isa<> instead getAs<> in conditions 2022-06-15 16:58:13 +02:00
IteratorRangeChecker.cpp [analyzer][NFC] Separate CallDescription from CallEvent 2021-11-15 19:10:46 +01:00
IvarInvalidationChecker.cpp [analyzer] Clean checker options from bool to DefaultBool (NFC) 2022-04-23 14:47:29 -05:00
LLVMConventionsChecker.cpp [clang] Add a raw_ostream operator<< overload for QualType 2022-04-20 22:09:05 +01:00
LocalizationChecker.cpp [clang] Don't use Optional::hasValue (NFC) 2022-06-20 10:51:34 -07:00
MIGChecker.cpp [clang][NFC] Inclusive terms: replace some uses of sanity in clang 2021-11-19 14:58:35 -05:00
MacOSKeychainAPIChecker.cpp [analyzer][NFC] Refactor llvm::isa<> usages in the StaticAnalyzer 2021-10-20 17:43:31 +02:00
MacOSXAPIChecker.cpp
MallocChecker.cpp [analyzer] Warn if the size of the array in `new[]` is undefined 2022-09-04 23:06:58 +02:00
MallocOverflowSecurityChecker.cpp [analyzer][NFC] Refactor llvm::isa<> usages in the StaticAnalyzer 2021-10-20 17:43:31 +02:00
MallocSizeofChecker.cpp [clang] Add a raw_ostream operator<< overload for QualType 2022-04-20 22:09:05 +01:00
MismatchedIteratorChecker.cpp
MmapWriteExecChecker.cpp [analyzer][NFC] Prefer using isa<> instead getAs<> in conditions 2022-06-15 16:58:13 +02:00
Move.h
MoveChecker.cpp [analyzer] Fix false positive in use-after-move checker 2022-08-09 17:26:30 -07:00
NSAutoreleasePoolChecker.cpp
NSErrorChecker.cpp [clang] Qualify auto in range-based for loops (NFC) 2022-09-03 23:27:27 -07:00
NoReturnFunctionChecker.cpp
NonNullParamChecker.cpp [clang] Use value instead of getValue (NFC) 2022-07-13 23:39:33 -07:00
NonnullGlobalConstantsChecker.cpp [clang] Implement ElaboratedType sugaring for types written bare 2022-07-27 11:10:54 +02:00
NullabilityChecker.cpp [analyzer] Prefer wrapping SymbolicRegions by ElementRegions 2022-09-13 08:58:46 +02:00
NumberObjectConversionChecker.cpp [clang] Implement ElaboratedType sugaring for types written bare 2022-07-27 11:10:54 +02:00
OSObjectCStyleCast.cpp [analyzer] Support allocClassWithName in OSObjectCStyleCast checker 2021-03-30 15:58:06 +03:00
ObjCAtSyncChecker.cpp [analyzer][NFC] Prefer using isa<> instead getAs<> in conditions 2022-06-15 16:58:13 +02:00
ObjCAutoreleaseWriteChecker.cpp [analyzer] Fix return of llvm::StringRef to destroyed std::string 2022-05-01 12:24:32 +01:00
ObjCContainersASTChecker.cpp [clang] Add a raw_ostream operator<< overload for QualType 2022-04-20 22:09:05 +01:00
ObjCContainersChecker.cpp [analyzer][NFC] Remove dead code and modernize surroundings 2022-06-15 16:50:12 +02:00
ObjCMissingSuperCallChecker.cpp
ObjCPropertyChecker.cpp
ObjCSelfInitChecker.cpp [analyzer][NFC] Prefer using isa<> instead getAs<> in conditions 2022-06-15 16:58:13 +02:00
ObjCSuperDeallocChecker.cpp
ObjCUnusedIVarsChecker.cpp
PaddingChecker.cpp Use any_of (NFC) 2022-07-24 14:48:11 -07:00
PointerArithChecker.cpp
PointerIterationChecker.cpp
PointerSortingChecker.cpp
PointerSubChecker.cpp
PthreadLockChecker.cpp [analyzer] Clean checker options from bool to DefaultBool (NFC) 2022-04-23 14:47:29 -05:00
ReturnPointerRangeChecker.cpp [analyzer] Replace adjacent assumeInBound calls to assumeInBoundDual 2022-05-10 10:16:55 +02:00
ReturnUndefChecker.cpp
ReturnValueChecker.cpp Remove redundant string initialization (NFC) 2021-12-26 09:39:26 -08:00
RunLoopAutoreleaseLeakChecker.cpp
STLAlgorithmModeling.cpp [analyzer][NFC] Prefer using isa<> instead getAs<> in conditions 2022-06-15 16:58:13 +02:00
SimpleStreamChecker.cpp [analyzer][NFC] Remove dead code and modernize surroundings 2022-06-15 16:50:12 +02:00
SmartPtr.h [StaticAnalyzer] Remove redundant declaration isStdSmartPtr (NFC) 2021-12-25 00:35:41 -08:00
SmartPtrChecker.cpp
SmartPtrModeling.cpp [analyzer][NFC] Remove dead code and modernize surroundings 2022-06-15 16:50:12 +02:00
StackAddrEscapeChecker.cpp [analyzer] Fixing a bug raising false positives of stack block object 2022-08-26 12:19:32 -07:00
StdLibraryFunctionsChecker.cpp [clang][analyzer] Errno modeling code refactor (NFC). 2022-09-01 09:05:59 +02:00
StreamChecker.cpp [clang] Qualify auto in range-based for loops (NFC) 2022-09-03 23:27:27 -07:00
StringChecker.cpp [clang] Don't use Optional::hasValue (NFC) 2022-06-20 10:51:34 -07:00
Taint.cpp [Analyzer] Fix clang::ento::taint::dumpTaint definition 2022-05-02 17:44:06 +02:00
TaintTesterChecker.cpp [analyzer][NFC] Remove dead code and modernize surroundings 2022-06-15 16:50:12 +02:00
TestAfterDivZeroChecker.cpp
TraversalChecker.cpp
TrustNonnullChecker.cpp
TrustReturnsNonnullChecker.cpp [analyzer] Add support for __attribute__((returns_nonnull)). 2022-02-02 11:46:52 -08:00
UndefBranchChecker.cpp
UndefCapturedBlockVarChecker.cpp [analyzer] Change FindLastStoreBRVisitor to use Tracker 2021-06-11 12:49:03 +03:00
UndefResultChecker.cpp [analyzer] Replace adjacent assumeInBound calls to assumeInBoundDual 2022-05-10 10:16:55 +02:00
UndefinedArraySubscriptChecker.cpp
UndefinedAssignmentChecker.cpp [clang] Qualify auto in range-based for loops (NFC) 2022-09-03 23:27:27 -07:00
UndefinedNewArraySizeChecker.cpp [analyzer] Warn if the size of the array in `new[]` is undefined 2022-09-04 23:06:58 +02:00
UnixAPIChecker.cpp [clang] Use value instead of getValue (NFC) 2022-07-13 23:39:33 -07:00
UnreachableCodeChecker.cpp
VLASizeChecker.cpp [analyzer][NFC] Prefer using isa<> instead getAs<> in conditions 2022-06-15 16:58:13 +02:00
ValistChecker.cpp [analyzer] Fix ValistChecker false-positive involving symbolic pointers 2022-04-26 08:49:05 +02:00
VforkChecker.cpp [clang][NFC] Inclusive terms: Replace uses of whitelist in clang/lib/StaticAnalyzer 2021-10-29 16:51:36 -04:00
VirtualCallChecker.cpp
Yaml.h [NFC] Fix endif comments to match with include guard 2022-01-07 15:52:59 +08:00