Skip to content

Commit 9a92f2f

Browse files
authored
Make diagnostic pragma override -Werror=foo and DefaultError warnings
In GCC, `#pragma GCC diagnostic warning "-Wfoo"` overrides command-line `-Werror=foo` and errors that can become warnings (pedwarn with -pedantic-errors and permerror). ``` #pragma GCC diagnostic warning "-Wnarrowing" int x = {4.2}; #pragma GCC diagnostic warning "-Wundef" #if FOO #endif // gcc -c -Werror=undef -Werror=narrowing => two warnings ``` These diagnostics are similar to our Warning/ExtWarn/Extension diagnostics with DefaultError. This patch ports the behavior to Clang. Fix llvm#93474 Pull Request: llvm#93647
1 parent c7b3234 commit 9a92f2f

File tree

7 files changed

+56
-9
lines changed

7 files changed

+56
-9
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,9 @@ Non-comprehensive list of changes in this release
351351
- Added ``__is_bitwise_cloneable`` which is used to check whether a type
352352
can be safely copied by memcpy/memmove.
353353

354+
- ``#pragma GCC diagnostic warning "-Wfoo"`` can now downgrade ``-Werror=foo``
355+
errors and certain default-to-error ``-W`` diagnostics to warnings.
356+
354357
New Compiler Flags
355358
------------------
356359
- ``-fsanitize=implicit-bitfield-conversion`` checks implicit truncation and

clang/docs/UsersManual.rst

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1138,7 +1138,7 @@ and ``#pragma clang diagnostic`` are synonyms for Clang. GCC will ignore
11381138

11391139
The pragma may control any warning that can be used from the command
11401140
line. Warnings may be set to ignored, warning, error, or fatal. The
1141-
following example code will tell Clang or GCC to ignore the -Wall
1141+
following example code will tell Clang or GCC to ignore the ``-Wall``
11421142
warnings:
11431143

11441144
.. code-block:: c
@@ -1186,6 +1186,15 @@ severity levels. They can be used to change severity of a particular diagnostic
11861186
for a region of source file. A notable difference from GCC is that diagnostic
11871187
not enabled via command line arguments can't be enabled this way yet.
11881188

1189+
Some diagnostics associated with a ``-W`` flag have the error severity by
1190+
default. They can be ignored or downgraded to warnings:
1191+
1192+
.. code-block:: cpp
1193+
1194+
// C only
1195+
#pragma GCC diagnostic warning "-Wimplicit-function-declaration"
1196+
int main(void) { puts(""); }
1197+
11891198
In addition to controlling warnings and errors generated by the compiler, it is
11901199
possible to generate custom warning and error messages through the following
11911200
pragmas:

clang/lib/Basic/Diagnostic.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,9 +360,10 @@ void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map,
360360
"Cannot map errors into warnings!");
361361
assert((L.isInvalid() || SourceMgr) && "No SourceMgr for valid location");
362362

