diff --git a/clang/lib/StaticAnalyzer/Checkers/StringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StringChecker.cpp --- a/clang/lib/StaticAnalyzer/Checkers/StringChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StringChecker.cpp @@ -67,15 +67,18 @@ CheckerContext &C) const { if (!isCharToStringCtor(Call, C.getASTContext())) return; - const Loc Param = Call.getArgSVal(0).castAs(); + const auto Param = Call.getArgSVal(0).getAs(); + if (!Param.hasValue()) + return; // We managed to constrain the parameter to non-null. ProgramStateRef NotNull, Null; - std::tie(NotNull, Null) = C.getState()->assume(Param); + std::tie(NotNull, Null) = C.getState()->assume(*Param); if (NotNull) { const auto Callback = [Param](PathSensitiveBugReport &BR) -> std::string { - return BR.isInteresting(Param) ? "Assuming the pointer is not null." : ""; + return BR.isInteresting(*Param) ? "Assuming the pointer is not null." + : ""; }; // Emit note only if this operation constrained the pointer to be null. diff --git a/clang/test/Analysis/std-string.cpp b/clang/test/Analysis/std-string.cpp --- a/clang/test/Analysis/std-string.cpp +++ b/clang/test/Analysis/std-string.cpp @@ -8,6 +8,7 @@ void clang_analyzer_eval(bool); void clang_analyzer_warnIfReached(); +template void clang_analyzer_dump(T); void free(void *ptr); @@ -43,6 +44,12 @@ // expected-note@-2 {{The parameter must not be null}} } +void unknown_ctor_param(const char *p) { + // Pass 'UnknownVal' to the std::string constructor. + clang_analyzer_dump((char *)(p == 0)); // expected-warning {{Unknown}} expected-note {{Unknown}} + std::string x((char *)(p == 0)); // no-crash, no-warning +} + void ctor_notetag_on_constraining_symbol(const char *p) { clang_analyzer_eval(p == 0); // expected-warning {{UNKNOWN}} expected-note {{UNKNOWN}} std::string x(p); // expected-note {{Assuming the pointer is not null}}