From 24515d9819fcea76743d8ffca077620b679bf318 Mon Sep 17 00:00:00 2001 From: Eli Friedman <eli.friedman@gmail.com> Date: Tue, 20 Aug 2013 22:44:28 +0000 Subject: [PATCH] Add more specific flags for misc GNU extensions. This adds the following as subgroups of -Wgnu: -Wgnu-alignof-expression, -Wgnu-case-range, -Wgnu-complex-integer, -Wgnu-conditional-omitted-operand, -Wgnu-empty-initializer, -Wgnu-label-as-value, -Wgnu-local-label, and -Wgnu-statement-expression, Patch by Peter Lewis. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188839 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticGroups.td | 18 +++- include/clang/Basic/DiagnosticParseKinds.td | 18 ++-- test/Sema/gnu-flags.c | 98 +++++++++++++++++++++ 3 files changed, 123 insertions(+), 11 deletions(-) create mode 100644 test/Sema/gnu-flags.c diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index f1ab1e8dd75..f57d70c89cf 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -21,6 +21,7 @@ def : DiagGroup<"abi">; def : DiagGroup<"address">; def AddressOfTemporary : DiagGroup<"address-of-temporary">; def : DiagGroup<"aggregate-return">; +def GNUAlignofExpression : DiagGroup<"gnu-alignof-expression">; def AmbigMemberTemplate : DiagGroup<"ambiguous-member-template">; def ArrayBounds : DiagGroup<"array-bounds">; def ArrayBoundsPointerArithmetic : DiagGroup<"array-bounds-pointer-arithmetic">; @@ -45,10 +46,13 @@ def BuiltinMacroRedefined : DiagGroup<"builtin-macro-redefined">; def BuiltinRequiresHeader : DiagGroup<"builtin-requires-header">; def C99Compat : DiagGroup<"c99-compat">; def CXXCompat: DiagGroup<"c++-compat">; +def GNUCaseRange : DiagGroup<"gnu-case-range">; def CastAlign : DiagGroup<"cast-align">; def : DiagGroup<"cast-qual">; def : DiagGroup<"char-align">; def Comment : DiagGroup<"comment">; +def GNUComplexInteger : DiagGroup<"gnu-complex-integer">; +def GNUConditionalOmittedOperand : DiagGroup<"gnu-conditional-omitted-operand">; def ConfigMacros : DiagGroup<"config-macros">; def : DiagGroup<"ctor-dtor-privacy">; def GNUDesignator : DiagGroup<"gnu-designator">; @@ -82,6 +86,7 @@ def Documentation : DiagGroup<"documentation", DocumentationDeprecatedSync]>; def EmptyBody : DiagGroup<"empty-body">; +def GNUEmptyInitializer : DiagGroup<"gnu-empty-initializer">; def ExtraTokens : DiagGroup<"extra-tokens">; def CXX11ExtraSemi : DiagGroup<"c++11-extra-semi">; def ExtraSemi : DiagGroup<"extra-semi", [CXX11ExtraSemi]>; @@ -162,6 +167,8 @@ def KNRPromotedParameter : DiagGroup<"knr-promoted-parameter">; def : DiagGroup<"init-self">; def : DiagGroup<"inline">; def : DiagGroup<"invalid-pch">; +def GNULabelsAsValue : DiagGroup<"gnu-label-as-value">; +def GNULocalLabel : DiagGroup<"gnu-local-label">; def LiteralRange : DiagGroup<"literal-range">; def LocalTypeTemplateArgs : DiagGroup<"local-type-template-args", [CXX98CompatLocalTypeTemplateArgs]>; @@ -248,6 +255,7 @@ def StaticInInline : DiagGroup<"static-in-inline">; def StaticLocalInInline : DiagGroup<"static-local-in-inline">; def GNUStaticFloatInit : DiagGroup<"gnu-static-float-init">; def StaticFloatInit : DiagGroup<"static-float-init", [GNUStaticFloatInit]>; +def GNUStatementExpression : DiagGroup<"gnu-statement-expression">; def StringPlusInt : DiagGroup<"string-plus-int">; def StrncatSize : DiagGroup<"strncat-size">; def TautologicalOutOfRangeCompare : DiagGroup<"tautological-constant-out-of-range-compare">; @@ -527,8 +535,14 @@ def C11 : DiagGroup<"c11-extensions">; def C99 : DiagGroup<"c99-extensions">; // A warning group for warnings about GCC extensions. -def GNU : DiagGroup<"gnu", [GNUDesignator, VLAExtension, - ZeroLengthArray, GNUStaticFloatInit]>; +def GNU : DiagGroup<"gnu", [GNUAlignofExpression, GNUCaseRange, + GNUComplexInteger, + GNUConditionalOmittedOperand, + GNUDesignator, GNUEmptyInitializer, + VLAExtension, + GNULabelsAsValue, GNULocalLabel, + GNUStatementExpression, GNUStaticFloatInit, + ZeroLengthArray]>; // A warning group for warnings about code that clang accepts but gcc doesn't. def GccCompat : DiagGroup<"gcc-compat">; diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 15c7c980c94..4d7dc704628 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -54,7 +54,7 @@ def warn_duplicate_declspec : Warning<"duplicate '%0' declaration specifier">, def ext_plain_complex : ExtWarn< "plain '_Complex' requires a type specifier; assuming '_Complex double'">; def ext_integer_complex : Extension< - "complex integer types are a GNU extension">, InGroup<GNU>; + "complex integer types are a GNU extension">, InGroup<GNUComplexInteger>; def ext_thread_before : Extension<"'__thread' before '%0'">; def error_empty_enum : Error<"use of empty enum">; @@ -99,7 +99,7 @@ def warn_cxx98_compat_alignof : Warning< "alignof expressions are incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; def ext_alignof_expr : ExtWarn< - "%0 applied to an expression is a GNU extension">, InGroup<GNU>; + "%0 applied to an expression is a GNU extension">, InGroup<GNUAlignofExpression>; def warn_microsoft_dependent_exists : Warning< "dependent %select{__if_not_exists|__if_exists}0 declarations are ignored">, @@ -119,17 +119,17 @@ def ext_c11_noreturn : Extension< "_Noreturn functions are a C11-specific feature">, InGroup<C11>; def ext_gnu_indirect_goto : Extension< - "use of GNU indirect-goto extension">, InGroup<GNU>; + "use of GNU indirect-goto extension">, InGroup<GNULabelsAsValue>; def ext_gnu_address_of_label : Extension< - "use of GNU address-of-label extension">, InGroup<GNU>; + "use of GNU address-of-label extension">, InGroup<GNULabelsAsValue>; def ext_gnu_local_label : Extension< - "use of GNU locally declared label extension">, InGroup<GNU>; + "use of GNU locally declared label extension">, InGroup<GNULocalLabel>; def ext_gnu_statement_expr : Extension< - "use of GNU statement expression extension">, InGroup<GNU>; + "use of GNU statement expression extension">, InGroup<GNUStatementExpression>; def ext_gnu_conditional_expr : Extension< - "use of GNU ?: expression extension, eliding middle term">, InGroup<GNU>; + "use of GNU ?: conditional expression extension, omitting middle operand">, InGroup<GNUConditionalOmittedOperand>; def ext_gnu_empty_initializer : Extension< - "use of GNU empty initializer extension">, InGroup<GNU>; + "use of GNU empty initializer extension">, InGroup<GNUEmptyInitializer>; def ext_gnu_array_range : Extension<"use of GNU array range extension">, InGroup<GNUDesignator>; def ext_gnu_missing_equal_designator : ExtWarn< @@ -140,7 +140,7 @@ def ext_gnu_old_style_field_designator : ExtWarn< "use of GNU old-style field designator extension">, InGroup<GNUDesignator>; def ext_gnu_case_range : Extension<"use of GNU case range extension">, - InGroup<GNU>; + InGroup<GNUCaseRange>; // Generic errors. def err_expected_expression : Error<"expected expression">; diff --git a/test/Sema/gnu-flags.c b/test/Sema/gnu-flags.c new file mode 100644 index 00000000000..4ca965b7ddf --- /dev/null +++ b/test/Sema/gnu-flags.c @@ -0,0 +1,98 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -DALIGNOF +// RUN: %clang_cc1 -fsyntax-only -verify %s -DALL -Wgnu +// RUN: %clang_cc1 -fsyntax-only -verify %s -DALL \ +// RUN: -Wgnu-alignof-expression -Wgnu-case-range -Wgnu-complex-integer -Wgnu-conditional-omitted-operand \ +// RUN: -Wgnu-empty-initializer -Wgnu-label-as-value -Wgnu-local-label -Wgnu-statement-expression +// RUN: %clang_cc1 -fsyntax-only -verify %s -DNONE -Wgnu \ +// RUN: -Wno-gnu-alignof-expression -Wno-gnu-case-range -Wno-gnu-complex-integer -Wno-gnu-conditional-omitted-operand \ +// RUN: -Wno-gnu-empty-initializer -Wno-gnu-label-as-value -Wno-gnu-local-label -Wno-gnu-statement-expression +// RUNNOT: %clang_cc1 -fsyntax-only -verify %s -DALIGNOF -Wgnu-alignof-expression +// RUNNOT: %clang_cc1 -fsyntax-only -verify %s -DNONE -Wno-gnu-alignof-expression +// RUNNOT: %clang_cc1 -fsyntax-only -verify %s -DALIGNOF -DCASERANGE -Wgnu-case-range +// RUNNOT: %clang_cc1 -fsyntax-only -verify %s -DALIGNOF -DCOMPLEXINT -Wgnu-complex-integer +// RUNNOT: %clang_cc1 -fsyntax-only -verify %s -DALIGNOF -DOMITTEDOPERAND -Wgnu-conditional-omitted-operand +// RUNNOT: %clang_cc1 -fsyntax-only -verify %s -DALIGNOF -DEMPTYINIT -Wgnu-empty-initializer +// RUNNOT: %clang_cc1 -fsyntax-only -verify %s -DALIGNOF -DLABELVALUE -Wgnu-label-as-value +// RUNNOT: %clang_cc1 -fsyntax-only -verify %s -DALIGNOF -DLOCALLABEL -Wgnu-local-label +// RUNNOT: %clang_cc1 -fsyntax-only -verify %s -DALIGNOF -DSTATEMENTEXP -Wgnu-statement-expression + +#if NONE +// expected-no-diagnostics +#endif + + +#if ALL || ALIGNOF +// expected-warning@+4 {{'_Alignof' applied to an expression is a GNU extension}} +#endif + +char align; +_Static_assert(_Alignof(align) == 1, "align's alignment is wrong"); + + +#if ALL || CASERANGE +// expected-warning@+5 {{use of GNU case range extension}} +#endif + +void caserange(int x) { + switch (x) { + case 42 ... 44: ; + } +} + + +#if ALL || COMPLEXINT +// expected-warning@+3 {{complex integer types are a GNU extension}} +#endif + +_Complex short int complexint; + + +#if ALL || OMITTEDOPERAND +// expected-warning@+3 {{use of GNU ?: conditional expression extension, omitting middle operand}} +#endif + +static const char* omittedoperand = (const char*)0 ?: "Null"; + + +#if ALL || EMPTYINIT +// expected-warning@+3 {{use of GNU empty initializer extension}} +#endif + +struct { int x; } emptyinit = {}; + + +#if ALL || LABELVALUE +// expected-warning@+6 {{use of GNU address-of-label extension}} +// expected-warning@+7 {{use of GNU indirect-goto extension}} +#endif + +void labelvalue() { + void *ptr; + ptr = &&foo; +foo: + goto *ptr; +} + + +#if ALL || LOCALLABEL +// expected-warning@+5 {{use of GNU locally declared label extension}} +#endif + +void locallabel() { + { + __label__ foo; + goto foo; +foo: + ; + } +} + + +#if ALL || STATEMENTEXP +// expected-warning@+5 {{use of GNU statement expression extension}} +#endif + +void statementexp() +{ + int a = ({ 1; }); +} -- GitLab