Repository: spack/spack

Issue:
`-Werror` to `-Wno-error` translation does not work with `nvc++` because it doesn't support `-Wno-error`
### Steps to reproduce

Enter some `build-env` with `%nvhpc` (version 22.11 in my case):
```console
> spack build-env pika%nvhpc -- bash
```

```console
> nvc++ -Werror ...
nvc++-Error-Unknown switch: -Wno-error
```
Indeed, `nvc++` doesn't have a `-Wno-error` switch (it does have more specific ones, like `-Wno-deprecated-declarations`).

This clearly comes from https://github.com/spack/spack/pull/30882. I see there's a way to disable this behaviour per-package which is nice. However, in this case the behaviour would need to be overridden per-compiler. I didn't see such a toggle but maybe I'm missing it. I'm guessing `nvc++` may some day end up supporting `-Wno-error` so hard-coding somewhere that `nvc++` should not do that replacement seems clunky, but is there a better way?

### Error message

_No response_

### Information on your system

```console
> spack debug report
* **Spack:** 0.20.0.dev0 (ee9857d57858888cf3b400c6781ec9968dc19cc2)
* **Python:** 3.6.15
* **Platform:** linux-sles15-zen2
* **Concretizer:** clingo
```

### General information

- [X] I have run `spack debug report` and reported the version of Spack/Python/Platform
- [X] I have searched the issues of this repo and believe this is not a duplicate
- [X] I have run the failing commands in debug mode and reported the output


Discussion:
@samcmill fyi
I've filed an RFE to add support for this flag.  

In the meantime, there is the `-noswitcherror` option, or the equivalent `NVCOMPILER_NOSWITCHERROR=1` environment variable.
@trws fyi
That's very, very annoying.  I suppose we could make all packages built with nvhpc leave werror in.  We can't necessarily use the environment variable or other options without breaking build system checks, so we may be stuck with that until they can support what we're currently doing.

Resolving patch:
diff --git a/lib/spack/spack/package_base.py b/lib/spack/spack/package_base.py
--- a/lib/spack/spack/package_base.py
+++ b/lib/spack/spack/package_base.py
@@ -617,10 +617,6 @@ class PackageBase(WindowsRPath, PackageViewMixin, RedistributionMixin, metaclass
     #: By default do not run tests within package's install()
     run_tests = False
 
-    #: Keep -Werror flags, matches config:flags:keep_werror to override config
-    # NOTE: should be type Optional[Literal['all', 'specific', 'none']] in 3.8+
-    keep_werror: Optional[str] = None
-
     #: Most packages are NOT extendable. Set to True if you want extensions.
     extendable = False
 
@@ -926,6 +922,32 @@ def global_license_file(self):
             self.global_license_dir, self.name, os.path.basename(self.license_files[0])
         )
 
+    # NOTE: return type should be Optional[Literal['all', 'specific', 'none']] in
+    # Python 3.8+, but we still support 3.6.
+    @property
+    def keep_werror(self) -> Optional[str]:
+        """Keep ``-Werror`` flags, matches ``config:flags:keep_werror`` to override config.
+
+        Valid return values are:
+        * ``"all"``: keep all ``-Werror`` flags.
+        * ``"specific"``: keep only ``-Werror=specific-warning`` flags.
+        * ``"none"``: filter out all ``-Werror*`` flags.
+        * ``None``: respect the user's configuration (``"none"`` by default).
+        """
+        if self.spec.satisfies("%nvhpc@:23.3") or self.spec.satisfies("%pgi"):
+            # Filtering works by replacing -Werror with -Wno-error, but older nvhpc and
+            # PGI do not understand -Wno-error, so we disable filtering.
+            return "all"
+
+        elif self.spec.satisfies("%nvhpc@23.4:"):
+            # newer nvhpc supports -Wno-error but can't disable specific warnings with
+            # -Wno-error=warning. Skip -Werror=warning, but still filter -Werror.
+            return "specific"
+
+        else:
+            # use -Werror disablement by default for other compilers
+            return None
+
     @property
     def version(self):
         if not self.spec.versions.concrete:


Test patch:
diff --git a/lib/spack/spack/test/cc.py b/lib/spack/spack/test/cc.py
--- a/lib/spack/spack/test/cc.py
+++ b/lib/spack/spack/test/cc.py
@@ -828,14 +828,14 @@ def test_keep_and_replace(wrapper_environment):
         ),
         (
             "config:flags:keep_werror:specific",
-            ["-Werror", "-Werror=specific", "-bah"],
-            ["-Werror=specific", "-bah"],
+            ["-Werror", "-Werror=specific", "-Werror-specific2", "-bah"],
+            ["-Wno-error", "-Werror=specific", "-Werror-specific2", "-bah"],
             ["-Werror"],
         ),
         (
             "config:flags:keep_werror:none",
             ["-Werror", "-Werror=specific", "-bah"],
-            ["-bah", "-Wno-error", "-Wno-error=specific"],
+            ["-Wno-error", "-Wno-error=specific", "-bah"],
             ["-Werror", "-Werror=specific"],
         ),
         # check non-standard -Werror opts like -Werror-implicit-function-declaration
@@ -848,13 +848,13 @@ def test_keep_and_replace(wrapper_environment):
         (
             "config:flags:keep_werror:specific",
             ["-Werror", "-Werror-implicit-function-declaration", "-bah"],
-            ["-Werror-implicit-function-declaration", "-bah", "-Wno-error"],
+            ["-Wno-error", "-Werror-implicit-function-declaration", "-bah"],
             ["-Werror"],
         ),
         (
             "config:flags:keep_werror:none",
             ["-Werror", "-Werror-implicit-function-declaration", "-bah"],
-            ["-bah", "-Wno-error=implicit-function-declaration"],
+            ["-Wno-error", "-bah", "-Wno-error=implicit-function-declaration"],
             ["-Werror", "-Werror-implicit-function-declaration"],
         ),
     ],