enable extra-semi warnings

This is to prevent unnecessary semicolon usage and for consistency.

Change-Id: I46812808c32de1d865906b180d11f609d91a8e1a
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/13782
Reviewed-by: Brett Wilson <brettw@chromium.org>
Commit-Queue: Takuto Ikuta <tikuta@google.com>
diff --git a/build/gen.py b/build/gen.py
index 2d89af4..abe019c 100755
--- a/build/gen.py
+++ b/build/gen.py
@@ -439,7 +439,11 @@
         '-Wall',
         '-Wextra',
         '-Wno-unused-parameter',
+
+        '-Wextra-semi',
+        '-Wextra-semi-stmt',
         '-Wundef',
+
         '-std=c++17'
     ])
 
diff --git a/src/base/numerics/clamped_math.h b/src/base/numerics/clamped_math.h
index 9e83543..88e0e3a 100644
--- a/src/base/numerics/clamped_math.h
+++ b/src/base/numerics/clamped_math.h
@@ -233,12 +233,12 @@
 BASE_NUMERIC_ARITHMETIC_OPERATORS(Clamped, Clamp, Xor, ^, ^=)
 BASE_NUMERIC_ARITHMETIC_VARIADIC(Clamped, Clamp, Max)
 BASE_NUMERIC_ARITHMETIC_VARIADIC(Clamped, Clamp, Min)
-BASE_NUMERIC_COMPARISON_OPERATORS(Clamped, IsLess, <);
-BASE_NUMERIC_COMPARISON_OPERATORS(Clamped, IsLessOrEqual, <=);
-BASE_NUMERIC_COMPARISON_OPERATORS(Clamped, IsGreater, >);
-BASE_NUMERIC_COMPARISON_OPERATORS(Clamped, IsGreaterOrEqual, >=);
-BASE_NUMERIC_COMPARISON_OPERATORS(Clamped, IsEqual, ==);
-BASE_NUMERIC_COMPARISON_OPERATORS(Clamped, IsNotEqual, !=);
+BASE_NUMERIC_COMPARISON_OPERATORS(Clamped, IsLess, <)
+BASE_NUMERIC_COMPARISON_OPERATORS(Clamped, IsLessOrEqual, <=)
+BASE_NUMERIC_COMPARISON_OPERATORS(Clamped, IsGreater, >)
+BASE_NUMERIC_COMPARISON_OPERATORS(Clamped, IsGreaterOrEqual, >=)
+BASE_NUMERIC_COMPARISON_OPERATORS(Clamped, IsEqual, ==)
+BASE_NUMERIC_COMPARISON_OPERATORS(Clamped, IsNotEqual, !=)
 
 }  // namespace internal
 
diff --git a/src/base/numerics/safe_conversions.h b/src/base/numerics/safe_conversions.h
index 35c4089..32fb5a9 100644
--- a/src/base/numerics/safe_conversions.h
+++ b/src/base/numerics/safe_conversions.h
@@ -310,14 +310,14 @@
                        typename UnderlyingType<R>::type>(lhs, rhs);     \
   }
 
-BASE_NUMERIC_COMPARISON_OPERATORS(Strict, IsLess, <);
-BASE_NUMERIC_COMPARISON_OPERATORS(Strict, IsLessOrEqual, <=);
-BASE_NUMERIC_COMPARISON_OPERATORS(Strict, IsGreater, >);
-BASE_NUMERIC_COMPARISON_OPERATORS(Strict, IsGreaterOrEqual, >=);
-BASE_NUMERIC_COMPARISON_OPERATORS(Strict, IsEqual, ==);
-BASE_NUMERIC_COMPARISON_OPERATORS(Strict, IsNotEqual, !=);
+BASE_NUMERIC_COMPARISON_OPERATORS(Strict, IsLess, <)
+BASE_NUMERIC_COMPARISON_OPERATORS(Strict, IsLessOrEqual, <=)
+BASE_NUMERIC_COMPARISON_OPERATORS(Strict, IsGreater, >)
+BASE_NUMERIC_COMPARISON_OPERATORS(Strict, IsGreaterOrEqual, >=)
+BASE_NUMERIC_COMPARISON_OPERATORS(Strict, IsEqual, ==)
+BASE_NUMERIC_COMPARISON_OPERATORS(Strict, IsNotEqual, !=)
 
-};  // namespace internal
+}  // namespace internal
 
 using internal::as_signed;
 using internal::as_unsigned;
