diff options
author | Devin Coughlin <dcoughlin@apple.com> | 2016-02-08 00:28:24 +0000 |
---|---|---|
committer | Devin Coughlin <dcoughlin@apple.com> | 2016-02-08 00:28:24 +0000 |
commit | 480a0c00ca51d909a925120737b71289cbb79eda (patch) | |
tree | 210b82bfd5b8231de0512144f936d10f30cf5012 | |
parent | f1d54eb222d3b1dba50643473d4c77ea0f026915 (diff) | |
download | bcm5719-llvm-480a0c00ca51d909a925120737b71289cbb79eda.tar.gz bcm5719-llvm-480a0c00ca51d909a925120737b71289cbb79eda.zip |
[analyzer] Avoid crash when attempting to evaluate binary operation on LazyCompoundVal.
Instead, return UnknownValue if either operand is a nonloc::LazyCompoundVal. This is a
spot fix for PR 24951.
rdar://problem/23682244
llvm-svn: 260066
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/SValBuilder.cpp | 5 | ||||
-rw-r--r-- | clang/test/Analysis/string.c | 14 |
2 files changed, 19 insertions, 0 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp index 22bc14edd68..72bcdd9ecb0 100644 --- a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp @@ -367,6 +367,11 @@ SVal SValBuilder::evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, if (lhs.isUnknown() || rhs.isUnknown()) return UnknownVal(); + if (lhs.getAs<nonloc::LazyCompoundVal>() || + rhs.getAs<nonloc::LazyCompoundVal>()) { + return UnknownVal(); + } + if (Optional<Loc> LV = lhs.getAs<Loc>()) { if (Optional<Loc> RV = rhs.getAs<Loc>()) return evalBinOpLL(state, op, *LV, *RV, type); diff --git a/clang/test/Analysis/string.c b/clang/test/Analysis/string.c index 9fd3efb5c2d..c65d2be1a40 100644 --- a/clang/test/Analysis/string.c +++ b/clang/test/Analysis/string.c @@ -756,6 +756,20 @@ void strcmp_unknown_arg (char *unknown) { clang_analyzer_eval(strcmp(unknown, unknown) == 0); // expected-warning{{TRUE}} } +union argument { + char *f; +}; + +void function_pointer_cast_helper(char **a) { + strcmp("Hi", *a); // PR24951 crash +} + +void strcmp_union_function_pointer_cast(union argument a) { + void (*fPtr)(union argument *) = (void (*)(union argument *))function_pointer_cast_helper; + + fPtr(&a); +} + //===----------------------------------------------------------------------=== // strncmp() //===----------------------------------------------------------------------=== |