363-
// Don't allow a mapping to a warning override an error/fatal mapping.
363+
// A command line -Wfoo has an invalid L and cannot override error/fatal
364+
// mapping, while a warning pragma can.
364365
bool WasUpgradedFromWarning = false;
365-
if (Map == diag::Severity::Warning) {
366+
if (Map == diag::Severity::Warning && L.isInvalid()) {
366367
DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag);
367368
if (Info.getSeverity() == diag::Severity::Error ||
368369
Info.getSeverity() == diag::Severity::Fatal) {

clang/test/Modules/Inputs/implicit-built-Werror-using-W/convert.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
#ifdef USE_PRAGMA
22
#pragma clang diagnostic push
3+
#if USE_PRAGMA == 1
34
#pragma clang diagnostic warning "-Wshorten-64-to-32"
5+
#else
6+
#pragma clang diagnostic error "-Wshorten-64-to-32"
7+
#endif
48
#endif
59
template <class T> int convert(T V) { return V; }
610
#ifdef USE_PRAGMA

clang/test/Modules/implicit-built-Werror-using-W.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,23 @@
2222
// RUN: | FileCheck %s -allow-empty
2323
//
2424
// In the presence of a warning pragma, build with -Werror and then without.
25-
// RUN: not %clang_cc1 -triple x86_64-apple-darwin16 -fsyntax-only -fmodules \
26-
// RUN: -DUSE_PRAGMA -Werror=shorten-64-to-32 \
25+
// RUN: %clang_cc1 -triple x86_64-apple-darwin16 -fsyntax-only -fmodules \
26+
// RUN: -DUSE_PRAGMA=1 -Werror=shorten-64-to-32 \
2727
// RUN: -I%S/Inputs/implicit-built-Werror-using-W -fimplicit-module-maps \
2828
// RUN: -fmodules-cache-path=%t-pragma.cache -x c++ %s 2>&1 \
29-
// RUN: | FileCheck %s -check-prefix=CHECK-ERROR
29+
// RUN: | FileCheck %s -check-prefix=CHECK-WARN
3030
// RUN: %clang_cc1 -triple x86_64-apple-darwin16 -fsyntax-only -fmodules \
31-
// RUN: -DUSE_PRAGMA \
31+
// RUN: -DUSE_PRAGMA=1 \
3232
// RUN: -I%S/Inputs/implicit-built-Werror-using-W -fimplicit-module-maps \
3333
// RUN: -fmodules-cache-path=%t-pragma.cache -x c++ %s 2>&1 \
3434
// RUN: | FileCheck %s -check-prefix=CHECK-WARN
35+
36+
// Test an error pragma.
37+
// RUN: not %clang_cc1 -triple x86_64-apple-darwin16 -fsyntax-only -fmodules \
38+
// RUN: -DUSE_PRAGMA=2 -Wshorten-64-to-32 \
39+
// RUN: -I%S/Inputs/implicit-built-Werror-using-W -fimplicit-module-maps \
40+
// RUN: -fmodules-cache-path=%t-pragma.cache -x c++ %s 2>&1 \
41+
// RUN: | FileCheck %s -check-prefix=CHECK-ERROR
3542
#include <convert.h>
3643

3744
long long foo() { return convert<long long>(0); }

clang/test/Preprocessor/pragma_diagnostic.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-undef %s
22
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-undef -Wno-unknown-warning-option -DAVOID_UNKNOWN_WARNING %s
3+
// RUN: %clang_cc1 -fsyntax-only -verify -Werror=undef -DINITIAL_UNDEF %s
34

5+
#ifdef INITIAL_UNDEF
6+
#if FOO // expected-error {{'FOO' is not defined}}
7+
#endif
8+
#else
49
#if FOO // ok.
510
#endif
11+
#endif
612

713
#pragma GCC diagnostic warning "-Wundef"
814

@@ -52,6 +58,6 @@ void ppq(void){}
5258
void ppr(void){} // expected-error {{no previous prototype for function 'ppr'}}
5359
// expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
5460

55-
#pragma clang diagnostic warning "-Weverything" // This should not be effective
56-
void pps(void){} // expected-error {{no previous prototype for function 'pps'}}
61+
#pragma clang diagnostic warning "-Weverything" // Set to warning
62+
void pps(void){} // expected-warning {{no previous prototype for function 'pps'}}
5763
// expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}

clang/test/Sema/implicit-decl.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,20 @@ void GH48579_2(void) {
7474

7575
int GH48579_3 = ({a();}); // both-error {{statement expression not allowed at file scope}}
7676
void GH48579_4(int array[({ a(); })]); // both-error {{statement expression not allowed at file scope}}
77+
78+
void pragma_warning(void) {
79+
#pragma clang diagnostic warning "-Wimplicit-function-declaration"
80+
bark(); // expected-warning {{call to undeclared function 'bark'; ISO C99 and later do not support implicit function declarations}} \
81+
c2x-error {{use of undeclared identifier 'bark'}}
82+
}
83+
84+
void pragma_error(void) {
85+
#pragma clang diagnostic error "-Wimplicit-function-declaration"
86+
bark(); // expected-error {{call to undeclared function 'bark'; ISO C99 and later do not support implicit function declarations}} \
87+
c2x-error {{use of undeclared identifier 'bark'}}
88+
}
89+
90+
void pragma_ignored(void) {
91+
#pragma clang diagnostic ignored "-Wimplicit-function-declaration"
92+
bark(); // c2x-error {{use of undeclared identifier 'bark'}}
93+
}

0 commit comments

Comments
 (0)