[PATCH] D52133: [analyzer] A testing facility for testing relationships between symbols.
This revision was automatically updated to reflect the committed changes. Closed by commit rL343048: [analyzer] Add a testing facility for testing relationships between symbols. (authored by dergachev, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D52133?vs=165810&id=167029#toc Repository: rL LLVM https://reviews.llvm.org/D52133 Files: cfe/trunk/docs/analyzer/DebugChecks.rst cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp cfe/trunk/test/Analysis/expr-inspection.cpp cfe/trunk/test/Analysis/svalbuilder-rearrange-comparisons.c Index: cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp === --- cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp @@ -43,6 +43,8 @@ void analyzerPrintState(const CallExpr *CE, CheckerContext &C) const; void analyzerGetExtent(const CallExpr *CE, CheckerContext &C) const; void analyzerHashDump(const CallExpr *CE, CheckerContext &C) const; + void analyzerDenote(const CallExpr *CE, CheckerContext &C) const; + void analyzerExpress(const CallExpr *CE, CheckerContext &C) const; typedef void (ExprInspectionChecker::*FnCheck)(const CallExpr *, CheckerContext &C) const; @@ -60,6 +62,7 @@ } REGISTER_SET_WITH_PROGRAMSTATE(MarkedSymbols, SymbolRef) +REGISTER_MAP_WITH_PROGRAMSTATE(DenotedSymbols, SymbolRef, const StringLiteral *) bool ExprInspectionChecker::evalCall(const CallExpr *CE, CheckerContext &C) const { @@ -82,6 +85,8 @@ .Case("clang_analyzer_numTimesReached", &ExprInspectionChecker::analyzerNumTimesReached) .Case("clang_analyzer_hashDump", &ExprInspectionChecker::analyzerHashDump) +.Case("clang_analyzer_denote", &ExprInspectionChecker::analyzerDenote) +.Case("clang_analyzer_express", &ExprInspectionChecker::analyzerExpress) .Default(nullptr); if (!Handler) @@ -264,6 +269,13 @@ N = BugNode; State = State->remove(Sym); } + + for (auto I : State->get()) { +SymbolRef Sym = I.first; +if (!SymReaper.isLive(Sym)) + State = State->remove(Sym); + } + C.addTransition(State, N); } @@ -295,6 +307,92 @@ reportBug(HashContent, C); } +void ExprInspectionChecker::analyzerDenote(const CallExpr *CE, + CheckerContext &C) const { + if (CE->getNumArgs() < 2) { +reportBug("clang_analyzer_denote() requires a symbol and a string literal", + C); +return; + } + + SymbolRef Sym = C.getSVal(CE->getArg(0)).getAsSymbol(); + if (!Sym) { +reportBug("Not a symbol", C); +return; + } + + if (!isa(Sym)) { +reportBug("Not an atomic symbol", C); +return; + } + + const auto *E = dyn_cast(CE->getArg(1)->IgnoreParenCasts()); + if (!E) { +reportBug("Not a string literal", C); +return; + } + + ProgramStateRef State = C.getState(); + + C.addTransition(C.getState()->set(Sym, E)); +} + +class SymbolExpressor +: public SymExprVisitor> { + ProgramStateRef State; + +public: + SymbolExpressor(ProgramStateRef State) : State(State) {} + + Optional VisitSymExpr(const SymExpr *S) { +if (const StringLiteral *const *SLPtr = State->get(S)) { + const StringLiteral *SL = *SLPtr; + return std::string(SL->getBytes()); +} +return None; + } + + Optional VisitSymIntExpr(const SymIntExpr *S) { +if (auto Str = Visit(S->getLHS())) + return (*Str + " " + BinaryOperator::getOpcodeStr(S->getOpcode()) + " " + + std::to_string(S->getRHS().getLimitedValue()) + + (S->getRHS().isUnsigned() ? "U" : "")) + .str(); +return None; + } + + Optional VisitSymSymExpr(const SymSymExpr *S) { +if (auto Str1 = Visit(S->getLHS())) + if (auto Str2 = Visit(S->getRHS())) +return (*Str1 + " " + BinaryOperator::getOpcodeStr(S->getOpcode()) + +" " + *Str2).str(); +return None; + } +}; + +void ExprInspectionChecker::analyzerExpress(const CallExpr *CE, +CheckerContext &C) const { + if (CE->getNumArgs() == 0) { +reportBug("clang_analyzer_express() requires a symbol", C); +return; + } + + SymbolRef Sym = C.getSVal(CE->getArg(0)).getAsSymbol(); + if (!Sym) { +reportBug("Not a symbol", C); +return; + } + + SymbolExpressor V(C.getState()); + auto Str = V.Visit(Sym); + if (!Str) { +reportBug("Unable to express", C); +return; + } + + reportBug(*Str, C); +} + void ento::registerExprInspectionChecker(CheckerManager &Mgr) { Mgr.registerChecker(); } Index: cfe/trunk/docs/analyzer/DebugChecks.rst === --- cfe/trunk/docs/analyzer/DebugChecks.rst +++ cfe/trunk/docs/analyzer/DebugChecks.rst @@ -255,6 +25
[PATCH] D52133: [analyzer] A testing facility for testing relationships between symbols.
This revision was automatically updated to reflect the committed changes. Closed by commit rC343048: [analyzer] Add a testing facility for testing relationships between symbols. (authored by dergachev, committed by ). Repository: rL LLVM https://reviews.llvm.org/D52133 Files: docs/analyzer/DebugChecks.rst lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp test/Analysis/expr-inspection.cpp test/Analysis/svalbuilder-rearrange-comparisons.c Index: docs/analyzer/DebugChecks.rst === --- docs/analyzer/DebugChecks.rst +++ docs/analyzer/DebugChecks.rst @@ -255,6 +255,23 @@ clang_analyzer_hashDump(x); // expected-warning{{hashed string for x}} } +- ``void clang_analyzer_denote(int, const char *);`` + + Denotes symbols with strings. A subsequent call to clang_analyzer_express() + will expresses another symbol in terms of these string. Useful for testing + relationships between different symbols. + + Example usage:: + +void foo(int x) { + clang_analyzer_denote(x, "$x"); + clang_analyzer_express(x + 1); // expected-warning{{$x + 1}} +} + +- ``void clang_analyzer_express(int);`` + + See clang_analyzer_denote(). + Statistics == Index: test/Analysis/svalbuilder-rearrange-comparisons.c === --- test/Analysis/svalbuilder-rearrange-comparisons.c +++ test/Analysis/svalbuilder-rearrange-comparisons.c @@ -1,10 +1,8 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection,core.builtin -analyzer-config aggressive-binary-operation-simplification=true -verify -analyzer-config eagerly-assume=false %s -// Temporary xfailing, as debug printing functionality has changed. -// XFAIL: * - -void clang_analyzer_dump(int x); void clang_analyzer_eval(int x); +void clang_analyzer_denote(int x, const char *literal); +void clang_analyzer_express(int x); void exit(int); @@ -29,907 +27,951 @@ void compare_different_symbol_equal() { int x = f(), y = f(); - clang_analyzer_dump(x); // expected-warning{{conj_$2{int}}} - clang_analyzer_dump(y); // expected-warning{{conj_$9{int}}} - clang_analyzer_dump(x == y); - // expected-warning@-1{{((conj_$2{int}) - (conj_$9{int})) == 0}} + clang_analyzer_denote(x, "$x"); + clang_analyzer_denote(y, "$y"); + clang_analyzer_express(x == y); // expected-warning {{$x - $y == 0}} } void compare_different_symbol_plus_left_int_equal() { - int x = f()+1, y = f(); - clang_analyzer_dump(x); // expected-warning{{(conj_$2{int}) + 1}} - clang_analyzer_dump(y); // expected-warning{{conj_$9{int}}} - clang_analyzer_dump(x == y); - // expected-warning@-1{{((conj_$9{int}) - (conj_$2{int})) == 1}} + int x = f(), y = f(); + clang_analyzer_denote(x, "$x"); + clang_analyzer_denote(y, "$y"); + x += 1; + clang_analyzer_express(x == y); // expected-warning {{$y - $x == 1}} } void compare_different_symbol_minus_left_int_equal() { - int x = f()-1, y = f(); - clang_analyzer_dump(x); // expected-warning{{(conj_$2{int}) - 1}} - clang_analyzer_dump(y); // expected-warning{{conj_$9{int}}} - clang_analyzer_dump(x == y); - // expected-warning@-1{{((conj_$2{int}) - (conj_$9{int})) == 1}} + int x = f(), y = f(); + clang_analyzer_denote(x, "$x"); + clang_analyzer_denote(y, "$y"); + x -= 1; + clang_analyzer_express(x == y); // expected-warning {{$x - $y == 1}} } void compare_different_symbol_plus_right_int_equal() { - int x = f(), y = f()+2; - clang_analyzer_dump(x); // expected-warning{{conj_$2{int}}} - clang_analyzer_dump(y); // expected-warning{{(conj_$9{int}) + 2}} - clang_analyzer_dump(x == y); - // expected-warning@-1{{((conj_$2{int}) - (conj_$9{int})) == 2}} + int x = f(), y = f(); + clang_analyzer_denote(x, "$x"); + clang_analyzer_denote(y, "$y"); + y += 2; + clang_analyzer_express(y); // expected-warning {{$y + 2}} + clang_analyzer_express(x == y); // expected-warning {{$x - $y == 2}} } void compare_different_symbol_minus_right_int_equal() { - int x = f(), y = f()-2; - clang_analyzer_dump(x); // expected-warning{{conj_$2{int}}} - clang_analyzer_dump(y); // expected-warning{{(conj_$9{int}) - 2}} - clang_analyzer_dump(x == y); - // expected-warning@-1{{((conj_$9{int}) - (conj_$2{int})) == 2}} + int x = f(), y = f(); + clang_analyzer_denote(x, "$x"); + clang_analyzer_denote(y, "$y"); + y -= 2; + clang_analyzer_express(y); // expected-warning {{$y - 2}} + clang_analyzer_express(x == y); // expected-warning {{$y - $x == 2}} } void compare_different_symbol_plus_left_plus_right_int_equal() { - int x = f()+2, y = f()+1; - clang_analyzer_dump(x); // expected-warning{{(conj_$2{int}) + 2}} - clang_analyzer_dump(y); // expected-warning{{(conj_$9{int}) + 1}} - clang_analyzer_dump(x == y); - // expected-warning@-1{{((conj_$9{int}) - (conj_$2{int})) == 1}} + int x = f(), y = f(); + clang_analyzer_denote(x, "$x"); + clang_analyzer_denote(y, "$y"); + x += 2; + y +=
[PATCH] D52133: [analyzer] A testing facility for testing relationships between symbols.
george.karpenkov accepted this revision. george.karpenkov added inline comments. This revision is now accepted and ready to land. Comment at: lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp:273 + + for (auto I : State->get()) { +SymbolRef Sym = I.first; Sidenote: this code fragment is so common I wonder whether we should have a helper/facility for that. https://reviews.llvm.org/D52133 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D52133: [analyzer] A testing facility for testing relationships between symbols.
NoQ added a comment. Mm, i mean, that reason as good as well. https://reviews.llvm.org/D52133 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D52133: [analyzer] A testing facility for testing relationships between symbols.
NoQ marked an inline comment as done. NoQ added a comment. In https://reviews.llvm.org/D52133#1237312, @george.karpenkov wrote: > @NoQ Actually I agree with @baloghadamsoftware that it makes sense to have a > separate test, as this functionality should be tested regardless of > svalbuilder-rearrange-comparisons existence. That's why i added a spearate test. https://reviews.llvm.org/D52133 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D52133: [analyzer] A testing facility for testing relationships between symbols.
george.karpenkov added a comment. @NoQ Actually I agree with @baloghadamsoftware that it makes sense to have a separate test, as this functionality should be tested regardless of svalbuilder-rearrange-comparisons existence. https://reviews.llvm.org/D52133 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D52133: [analyzer] A testing facility for testing relationships between symbols.
NoQ marked an inline comment as done. NoQ added a comment. > Should not it we have its own test in `expr-inspection.c`? This isn't usually necessary when we're testing all code paths anyway, but i guess it's worth it to test our sanity-check warnings. Comment at: lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp:65 REGISTER_SET_WITH_PROGRAMSTATE(MarkedSymbols, SymbolRef) +REGISTER_MAP_WITH_PROGRAMSTATE(DenotedSymbols, SymbolRef, const void *) baloghadamsoftware wrote: > Why const `void *`? Whoops, i was incorrectly recalling that it doesn't work because the respective type trait structures aren't defined for non-void pointers, but that must have been some other data structure. https://reviews.llvm.org/D52133 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D52133: [analyzer] A testing facility for testing relationships between symbols.
NoQ updated this revision to Diff 165810. NoQ added a comment. Address comments. Add more sanity checks and test them. https://reviews.llvm.org/D52133 Files: docs/analyzer/DebugChecks.rst lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp test/Analysis/expr-inspection.cpp test/Analysis/svalbuilder-rearrange-comparisons.c Index: test/Analysis/svalbuilder-rearrange-comparisons.c === --- test/Analysis/svalbuilder-rearrange-comparisons.c +++ test/Analysis/svalbuilder-rearrange-comparisons.c @@ -1,10 +1,8 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection,core.builtin -analyzer-config aggressive-binary-operation-simplification=true -verify -analyzer-config eagerly-assume=false %s -// Temporary xfailing, as debug printing functionality has changed. -// XFAIL: * - -void clang_analyzer_dump(int x); void clang_analyzer_eval(int x); +void clang_analyzer_denote(int x, const char *literal); +void clang_analyzer_express(int x); void exit(int); @@ -29,907 +27,951 @@ void compare_different_symbol_equal() { int x = f(), y = f(); - clang_analyzer_dump(x); // expected-warning{{conj_$2{int}}} - clang_analyzer_dump(y); // expected-warning{{conj_$9{int}}} - clang_analyzer_dump(x == y); - // expected-warning@-1{{((conj_$2{int}) - (conj_$9{int})) == 0}} + clang_analyzer_denote(x, "$x"); + clang_analyzer_denote(y, "$y"); + clang_analyzer_express(x == y); // expected-warning {{$x - $y == 0}} } void compare_different_symbol_plus_left_int_equal() { - int x = f()+1, y = f(); - clang_analyzer_dump(x); // expected-warning{{(conj_$2{int}) + 1}} - clang_analyzer_dump(y); // expected-warning{{conj_$9{int}}} - clang_analyzer_dump(x == y); - // expected-warning@-1{{((conj_$9{int}) - (conj_$2{int})) == 1}} + int x = f(), y = f(); + clang_analyzer_denote(x, "$x"); + clang_analyzer_denote(y, "$y"); + x += 1; + clang_analyzer_express(x == y); // expected-warning {{$y - $x == 1}} } void compare_different_symbol_minus_left_int_equal() { - int x = f()-1, y = f(); - clang_analyzer_dump(x); // expected-warning{{(conj_$2{int}) - 1}} - clang_analyzer_dump(y); // expected-warning{{conj_$9{int}}} - clang_analyzer_dump(x == y); - // expected-warning@-1{{((conj_$2{int}) - (conj_$9{int})) == 1}} + int x = f(), y = f(); + clang_analyzer_denote(x, "$x"); + clang_analyzer_denote(y, "$y"); + x -= 1; + clang_analyzer_express(x == y); // expected-warning {{$x - $y == 1}} } void compare_different_symbol_plus_right_int_equal() { - int x = f(), y = f()+2; - clang_analyzer_dump(x); // expected-warning{{conj_$2{int}}} - clang_analyzer_dump(y); // expected-warning{{(conj_$9{int}) + 2}} - clang_analyzer_dump(x == y); - // expected-warning@-1{{((conj_$2{int}) - (conj_$9{int})) == 2}} + int x = f(), y = f(); + clang_analyzer_denote(x, "$x"); + clang_analyzer_denote(y, "$y"); + y += 2; + clang_analyzer_express(y); // expected-warning {{$y + 2}} + clang_analyzer_express(x == y); // expected-warning {{$x - $y == 2}} } void compare_different_symbol_minus_right_int_equal() { - int x = f(), y = f()-2; - clang_analyzer_dump(x); // expected-warning{{conj_$2{int}}} - clang_analyzer_dump(y); // expected-warning{{(conj_$9{int}) - 2}} - clang_analyzer_dump(x == y); - // expected-warning@-1{{((conj_$9{int}) - (conj_$2{int})) == 2}} + int x = f(), y = f(); + clang_analyzer_denote(x, "$x"); + clang_analyzer_denote(y, "$y"); + y -= 2; + clang_analyzer_express(y); // expected-warning {{$y - 2}} + clang_analyzer_express(x == y); // expected-warning {{$y - $x == 2}} } void compare_different_symbol_plus_left_plus_right_int_equal() { - int x = f()+2, y = f()+1; - clang_analyzer_dump(x); // expected-warning{{(conj_$2{int}) + 2}} - clang_analyzer_dump(y); // expected-warning{{(conj_$9{int}) + 1}} - clang_analyzer_dump(x == y); - // expected-warning@-1{{((conj_$9{int}) - (conj_$2{int})) == 1}} + int x = f(), y = f(); + clang_analyzer_denote(x, "$x"); + clang_analyzer_denote(y, "$y"); + x += 2; + y += 1; + clang_analyzer_express(x); // expected-warning {{$x + 2}} + clang_analyzer_express(y); // expected-warning {{$y + 1}} + clang_analyzer_express(x == y); // expected-warning {{$y - $x == 1}} } void compare_different_symbol_plus_left_minus_right_int_equal() { - int x = f()+2, y = f()-1; - clang_analyzer_dump(x); // expected-warning{{(conj_$2{int}) + 2}} - clang_analyzer_dump(y); // expected-warning{{(conj_$9{int}) - 1}} - clang_analyzer_dump(x == y); - // expected-warning@-1{{((conj_$9{int}) - (conj_$2{int})) == 3}} + int x = f(), y = f(); + clang_analyzer_denote(x, "$x"); + clang_analyzer_denote(y, "$y"); + x += 2; + y -= 1; + clang_analyzer_express(x); // expected-warning {{$x + 2}} + clang_analyzer_express(y); // expected-warning {{$y - 1}} + clang_analyzer_express(x == y); // expected-warning {{$y - $x == 3}} } void compare_different_symbol_minus_left_plus_right_int_equal() { - i
[PATCH] D52133: [analyzer] A testing facility for testing relationships between symbols.
baloghadamsoftware added a comment. This looks better than using the "raw" dumps. Should not it we have its own test in `expr-inspection.c`? Comment at: lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp:65 REGISTER_SET_WITH_PROGRAMSTATE(MarkedSymbols, SymbolRef) +REGISTER_MAP_WITH_PROGRAMSTATE(DenotedSymbols, SymbolRef, const void *) Why const `void *`? Repository: rC Clang https://reviews.llvm.org/D52133 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D52133: [analyzer] A testing facility for testing relationships between symbols.
NoQ created this revision. NoQ added reviewers: dcoughlin, xazax.hun, a.sidorin, george.karpenkov, szepet, rnkovacs, baloghadamsoftware. Herald added subscribers: cfe-commits, Szelethus, jfb, mikhail.ramalho. A test introduced in https://reviews.llvm.org/rC329780 was disabled in https://reviews.llvm.org/rC342317 for the reason explained in https://reviews.llvm.org/D41938?id=130403#inline-371070 - tests shouldn't test dump infrastructure when all they care about is how symbols relate to each other. Add a new feature to ExprInspection: `clang_analyzer_denote()` and `clang_analyzer_explain()`. The former adds a notation to a symbol, the latter expresses another symbol in terms of previously denoted symbols. It's currently a bit wonky - doesn't print parentheses and only supports denoting atomic symbols. But it's even more readable that way. I also noticed that an important use case was omitted in these tests. Namely, tests for unsigned integer rearrangement are done with signed-type symbols stored in unsigned variables and we also need to test unsigned symbols stored in unsigned variables (and ideally also unsigned symbols stored in signed variables). Repository: rC Clang https://reviews.llvm.org/D52133 Files: docs/analyzer/DebugChecks.rst lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp test/Analysis/svalbuilder-rearrange-comparisons.c Index: test/Analysis/svalbuilder-rearrange-comparisons.c === --- test/Analysis/svalbuilder-rearrange-comparisons.c +++ test/Analysis/svalbuilder-rearrange-comparisons.c @@ -1,10 +1,8 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection,core.builtin -analyzer-config aggressive-binary-operation-simplification=true -verify -analyzer-config eagerly-assume=false %s -// Temporary xfailing, as debug printing functionality has changed. -// XFAIL: * - -void clang_analyzer_dump(int x); void clang_analyzer_eval(int x); +void clang_analyzer_denote(int x, const char *literal); +void clang_analyzer_express(int x); void exit(int); @@ -29,907 +27,951 @@ void compare_different_symbol_equal() { int x = f(), y = f(); - clang_analyzer_dump(x); // expected-warning{{conj_$2{int}}} - clang_analyzer_dump(y); // expected-warning{{conj_$9{int}}} - clang_analyzer_dump(x == y); - // expected-warning@-1{{((conj_$2{int}) - (conj_$9{int})) == 0}} + clang_analyzer_denote(x, "$x"); + clang_analyzer_denote(y, "$y"); + clang_analyzer_express(x == y); // expected-warning {{$x - $y == 0}} } void compare_different_symbol_plus_left_int_equal() { - int x = f()+1, y = f(); - clang_analyzer_dump(x); // expected-warning{{(conj_$2{int}) + 1}} - clang_analyzer_dump(y); // expected-warning{{conj_$9{int}}} - clang_analyzer_dump(x == y); - // expected-warning@-1{{((conj_$9{int}) - (conj_$2{int})) == 1}} + int x = f(), y = f(); + clang_analyzer_denote(x, "$x"); + clang_analyzer_denote(y, "$y"); + x += 1; + clang_analyzer_express(x == y); // expected-warning {{$y - $x == 1}} } void compare_different_symbol_minus_left_int_equal() { - int x = f()-1, y = f(); - clang_analyzer_dump(x); // expected-warning{{(conj_$2{int}) - 1}} - clang_analyzer_dump(y); // expected-warning{{conj_$9{int}}} - clang_analyzer_dump(x == y); - // expected-warning@-1{{((conj_$2{int}) - (conj_$9{int})) == 1}} + int x = f(), y = f(); + clang_analyzer_denote(x, "$x"); + clang_analyzer_denote(y, "$y"); + x -= 1; + clang_analyzer_express(x == y); // expected-warning {{$x - $y == 1}} } void compare_different_symbol_plus_right_int_equal() { - int x = f(), y = f()+2; - clang_analyzer_dump(x); // expected-warning{{conj_$2{int}}} - clang_analyzer_dump(y); // expected-warning{{(conj_$9{int}) + 2}} - clang_analyzer_dump(x == y); - // expected-warning@-1{{((conj_$2{int}) - (conj_$9{int})) == 2}} + int x = f(), y = f(); + clang_analyzer_denote(x, "$x"); + clang_analyzer_denote(y, "$y"); + y += 2; + clang_analyzer_express(y); // expected-warning {{$y + 2}} + clang_analyzer_express(x == y); // expected-warning {{$x - $y == 2}} } void compare_different_symbol_minus_right_int_equal() { - int x = f(), y = f()-2; - clang_analyzer_dump(x); // expected-warning{{conj_$2{int}}} - clang_analyzer_dump(y); // expected-warning{{(conj_$9{int}) - 2}} - clang_analyzer_dump(x == y); - // expected-warning@-1{{((conj_$9{int}) - (conj_$2{int})) == 2}} + int x = f(), y = f(); + clang_analyzer_denote(x, "$x"); + clang_analyzer_denote(y, "$y"); + y -= 2; + clang_analyzer_express(y); // expected-warning {{$y - 2}} + clang_analyzer_express(x == y); // expected-warning {{$y - $x == 2}} } void compare_different_symbol_plus_left_plus_right_int_equal() { - int x = f()+2, y = f()+1; - clang_analyzer_dump(x); // expected-warning{{(conj_$2{int}) + 2}} - clang_analyzer_dump(y); // expected-warning{{(conj_$9{int}) + 1}} - clang_analyzer_dump(x == y); - // expected-warning@-1{{((conj_$9{int}) - (conj_$2{