Index: lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp =================================================================== --- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -935,6 +935,8 @@ // Offset the increment by the pointer size. llvm::APSInt Multiplicand(rightI.getBitWidth(), /* isUnsigned */ true); + QualType PteeTy = resultTy.getTypePtr()->castAs()->getPointeeType(); + Multiplicand = getContext().getTypeSizeInChars(PteeTy).getQuantity(); rightI *= Multiplicand; // Compute the adjusted pointer. Index: test/Analysis/explain-svals.cpp =================================================================== --- test/Analysis/explain-svals.cpp +++ test/Analysis/explain-svals.cpp @@ -59,8 +59,7 @@ clang_analyzer_explain(&s.s2[5].y[3]); // expected-warning-re{{{{^pointer to element of type 'int' with index 3 of field 'y' of base object 'S::S3' inside element of type 'struct S::S2' with index 5 of field 's2' of parameter 's'$}}}} if (!s.s2[7].x) { clang_analyzer_explain(s.s2[7].x); // expected-warning-re{{{{^concrete memory address '0'$}}}} - // FIXME: we need to be explaining '1' rather than '0' here; not explainer bug. - clang_analyzer_explain(s.s2[7].x + 1); // expected-warning-re{{{{^concrete memory address '0'$}}}} + clang_analyzer_explain(s.s2[7].x + 1); // expected-warning-re{{{{^concrete memory address '4'$}}}} } } Index: test/Analysis/inlining/inline-defensive-checks.c =================================================================== --- test/Analysis/inlining/inline-defensive-checks.c +++ test/Analysis/inlining/inline-defensive-checks.c @@ -159,8 +159,7 @@ void idcTrackZeroValueThroughUnaryPointerOperatorsWithOffset2(struct S *s) { idc(s); int *x = &(s->f2) - 1; - // FIXME: Should not warn. - *x = 7; // expected-warning{{Dereference of null pointer}} + *x = 7; // no-warning } void idcTrackZeroValueThroughUnaryPointerOperatorsWithAssignment(struct S *s) { Index: test/Analysis/pointer-arithmetic.c =================================================================== --- test/Analysis/pointer-arithmetic.c +++ test/Analysis/pointer-arithmetic.c @@ -0,0 +1,28 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s + +int test1() { + int *p = (int *)sizeof(int); + p -= 1; + return *p; // expected-warning {{Dereference of null pointer}} +} + +int test2() { + int *p = (int *)sizeof(int); + p -= 2; + p += 1; + return *p; // expected-warning {{Dereference of null pointer}} +} + +int test3() { + int *p = (int *)sizeof(int); + p++; + p--; + p--; + return *p; // expected-warning {{Dereference of null pointer}} +} + +int test4() { + int *p = 0; + p += 1; + return *p; // no-warning +}