Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F11023344
D60988.diff
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Wed, Dec 11, 6:08 AM
Size
1 KB
Mime Type
text/x-patch; charset=utf-8
Expires
Thu, Dec 12, 6:08 AM (23 h, 59 m)
Engine
blob
Format
Raw Data
Handle
5862505
Attached To
D60988: [analyzer] Fix crash when returning C++ objects from ObjC messages-to-nil.
D60988.diff
View Options
Index: lib/StaticAnalyzer/Core/RegionStore.cpp
===================================================================
--- lib/StaticAnalyzer/Core/RegionStore.cpp
+++ lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -2361,7 +2361,14 @@
// In C++17 aggregates may have base classes, handle those as well.
// They appear before fields in the initializer list / compound value.
if (const auto *CRD = dyn_cast<CXXRecordDecl>(RD)) {
- assert(CRD->isAggregate() &&
+ // If the object was constructed with a constructor, its value is a
+ // LazyCompoundVal. If it's a raw CompoundVal, it means that we're
+ // performing aggregate initialization. The only exception from this
+ // rule is sending an Objective-C++ message that returns a C++ object
+ // to a nil receiver; in this case the semantics is to return a
+ // zero-initialized object even if it's a C++ object that doesn't have
+ // this sort of constructor; the CompoundVal is empty in this case.
+ assert((CRD->isAggregate() || (Ctx.getLangOpts().ObjC && VI == VE)) &&
"Non-aggregates are constructed with a constructor!");
for (const auto &B : CRD->bases()) {
Index: test/Analysis/nil-receiver.mm
===================================================================
--- test/Analysis/nil-receiver.mm
+++ test/Analysis/nil-receiver.mm
@@ -0,0 +1,24 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection \
+// RUN: -verify %s
+
+#define nil ((id)0)
+
+void clang_analyzer_eval(int);
+
+struct S {
+ int x;
+ S();
+};
+
+@interface I
+@property S s;
+@end
+
+void foo() {
+ // This produces a zero-initialized structure.
+ // FIXME: This very fact does deserve the warning, because zero-initialized
+ // structures aren't always valid in C++. It's particularly bad when the
+ // object has a vtable.
+ S s = ((I *)nil).s;
+ clang_analyzer_eval(s.x == 0); // expected-warning{{TRUE}}
+}
Event Timeline
Log In to Comment