+2020-07-30  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>
+
+       * breakpoint.c (set_breakpoint_condition): Update the condition
+       expressions after checking that the input condition string parses
+       successfully and does not contain junk at the end.
+
 2020-07-30  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>
 
        * breakpoint.c (set_breakpoint_condition): Update the
 
 set_breakpoint_condition (struct breakpoint *b, const char *exp,
                          int from_tty)
 {
-  if (is_watchpoint (b))
-    {
-      struct watchpoint *w = (struct watchpoint *) b;
-
-      w->cond_exp.reset ();
-    }
-  else
+  if (*exp == 0)
     {
-      struct bp_location *loc;
+      xfree (b->cond_string);
+      b->cond_string = nullptr;
 
-      for (loc = b->loc; loc; loc = loc->next)
+      if (is_watchpoint (b))
        {
-         loc->cond.reset ();
+         struct watchpoint *w = (struct watchpoint *) b;
 
-         /* No need to free the condition agent expression
-            bytecode (if we have one).  We will handle this
-            when we go through update_global_location_list.  */
+         w->cond_exp.reset ();
        }
-    }
+      else
+       {
+         struct bp_location *loc;
 
-  if (*exp == 0)
-    {
-      xfree (b->cond_string);
-      b->cond_string = nullptr;
+         for (loc = b->loc; loc; loc = loc->next)
+           {
+             loc->cond.reset ();
+
+             /* No need to free the condition agent expression
+                bytecode (if we have one).  We will handle this
+                when we go through update_global_location_list.  */
+           }
+       }
 
       if (from_tty)
        printf_filtered (_("Breakpoint %d now unconditional.\n"), b->number);
 
          innermost_block_tracker tracker;
          arg = exp;
-         w->cond_exp = parse_exp_1 (&arg, 0, 0, 0, &tracker);
+         expression_up new_exp = parse_exp_1 (&arg, 0, 0, 0, &tracker);
          if (*arg)
            error (_("Junk at end of expression"));
+         w->cond_exp = std::move (new_exp);
          w->cond_exp_valid_block = tracker.block ();
        }
       else
        {
          struct bp_location *loc;
 
+         /* Parse and set condition expressions.  We make two passes.
+            In the first, we parse the condition string to see if it
+            is valid in all locations.  If so, the condition would be
+            accepted.  So we go ahead and set the locations'
+            conditions.  In case a failing case is found, we throw
+            the error and the condition string will be rejected.
+            This two-pass approach is taken to avoid setting the
+            state of locations in case of a reject.  */
+         for (loc = b->loc; loc; loc = loc->next)
+           {
+             arg = exp;
+             parse_exp_1 (&arg, loc->address,
+                          block_for_pc (loc->address), 0);
+             if (*arg != 0)
+               error (_("Junk at end of expression"));
+           }
+
+         /* If we reach here, the condition is valid at all locations.  */
          for (loc = b->loc; loc; loc = loc->next)
            {
              arg = exp;
              loc->cond =
                parse_exp_1 (&arg, loc->address,
                             block_for_pc (loc->address), 0);
-             if (*arg)
-               error (_("Junk at end of expression"));
            }
        }
 
 
+2020-07-30  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>
+
+       * gdb.base/condbreak-bad.exp: Extend the test with scenarios
+       that attempt to overwrite an existing condition with a condition
+       that fails parsing and also with a condition that parses fine
+       but contains junk at the end.
+
 2020-07-30  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>
 
        * gdb.base/condbreak-bad.c: New test.
 
         "${decimal}${fill}breakpoint${fill}keep y${fill}:${bp_location}"] \
     "breakpoint is unconditional"
 
+# Now define a valid condition.  Attempt to override that with a 'bad'
+# condition again.  The condition should be preserved.
+with_test_prefix "with run" {
+    gdb_test_no_output "cond $bpnum a == 10"
+
+    gdb_test "cond $bpnum gibberish" \
+       "No symbol \"gibberish\" in current context." \
+       "attempt a bad condition"
+
+    gdb_test "info break" \
+       [multi_line \
+            "Num${fill}What" \
+            "${decimal}${fill}breakpoint${fill}keep y${fill}:${bp_location}" \
+            "${fill}stop only if a == 10${fill}"] \
+       "breakpoint condition is preserved"
+
+    # Run the code.  We should hit the breakpoint, because the
+    # condition evaluates to true.
+
+    gdb_run_cmd
+    gdb_test "" ".*reakpoint .*, main .*${srcfile}.*" "run to the bp"
+}
+
+# Restart.  Repeat the test above after the program has started.
+# This is needed to check a scenario where the breakpoints are no
+# longer re-inserted due to solib events.  Note that runto_main
+# deletes the breakpoints.
+with_test_prefix "with continue 1" {
+    if {![runto_main]} {
+       fail "could not run to main"
+       return -1
+    }
+
+    gdb_breakpoint "$bp_location"
+    set bpnum [get_integer_valueof "\$bpnum" 0 "get bpnum"]
+
+    gdb_test_no_output "cond $bpnum a == 10"
+
+    gdb_test "cond $bpnum gibberish" \
+       "No symbol \"gibberish\" in current context." \
+       "attempt a bad condition"
+
+    # Resume.  We should hit the breakpoint, because the
+    # condition evaluates to true.
+    gdb_continue_to_breakpoint "${srcfile}:${bp_location}"
+}
+
+# Repeat with a condition that evaluates to false.
+with_test_prefix "with continue 2" {
+    if {![runto_main]} {
+       fail "could not run to main"
+       return -1
+    }
+
+    gdb_breakpoint "$bp_location"
+    set bpnum [get_integer_valueof "\$bpnum" 0 "get bpnum"]
+
+    gdb_test_no_output "cond $bpnum a == 999"
+    
+    gdb_test "cond $bpnum gibberish" \
+       "No symbol \"gibberish\" in current context." \
+       "attempt a bad condition"
+
+    # Resume.  We should *not* hit the breakpoint, because the
+    # condition evaluates to false.
+    gdb_continue_to_end
+}
+
+# Repeat with a condition that contains junk at the end.
+with_test_prefix "with junk" {
+    if {![runto_main]} {
+       fail "could not run to main"
+       return -1
+    }
+
+    gdb_breakpoint "$bp_location"
+    set bpnum [get_integer_valueof "\$bpnum" 0 "get bpnum"]
+
+    gdb_test_no_output "cond $bpnum a == 999"
+
+    gdb_test "cond $bpnum a == 10 if" \
+       "Junk at end of expression" \
+       "attempt a bad condition"
+
+    # Resume.  We should *not* hit the breakpoint, because the
+    # condition evaluates to false.
+    gdb_continue_to_end
+}