[analyzer] Handle C string default values for const char * arguments.
Previously, SValBuilder knew how to evaluate StringLiterals, but couldn't handle an array-to-pointer decay for constant values. Additionally, RegionStore was being too strict about loading from an array, refusing to return a 'char' value from a 'const char' array. Both of these have been fixed. llvm-svn: 186520
This commit is contained in:
parent
05b2f98d89
commit
5fded08403
|
@ -1497,7 +1497,7 @@ SVal RegionStoreManager::getBindingForElement(RegionBindingsConstRef B,
|
|||
// FIXME: Handle loads from strings where the literal is treated as
|
||||
// an integer, e.g., *((unsigned int*)"hello")
|
||||
QualType T = Ctx.getAsArrayType(StrR->getValueType())->getElementType();
|
||||
if (T != Ctx.getCanonicalType(R->getElementType()))
|
||||
if (!Ctx.hasSameUnqualifiedType(T, R->getElementType()))
|
||||
return UnknownVal();
|
||||
|
||||
const StringLiteral *Str = StrR->getStringLiteral();
|
||||
|
|
|
@ -266,6 +266,17 @@ Optional<SVal> SValBuilder::getConstantVal(const Expr *E) {
|
|||
case Stmt::CXXNullPtrLiteralExprClass:
|
||||
return makeNull();
|
||||
|
||||
case Stmt::ImplicitCastExprClass: {
|
||||
const CastExpr *CE = cast<CastExpr>(E);
|
||||
if (CE->getCastKind() == CK_ArrayToPointerDecay) {
|
||||
Optional<SVal> ArrayVal = getConstantVal(CE->getSubExpr());
|
||||
if (!ArrayVal)
|
||||
return None;
|
||||
return evalCast(*ArrayVal, CE->getType(), CE->getSubExpr()->getType());
|
||||
}
|
||||
// FALLTHROUGH
|
||||
}
|
||||
|
||||
// If we don't have a special case, fall back to the AST's constant evaluator.
|
||||
default: {
|
||||
// Don't try to come up with a value for materialized temporaries.
|
||||
|
|
|
@ -290,6 +290,15 @@ namespace DefaultArgs {
|
|||
clang_analyzer_eval(defaultFloatReferenceZero(1) == -1); // expected-warning{{UNKNOWN}}
|
||||
clang_analyzer_eval(defaultFloatReferenceZero() == 0); // expected-warning{{UNKNOWN}}
|
||||
}
|
||||
|
||||
char defaultString(const char *s = "abc") {
|
||||
return s[1];
|
||||
}
|
||||
|
||||
void testString() {
|
||||
clang_analyzer_eval(defaultString("xyz") == 'y'); // expected-warning{{TRUE}}
|
||||
clang_analyzer_eval(defaultString() == 'b'); // expected-warning{{TRUE}}
|
||||
}
|
||||
}
|
||||
|
||||
namespace OperatorNew {
|
||||
|
|
Loading…
Reference in New Issue