Index: clang/lib/StaticAnalyzer/Core/RegionStore.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -1704,9 +1704,9 @@ // FIXME: This is a hack, and doesn't do anything really intelligent yet. const RegionRawOffset &O = R->getAsArrayOffset(); - // If we cannot reason about the offset, return an unknown value. + // If we cannot reason about the offset, return a symbolic value. if (!O.getRegion()) - return UnknownVal(); + return svalBuilder.getRegionValueSymbolVal(R); if (const TypedValueRegion *baseR = dyn_cast_or_null(O.getRegion())) { Index: clang/test/Analysis/PR9289.cpp =================================================================== --- /dev/null +++ clang/test/Analysis/PR9289.cpp @@ -0,0 +1,97 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s + +int index_sym(const int *a, int index) { + int var; + int ret = 0; + if (a[index] < 2) + var = 1; + if (a[index] < 2) + ret = var; // no warning about garbage value + return ret; +} + +int index_int(const int *a, int index) { + int var; + int ret = 0; + if (a[42] < 2) + var = 1; + if (a[42] < 2) + ret = var; // no warning about garbage value + return ret; +} + +int multi_ext_arr(const int **a, int index, int index2) { + int var; + int ret = 0; + if (a[index][index2] < 2) + var = 1; + if (a[index][index2] < 2) + ret = var; // no warning about garbage value + return ret; +} + +int index_sym_change(const int *a, int index, int index2) { + int var; + int ret = 0; + if (a[index] < 2) + var = 1; + index = index2; + if (a[index] < 2) + ret = var; // expected-warning{{Assigned value is garbage or undefined [core.uninitialized.Assign]}} + return ret; +} + +int index_int_change(const int *a, int index, int index2) { + int var; + int ret = 0; + if (a[index] < 2) + var = 1; + index = 42; + if (a[index] < 2) + ret = var; // expected-warning{{Assigned value is garbage or undefined [core.uninitialized.Assign]}} + return ret; +} + +int element_sym_change(int *a, int index, int newValue) { + int var; + int ret = 0; + if (a[index] < 2) + var = 1; + a[index] = newValue; + if (a[index] < 2) + ret = var; // expected-warning{{Assigned value is garbage or undefined [core.uninitialized.Assign]}} + return ret; +} + +int element_int_change(int *a, int index) { + int var; + int ret = 0; + if (a[index] < 2) + var = 1; + a[index] = 42; + if (a[index] < 2) + ret = var; // no warning, branch does not execute + return ret; +} + +int element_int_change2(int *a, int index) { + int var; + int ret = 0; + if (a[index] < 2) + var = 1; + a[index] = 1; + if (a[index] < 2) + ret = var; // expected-warning{{Assigned value is garbage or undefined [core.uninitialized.Assign]}} + return ret; +} + +int ptr_sym_change(int *a, int index, int *a2) { + int var; + int ret = 0; + if (a[index] < 2) + var = 1; + a = a2; + if (a[index] < 2) + ret = var; // expected-warning{{Assigned value is garbage or undefined [core.uninitialized.Assign]}} + return ret; +} \ No newline at end of file