From c6f76aa5cdb02c376df17aafadf2dd7cf41fe5b1 Mon Sep 17 00:00:00 2001
From: wangqiang <wangqiang1@kylinos.cn>
Date: Fri, 19 Jul 2024 11:01:22 +0800
Subject: [PATCH 2/2] Handling of option `-Wall` and `-Werror=format=2`
 override `-Wno`

Fix nfs-utils build issue

Signed-off-by: wangqiang <wangqiang1@kylinos.cn>
---
 clang/lib/Frontend/CompilerInvocation.cpp | 32 ++++++++++++++++++++++-
 clang/test/Driver/test-warnning.c         | 15 +++++++++++
 2 files changed, 46 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/Driver/test-warnning.c

diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index d7b609ef276c..cbb122cc6eeb 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -817,10 +817,40 @@ static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group,
                               OptSpecifier GroupWithValue,
                               std::vector<std::string> &Diagnostics) {
   for (auto *A : Args.filtered(Group)) {
+#ifdef BUILD_FOR_OPENEULER
+    bool  GccCompatible = Args.hasFlag(options::OPT_fgcc_compatible,
+    options::OPT_fno_gcc_compatible, false);
     if (A->getOption().getKind() == Option::FlagClass) {
       // The argument is a pure flag (such as OPT_Wall or
       // OPT_Wdeprecated). Add its name (minus the "W" or "R" at the
       // beginning) to the diagnostics.
+      if (A->getOption().getName() == "Wall" && GccCompatible) {
+          // Avoid -Wall and -Werror=format=2 override -Wno-xxx
+          Diagnostics.insert(
+              Diagnostics.begin(),
+              std::string(A->getOption().getName().drop_front(1)));
+      } else {
+          Diagnostics.push_back(
+              std::string(A->getOption().getName().drop_front(1)));
+      }
+    } else if (A->getOption().matches(GroupWithValue)) {
+        // This is -Wfoo= or -Rfoo=, where foo is the name of the diagnostic
+        // group. Add only the group name to the diagnostics.
+        Diagnostics.push_back(std::string(
+            A->getOption().getName().drop_front(1).rtrim("=-")));
+    } else {
+        // Otherwise, add its value (for OPT_W_Joined and similar).
+        if (std::string(A->getValue()) == "error=format=2" && GccCompatible) {
+            // Avoid -Werror=format=2 override -Wno-xxx
+            Diagnostics.insert(Diagnostics.begin(), A->getValue());
+        } else {
+            Diagnostics.push_back(A->getValue());
+        }
+    }
+#else
+    if (A->getOption().getKind() == Option::FlagClass) {
+      // The argument is a pure flag (such as OPT_Wall or OPT_Wdeprecated). Add
+      // its name (minus the "W" or "R" at the beginning) to the diagnostics.
       Diagnostics.push_back(
           std::string(A->getOption().getName().drop_front(1)));
     } else if (A->getOption().matches(GroupWithValue)) {
@@ -830,9 +860,9 @@ static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group,
           std::string(A->getOption().getName().drop_front(1).rtrim("=-")));
     } else {
       // Otherwise, add its value (for OPT_W_Joined and similar).
-
       Diagnostics.push_back(A->getValue());
     }
+#endif
   }
 }
 
diff --git a/clang/test/Driver/test-warnning.c b/clang/test/Driver/test-warnning.c
new file mode 100644
index 000000000000..641f9e3512d5
--- /dev/null
+++ b/clang/test/Driver/test-warnning.c
@@ -0,0 +1,15 @@
+// REQUIRES: build_for_openeuler
+
+// RUN: %clang -v -fgcc-compatible -Wno-format-security -Werror=format=2 -Wall %s
+// RUN: %clang -v -Wall %s 2>&1 | FileCheck -check-prefix=CHECK-ERROR %s
+// CHECK-ERROR: warning: format string is not a string literal (potentially insecure)
+// RUN: %clang -v -Wno-format-security -Werror=format=2 -Wall %s 2>&1 | FileCheck -check-prefix=CHECK-ERROR %s
+// CHECK-ERROR: error: format string is not a string literal (potentially insecure)
+
+#include <stdio.h>
+
+int main() {
+    char *str = "llvm-project";
+    printf(str);
+    return 0;
+}
\ No newline at end of file
-- 
2.33.0

