================
@@ -6177,6 +6212,102 @@ TEST(TransferTest, ConditionalOperatorLocation) {
       });
 }
 
+TEST(TransferTest, ConditionalOperatorValuesTested) {
+  // Even though the LHS and the RHS of the conditional operator have different
+  // StorageLocations, we get constraints from the condition that the values
+  // must be equal to B1 for JoinDifferentIsB1, or B2 for JoinDifferentIsB2.
+  std::string Code = R"(
+    void target(bool B1, bool B2) {
+      bool JoinDifferentIsB1 = (B1 == B2) ? B2 : B1;
+      bool JoinDifferentIsB2 = (B1 == B2) ? B1 : B2;
+      // [[p]]
+    }
+  )";
+  runDataflow(
+      Code,
+      [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+         ASTContext &ASTCtx) {
+        Environment Env = getEnvironmentAtAnnotation(Results, "p").fork();
+
+        auto &B1 = getValueForDecl<BoolValue>(ASTCtx, Env, "B1");
+        auto &B2 = getValueForDecl<BoolValue>(ASTCtx, Env, "B2");
+        auto &JoinDifferentIsB1 =
+            getValueForDecl<BoolValue>(ASTCtx, Env, "JoinDifferentIsB1");
+        auto &JoinDifferentIsB2 =
+            getValueForDecl<BoolValue>(ASTCtx, Env, "JoinDifferentIsB2");
+
+        const Formula &JoinDifferentIsB1EqB1 =
+            Env.arena().makeEquals(JoinDifferentIsB1.formula(), B1.formula());
+        EXPECT_TRUE(Env.allows(JoinDifferentIsB1EqB1));
+        EXPECT_TRUE(Env.proves(JoinDifferentIsB1EqB1));
+
+        const Formula &JoinDifferentIsB2EqB2 =
+            Env.arena().makeEquals(JoinDifferentIsB2.formula(), B2.formula());
+        EXPECT_TRUE(Env.allows(JoinDifferentIsB2EqB2));
+        EXPECT_TRUE(Env.proves(JoinDifferentIsB2EqB2));
+      });
+}
+
+TEST(TransferTest, ConditionalOperatorLocationUpdatedAfter) {
+  // We don't currently model a Conditional Operator with an LValue result
+  // as having aliases to the LHS and RHS (if it isn't just the same LValue
+  // on both sides). We also don't model that the update "may" happen
+  // (a weak update). So, we don't consider the LHS and RHS as being weakly
+  // updated at [[after_diff]].
+  std::string Code = R"(
+    void target(bool Cond, bool B1, bool B2) {
+      (void)0;
+      // [[before_same]]
+      (Cond ? B1 : B1) = !B1;
+      // [[after_same]]
+      (Cond ? B1 : B2) = !B1;
+      // [[after_diff]]
+    }
+  )";
+  runDataflow(
+      Code,
+      [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+         ASTContext &ASTCtx) {
+        Environment BeforeSameEnv =
+            getEnvironmentAtAnnotation(Results, "before_same").fork();
+        Environment AfterSameEnv =
+            getEnvironmentAtAnnotation(Results, "after_same").fork();
+        Environment AfterDiffEnv =
+            getEnvironmentAtAnnotation(Results, "after_diff").fork();
+
+        auto &BeforeSameB1 =
+            getValueForDecl<BoolValue>(ASTCtx, BeforeSameEnv, "B1");
+        auto &AfterSameB1 =
+            getValueForDecl<BoolValue>(ASTCtx, AfterSameEnv, "B1");
+        auto &AfterDiffB1 =
+            getValueForDecl<BoolValue>(ASTCtx, AfterDiffEnv, "B1");
+
+        EXPECT_NE(&BeforeSameB1, &AfterSameB1);
+        EXPECT_NE(&BeforeSameB1, &AfterDiffB1);
+        // FIXME: The formula for AfterSameB1 should be different from
+        // AfterDiffB1 to reflect that B1 may be updated.
+        EXPECT_EQ(&AfterSameB1, &AfterDiffB1);
+
+        // The value of B1 is definitely different from before_same vs
+        // after_same.
+        const Formula &B1ChangedForSame =
+            AfterSameEnv.arena().makeNot(AfterSameEnv.arena().makeEquals(
+                AfterSameB1.formula(), BeforeSameB1.formula()));
+        EXPECT_TRUE(AfterSameEnv.allows(B1ChangedForSame));
+        EXPECT_TRUE(AfterSameEnv.proves(B1ChangedForSame));
+
+        // FIXME: It should be possible that B1 *may* be updated, so it may be
----------------
bazuzi wrote:

It would more clear to me that only the `allows` expectation needs to change if 
this comment were moved to precede that line, after this decl.

https://github.com/llvm/llvm-project/pull/168994
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to