Skip to content

Make diagnostic pragma override -Werror=foo and DefaultError warnings #93647

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,9 @@ Non-comprehensive list of changes in this release
- Added ``__is_bitwise_cloneable`` which is used to check whether a type
can be safely copied by memcpy/memmove.

- ``#pragma GCC diagnostic warning "-Wfoo"`` can now downgrade ``-Werror=foo``
errors and certain default-to-error ``-W`` diagnostics to warnings.

New Compiler Flags
------------------
- ``-fsanitize=implicit-bitfield-conversion`` checks implicit truncation and
Expand Down
11 changes: 10 additions & 1 deletion clang/docs/UsersManual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1138,7 +1138,7 @@ and ``#pragma clang diagnostic`` are synonyms for Clang. GCC will ignore

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

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

Some diagnostics associated with a ``-W`` flag have the error severity by
default. They can be ignored or downgraded to warnings:

.. code-block:: cpp

// C only
#pragma GCC diagnostic warning "-Wimplicit-function-declaration"
int main(void) { puts(""); }

In addition to controlling warnings and errors generated by the compiler, it is
possible to generate custom warning and error messages through the following
pragmas:
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/Basic/Diagnostic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,9 +360,10 @@ void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map,
"Cannot map errors into warnings!");
assert((L.isInvalid() || SourceMgr) && "No SourceMgr for valid location");

// Don't allow a mapping to a warning override an error/fatal mapping.
// A command line -Wfoo has an invalid L and cannot override error/fatal
// mapping, while a warning pragma can.
bool WasUpgradedFromWarning = false;
if (Map == diag::Severity::Warning) {
if (Map == diag::Severity::Warning && L.isInvalid()) {
DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag);
if (Info.getSeverity() == diag::Severity::Error ||
Info.getSeverity() == diag::Severity::Fatal) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#ifdef USE_PRAGMA
#pragma clang diagnostic push
#if USE_PRAGMA == 1
#pragma clang diagnostic warning "-Wshorten-64-to-32"
#else
#pragma clang diagnostic error "-Wshorten-64-to-32"
#endif
#endif
template <class T> int convert(T V) { return V; }
#ifdef USE_PRAGMA
Expand Down
15 changes: 11 additions & 4 deletions clang/test/Modules/implicit-built-Werror-using-W.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,23 @@
// RUN: | FileCheck %s -allow-empty
//
// In the presence of a warning pragma, build with -Werror and then without.
// RUN: not %clang_cc1 -triple x86_64-apple-darwin16 -fsyntax-only -fmodules \
// RUN: -DUSE_PRAGMA -Werror=shorten-64-to-32 \
// RUN: %clang_cc1 -triple x86_64-apple-darwin16 -fsyntax-only -fmodules \
// RUN: -DUSE_PRAGMA=1 -Werror=shorten-64-to-32 \
// RUN: -I%S/Inputs/implicit-built-Werror-using-W -fimplicit-module-maps \
// RUN: -fmodules-cache-path=%t-pragma.cache -x c++ %s 2>&1 \
// RUN: | FileCheck %s -check-prefix=CHECK-ERROR
// RUN: | FileCheck %s -check-prefix=CHECK-WARN
// RUN: %clang_cc1 -triple x86_64-apple-darwin16 -fsyntax-only -fmodules \
// RUN: -DUSE_PRAGMA \
// RUN: -DUSE_PRAGMA=1 \
// RUN: -I%S/Inputs/implicit-built-Werror-using-W -fimplicit-module-maps \
// RUN: -fmodules-cache-path=%t-pragma.cache -x c++ %s 2>&1 \
// RUN: | FileCheck %s -check-prefix=CHECK-WARN

// Test an error pragma.
// RUN: not %clang_cc1 -triple x86_64-apple-darwin16 -fsyntax-only -fmodules \
// RUN: -DUSE_PRAGMA=2 -Wshorten-64-to-32 \
// RUN: -I%S/Inputs/implicit-built-Werror-using-W -fimplicit-module-maps \
// RUN: -fmodules-cache-path=%t-pragma.cache -x c++ %s 2>&1 \
// RUN: | FileCheck %s -check-prefix=CHECK-ERROR
#include <convert.h>

long long foo() { return convert<long long>(0); }
Expand Down
10 changes: 8 additions & 2 deletions clang/test/Preprocessor/pragma_diagnostic.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-undef %s
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-undef -Wno-unknown-warning-option -DAVOID_UNKNOWN_WARNING %s
// RUN: %clang_cc1 -fsyntax-only -verify -Werror=undef -DINITIAL_UNDEF %s

#ifdef INITIAL_UNDEF
#if FOO // expected-error {{'FOO' is not defined}}
#endif
#else
#if FOO // ok.
#endif
#endif

#pragma GCC diagnostic warning "-Wundef"

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

#pragma clang diagnostic warning "-Weverything" // This should not be effective
void pps(void){} // expected-error {{no previous prototype for function 'pps'}}
#pragma clang diagnostic warning "-Weverything" // Set to warning
void pps(void){} // expected-warning {{no previous prototype for function 'pps'}}
// expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
17 changes: 17 additions & 0 deletions clang/test/Sema/implicit-decl.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,20 @@ void GH48579_2(void) {

int GH48579_3 = ({a();}); // both-error {{statement expression not allowed at file scope}}
void GH48579_4(int array[({ a(); })]); // both-error {{statement expression not allowed at file scope}}

void pragma_warning(void) {
#pragma clang diagnostic warning "-Wimplicit-function-declaration"
bark(); // expected-warning {{call to undeclared function 'bark'; ISO C99 and later do not support implicit function declarations}} \
c2x-error {{use of undeclared identifier 'bark'}}
}

void pragma_error(void) {
#pragma clang diagnostic error "-Wimplicit-function-declaration"
bark(); // expected-error {{call to undeclared function 'bark'; ISO C99 and later do not support implicit function declarations}} \
c2x-error {{use of undeclared identifier 'bark'}}
}

void pragma_ignored(void) {
#pragma clang diagnostic ignored "-Wimplicit-function-declaration"
bark(); // c2x-error {{use of undeclared identifier 'bark'}}
}
Loading