Fixes PR27439
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
We're going to try evaluating the array size anyway (in isArraySizeVLA). It would be much better to produce the overflow warnings as part of that evaluation rather than adding an extra evaluation step to produce them.
This is still evaluating the expression twice. To evaluate it only once, you'll need to sink the checks into Sema::VerifyIntegerConstantExpression's call to EvaluateKnownConstInt. (That should also remove the redundant diagnostics noise in the language modes where signed overflow renders an expression non-constant.)
I have not found a way yet since EvaluateForOverflow returns nothing so I don't know how to check whether there was overflow or not.
Uploaded alternative patch which passes test suite and has no double warning issue.
lib/Sema/SemaType.cpp | ||
---|---|---|
2232 ↗ | (On Diff #167858) | What's up with this statement? Why is it needed? This won't handle overflows for unary expression for example. |
lib/Sema/SemaType.cpp | ||
---|---|---|
2232 ↗ | (On Diff #167858) | Ok, I should use Sema::CheckForIntOverflow But anyway, CheckForIntOverflow does not care about UnaryOperator either currently :) |
lib/Sema/SemaType.cpp | ||
---|---|---|
2232 ↗ | (On Diff #167858) | Anyway, the negative array size is handled a few lines above. |
The array size is still evaluated twice. Try to incorporate the check in Sema::VerifyIntegerConstantExpression.
Thanks!
But I think I need to change EvaluateForOverflow method to return bool to indicate overflowing.
Nah, you don't even need to call EvaluateForOverflow I believe. :) Have a look overflow evaluation is done.
Well..
if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) { if (Result) { *Result = E->EvaluateKnownConstInt(Context); // here
}
and
char a[2147483642 * 3];
Result->getBitWidth() reports 32. I don't know how to detect there if overflow or not :/ I have already spent some time to solve this, but still no good solution. Possibly I would abandon this patch.
lib/Sema/SemaType.cpp | ||
---|---|---|
2231 ↗ | (On Diff #167858) | This is still evaluating the expression twice. To avoid that, you need to change the existing code that calls the evaluator to ask it to produce overflow warnings as a side-effect rather than adding a new call to CheckForIntOverflow. |
But see Richard's comment: https://reviews.llvm.org/D52750#125175 so I am not sure :/
That's fine :) btw, thanks for review comments!
Hopefully, this solution would be now acceptable :)
Yeah, this looks better.
Though this really highlights that the "warn on undefined behavior" behavior of the constant evaluator should be orthogonal to the evaluation mode... we don't really need/want to evaluate past a side-effect or non-constant expression here.