diff --git a/src/gn/analyzer.cc b/src/gn/analyzer.cc
index e15c265..b1be618 100644
--- a/src/gn/analyzer.cc
+++ b/src/gn/analyzer.cc
@@ -89,7 +89,7 @@
                  const std::string& key,
                  const std::string& value) {
   dict.SetKey(key, base::Value(value));
-};
+}
 
 void WriteLabels(const Label& default_toolchain,
                  base::DictionaryValue& dict,
diff --git a/src/gn/command_format.cc b/src/gn/command_format.cc
index a3fda21..6118fa4 100644
--- a/src/gn/command_format.cc
+++ b/src/gn/command_format.cc
@@ -519,7 +519,7 @@
 
 #define RETURN_IF_SET(x)             \
   if (int result = (x); result >= 0) \
-    return result;
+    return result
 
   if (const AccessorNode* accessor = node->AsAccessor()) {
     RETURN_IF_SET(SuffixCommentTreeWalk(accessor->subscript()));
@@ -559,7 +559,7 @@
   }
 
   return -1;
-};
+}
 
 // If there are suffix comments on the first node or its children, they might
 // carry down multiple lines. Otherwise, use the node's normal end range. This
diff --git a/src/gn/compile_commands_writer.cc b/src/gn/compile_commands_writer.cc
index c65d378..a2ee3a0 100644
--- a/src/gn/compile_commands_writer.cc
+++ b/src/gn/compile_commands_writer.cc
@@ -66,7 +66,7 @@
   RecursiveTargetConfigToStream<T>(config, target, getter, writer, out);
   base::EscapeJSONString(out.str(), false, &result);
   return result;
-};
+}
 
 void SetupCompileFlags(const Target* target,
                        PathOutput& path_output,
diff --git a/src/gn/immutable_vector.h b/src/gn/immutable_vector.h
index 306819b..0897bec 100644
--- a/src/gn/immutable_vector.h
+++ b/src/gn/immutable_vector.h
@@ -40,7 +40,7 @@
   const T* data() const { return begin(); }
   size_t size() const { return header_ ? header_->size : 0u; }
   bool empty() const { return size() == 0; }
-  const T& operator[](size_t offset) const { return begin()[offset]; };
+  const T& operator[](size_t offset) const { return begin()[offset]; }
 
   const T* begin() const { return header_ ? &header_->item0 : nullptr; }
   const T* end() const {
diff --git a/src/gn/json_project_writer.cc b/src/gn/json_project_writer.cc
index ba23749..27368ff 100644
--- a/src/gn/json_project_writer.cc
+++ b/src/gn/json_project_writer.cc
@@ -313,7 +313,6 @@
 
         if (line_end == std::string_view::npos) {
           out_ << json;
-          ;
           comma_ = {};
           return;
         }
diff --git a/src/gn/parse_tree.cc b/src/gn/parse_tree.cc
index e9ca8fa..28d5313 100644
--- a/src/gn/parse_tree.cc
+++ b/src/gn/parse_tree.cc
@@ -258,10 +258,12 @@
 std::unique_ptr<ParseNode> ParseNode::BuildFromJSON(const base::Value& value) {
   const std::string& str_type = value.FindKey(kJsonNodeType)->GetString();
 
-#define RETURN_IF_MATCHES_NAME(t)     \
-  if (str_type == t::kDumpNodeName) { \
-    return t::NewFromJSON(value);     \
-  }
+#define RETURN_IF_MATCHES_NAME(t)               \
+  do {                                          \
+    if (str_type == t::kDumpNodeName) {         \
+      return t::NewFromJSON(value);             \
+    }                                           \
+  } while(0)
 
   RETURN_IF_MATCHES_NAME(AccessorNode);
   RETURN_IF_MATCHES_NAME(BinaryOpNode);
@@ -332,7 +334,8 @@
   const base::Value* child = value.FindKey(kJsonNodeChild); \
   if (!child || !child->is_list()) {                        \
     return nullptr;                                         \
-  }
+  }                                                         \
+  (void)(0) // this is to supress extra semicolon warning.
 
 // static
 std::unique_ptr<AccessorNode> AccessorNode::NewFromJSON(
diff --git a/src/gn/rust_project_writer_helpers.h b/src/gn/rust_project_writer_helpers.h
index 4ccf568..9aa7eba 100644
--- a/src/gn/rust_project_writer_helpers.h
+++ b/src/gn/rust_project_writer_helpers.h
@@ -78,7 +78,7 @@
   std::optional<OutputFile>& gen_dir() { return gen_dir_; }
 
   // Returns the crate index.
-  CrateIndex index() { return index_; };
+  CrateIndex index() { return index_; }
 
   // Returns the displayable crate label.
   const std::string& label() { return label_; }
diff --git a/src/gn/string_atom.h b/src/gn/string_atom.h
index c590e0b..51aa8d5 100644
--- a/src/gn/string_atom.h
+++ b/src/gn/string_atom.h
@@ -171,7 +171,7 @@
   template <typename U>
   bool operator()(const U& a, const StringAtom& b) const noexcept {
     return a < b.str();
-  };
+  }
 };
 
 template <>