diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp | 4 | ||||
| -rw-r--r-- | clang/test/Analysis/nonnull.m | 47 |
2 files changed, 49 insertions, 2 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp index c9b86399fd9..f9a43ad803d 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp @@ -104,7 +104,9 @@ void NonNullParamChecker::checkPreCall(const CallEvent &Call, V = *CSV_I; DV = V.getAs<DefinedSVal>(); assert(++CSV_I == CSV->end()); - if (!DV) + // FIXME: Handle (some_union){ some_other_union_val }, which turns into + // a LazyCompoundVal inside a CompoundVal. + if (!V.getAs<Loc>()) continue; // Retrieve the corresponding expression. if (const CompoundLiteralExpr *CE = dyn_cast<CompoundLiteralExpr>(ArgE)) diff --git a/clang/test/Analysis/nonnull.m b/clang/test/Analysis/nonnull.m index a4955ca0a45..0cea80b536d 100644 --- a/clang/test/Analysis/nonnull.m +++ b/clang/test/Analysis/nonnull.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core -w -verify %s @interface MyObject - (void)takePointer:(void *)ptr __attribute__((nonnull(1))); @@ -30,3 +30,48 @@ void testSubclassArg(int *p, Subclass *obj) { [obj takePointerArg:p]; // expected-warning{{nonnull}} } + +union rdar16153464_const_cp_t { + const struct rdar16153464_cczp *zp; + const struct rdar16153464_cczp_prime *prime; +} __attribute__((transparent_union)); + +struct rdar16153464_header { + union rdar16153464_const_cp_t cp; + unsigned char pad[16 - sizeof(union rdar16153464_const_cp_t *)]; +} __attribute__((aligned(16))); + + +struct rdar16153464_full_ctx { + struct rdar16153464_header hdr; +} __attribute__((aligned(16))); + + +struct rdar16153464_pub_ctx { + struct rdar16153464_header hdr; +} __attribute__((aligned(16))); + + +union rdar16153464_full_ctx_t { + struct rdar16153464_full_ctx *_full; + struct rdar16153464_header *hdr; + struct rdar16153464_body *body; + struct rdar16153464_public *pub; +} __attribute__((transparent_union)); + +union rdar16153464_pub_ctx_t { + struct rdar16153464_pub_ctx *_pub; + struct rdar16153464_full_ctx *_full; + struct rdar16153464_header *hdr; + struct rdar16153464_body *body; + struct rdar16153464_public *pub; + union rdar16153464_full_ctx_t innert; +} __attribute__((transparent_union)); + +int rdar16153464(union rdar16153464_full_ctx_t inner) +{ + extern void rdar16153464_check(union rdar16153464_pub_ctx_t outer) __attribute((nonnull(1))); + rdar16153464_check((union rdar16153464_pub_ctx_t){ .innert = inner }); // no-warning + rdar16153464_check(inner); // no-warning + rdar16153464_check(0); // expected-warning{{nonnull}} +} |

