ASDenysPetrov marked 3 inline comments as done.
ASDenysPetrov added a comment.

@NoQ You concerns are absolutly justified. I agree with you. Let me tell what 
I'm thinking in inlines.

If you are interested in why the assertion happens, please, look D77062#1977613 
<https://reviews.llvm.org/D77062#1977613>



================
Comment at: clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp:273
   Optional<DefinedSVal> val = V.getAs<DefinedSVal>();
-  if (!val)
-    return std::pair<ProgramStateRef , ProgramStateRef >(state, state);
+  if (val && !V.getAs<nonloc::LazyCompoundVal>()) {
+     // return pair shall be {null, non-null} so reorder states
----------------
NoQ wrote:
> Basically `SVal::getAs<>` should not be used for discovering the type of the 
> value; only the exact representation that's used for the value of the type 
> that's already in your possession. Say, it's ok to use it to discriminate 
> between, say, compound value and lazy compound value. It's ok to use it to 
> discriminate between a concrete integer and a symbol. It's ok to use it do 
> discriminate between a known value and an unknown value. But if it's used for 
> discriminating between a compound value and a numeric symbol, i'm 99% sure 
> it's incorrect. You should already know the type from the AST before you even 
> obtain the value. It doesn't make sense to run the checker at all if the 
> function receives a structure. And if it doesn't receive the structure but 
> the run-time value is of structure type, then either the checker isn't 
> obtaining the value correctly or there's bug in path-sensitive analysis. 
> That's why i still believe you're only treating the symptoms. There's nothing 
> normal in the situation where "strcpy suddenly accepts a structure (or an 
> array) by value".
I'll remove `V.getAs<nonloc::LazyCompoundVal>()`. I mistakenly added this 
`V.getAs<nonloc::LazyCompoundVal>()` to keep code safe regardless of the 
checker intention and sanity. The point is that `state->assume(*val)` calls 
`ConstraintMgr->assumeDual` which finally calls 
`SimpleConstraintManager::assumeAux`. `assumeAux` handles all NonLoc kinds 
except **LazyCompoundValKind**and **CompoundValKind**(I missed to check it). In 
case of these two kinds it leads to `llvm_unreachable("'Assume' not implemented 
for this NonLoc");`. But for now I understand that I failed because 
**unreachable** means I might not have check for those kinds, since the 
function already takes on this work. 

However it is not an actual fix. The fix is `std::tie(states.second, 
states.first) = state->assume(*val);`. You can see the summary above.


================
Comment at: clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp:2270-2278
   // Pro-actively check that argument types are safe to do arithmetic upon.
   // We do not want to crash if someone accidentally passes a structure
   // into, say, a C++ overload of any of these functions. We could not check
   // that for std::copy because they may have arguments of other types.
   for (auto I : CE->arguments()) {
     QualType T = I->getType();
     if (!T->isIntegralOrEnumerationType() && !T->isPointerType())
----------------
This check prevents passing **structures**. From this point we are sure to work 
with **pointers **and **integral **types in arguments:
E.g. `char *strcpy(int i1, int i2);`, `char *strcpy(char *c1, char *c2);`, 
`char *strcpy(Kind t1, Kind t2);`
This confirms @NoQ's supposition that checker narrows argument types.
P.S. Honestly I'd narrow this more aggressively to just a **char pointer 
**type, anyway it doesn't relate to the bug and I wouldn't add this to a single 
patch.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77062/new/

https://reviews.llvm.org/D77062



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to