Page MenuHomePhabricator

Fix -Winteger-overflow to diagnose regardless of the top-level syntactic form.

Authored by rsmith on Mar 18 2021, 6:49 PM.



Previously -Winteger-overflow did not do any checking of expressions
whose top-level syntactic form wasn't one of a small list of special
cases. This meant that the warning would appear and disappear depending
on enclosing syntax.

Additionally, if constant evaluation hit a case that it didn't
understand, it would often bail out without visiting subexpressions, so
we wouldn't see warnings on overflow in subexpressions depending on the
form of intervening expressions.

We now walk all evaluated subexpressions of a particular expression when
checking for overflow, and evaluate subtrees rooted on each operation
that might overflow. If such evaluation hits an unevaluatable
subexpression, we switch back to walking the AST looking for
subexpressions to evaluate.

The extra evaluation here also exposed an issue where casts between
complex and fixed-point types would create bogus AST nodes using
CK_IntegralCast, which would lead to the constant evaluator asserting.
That's fixed here too.

Diff Detail

Unit TestsFailed

1,890 msx64 debian > libarcher.races::lock-unrelated.c
Script: -- : 'RUN: at line 13'; /mnt/disks/ssd0/agent/llvm-project/build/./bin/clang -fopenmp -pthread -fno-experimental-isel -g -O1 -fsanitize=thread -I /mnt/disks/ssd0/agent/llvm-project/openmp/tools/archer/tests -I /mnt/disks/ssd0/agent/llvm-project/build/projects/openmp/runtime/src -L /mnt/disks/ssd0/agent/llvm-project/build/lib -Wl,-rpath,/mnt/disks/ssd0/agent/llvm-project/build/lib /mnt/disks/ssd0/agent/llvm-project/openmp/tools/archer/tests/races/lock-unrelated.c -o /mnt/disks/ssd0/agent/llvm-project/build/projects/openmp/tools/archer/tests/races/Output/lock-unrelated.c.tmp -latomic && env TSAN_OPTIONS='ignore_noninstrumented_modules=0:ignore_noninstrumented_modules=1' /mnt/disks/ssd0/agent/llvm-project/openmp/tools/archer/tests/deflake.bash /mnt/disks/ssd0/agent/llvm-project/build/projects/openmp/tools/archer/tests/races/Output/lock-unrelated.c.tmp 2>&1 | tee /mnt/disks/ssd0/agent/llvm-project/build/projects/openmp/tools/archer/tests/races/Output/lock-unrelated.c.tmp.log | /mnt/disks/ssd0/agent/llvm-project/build/./bin/FileCheck /mnt/disks/ssd0/agent/llvm-project/openmp/tools/archer/tests/races/lock-unrelated.c

Event Timeline

rsmith requested review of this revision.Mar 18 2021, 6:49 PM
rsmith created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptMar 18 2021, 6:49 PM

Looks good to me. Have a few clarification questions.


I'm not entirely sure but it can be useful to make it explicit in the comment the method doesn't deal with all the subexpressions recursively. Not convinced it is useful because don't have a good wording and you can get that information from the short method implementation. It is possible my suggestion is caused by checking the patch top-to-bottom without seeing how mightWarnOnUndefinedBehavior is used first, but that's not how developers would read the code later.


Just to confirm my understanding. There is no point in checking keepEvaluatingAfterFailure here because we are not short-circuiting anymore but can evaluate the expression in VisitExpr(UO). And we still check keepEvaluatingAfterFailure in SubexpressionVisitor::Run in EvaluateForDiagnostics.


What is the purpose of these changes to return CK_Dependent? Tests are passing without them and it's not obvious to me why do you need to change CK_IntegralCast to CK_Dependent.

rsmith added inline comments.Apr 1 2021, 5:55 PM

Would renaming this to something like shouldEvaluateForUndefinedBehaviorChecks help? That still doesn't completely capture the non-recursive nature. I think improving the comment is a good idea regardless.


Yes, exactly.


It shouldn't matter what we return, because the caller should always bail out and ignore our return value if Src is set to an invalid expression. But in principle, CK_IntegralCast is wrong, because this situation doesn't meet the constraints for an integral cast. We use "dependent" to mean not only "dependent on a C++ template parameter" but also "dependent on an error", so that seemed like the least wrong cast kind for this situation.

vsapsai accepted this revision.Apr 6 2021, 7:13 PM
vsapsai added inline comments.

Don't have strong feelings about shouldEvaluateForUndefinedBehaviorChecks. Both shouldEvaluateForUndefinedBehaviorChecks and mightWarnOnUndefinedBehavior convey enough intention and actual implementation is fairly easy to understand. And information at the call site in ShouldEvaluate seems to be sufficient for intention and implementation purposes.

Also considered inlining mightWarnOnUndefinedBehavior but it doesn't look like a better alternative.

It's up to you if you want to tweak it further, I don't have good suggestions.


Thanks for the explanation. "dependent on an error" is an important piece of information and now it makes more sense.

This revision is now accepted and ready to land.Apr 6 2021, 7:13 PM