Add specific warning flags for GNU ext in Sema.

This patch adds the following, more specific warning flags:

gnu-anonymous-struct
gnu-compound-literal-initializer
gnu-empty-struct
gnu-flexible-array-initializer
gnu-flexible-array-union-member
gnu-folding-constant
redeclared-class-member
gnu-redeclared-enum
gnu-union-cast
gnu-variable-sized-type-not-at-end

Patch by Peter Lewis.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190972 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eli Friedman 2013-09-18 23:23:17 +00:00
parent 83b6397f2d
commit 5f33c37f8f
6 changed files with 214 additions and 38 deletions

View File

@ -23,12 +23,14 @@ def AddressOfTemporary : DiagGroup<"address-of-temporary">;
def : DiagGroup<"aggregate-return">;
def GNUAlignofExpression : DiagGroup<"gnu-alignof-expression">;
def AmbigMemberTemplate : DiagGroup<"ambiguous-member-template">;
def GNUAnonymousStruct : DiagGroup<"gnu-anonymous-struct">;
def ArrayBounds : DiagGroup<"array-bounds">;
def ArrayBoundsPointerArithmetic : DiagGroup<"array-bounds-pointer-arithmetic">;
def Availability : DiagGroup<"availability">;
def Section : DiagGroup<"section">;
def AutoImport : DiagGroup<"auto-import">;
def GNUBinaryLiteral : DiagGroup<"gnu-binary-literal">;
def GNUCompoundLiteralInitializer : DiagGroup<"gnu-compound-literal-initializer">;
def BitFieldConstantConversion : DiagGroup<"bitfield-constant-conversion">;
def ConstantConversion :
DiagGroup<"constant-conversion", [ BitFieldConstantConversion ] >;
@ -88,10 +90,14 @@ def Documentation : DiagGroup<"documentation",
def EmptyBody : DiagGroup<"empty-body">;
def GNUEmptyInitializer : DiagGroup<"gnu-empty-initializer">;
def GNUEmptyStruct : DiagGroup<"gnu-empty-struct">;
def ExtraTokens : DiagGroup<"extra-tokens">;
def CXX11ExtraSemi : DiagGroup<"c++11-extra-semi">;
def ExtraSemi : DiagGroup<"extra-semi", [CXX11ExtraSemi]>;
def GNUFlexibleArrayInitializer : DiagGroup<"gnu-flexible-array-initializer">;
def GNUFlexibleArrayUnionMember : DiagGroup<"gnu-flexible-array-union-member">;
def GNUFoldingConstant : DiagGroup<"gnu-folding-constant">;
def FormatExtraArgs : DiagGroup<"format-extra-args">;
def FormatZeroLength : DiagGroup<"format-zero-length">;
@ -233,6 +239,8 @@ def PoundPragmaMessage : DiagGroup<"#pragma-messages">,
DiagCategory<"#pragma message Directive">;
def : DiagGroup<"pointer-to-int-cast">;
def : DiagGroup<"redundant-decls">;
def RedeclaredClassMember : DiagGroup<"redeclared-class-member">;
def GNURedeclaredEnum : DiagGroup<"gnu-redeclared-enum">;
def ReturnStackAddress : DiagGroup<"return-stack-address">;
def ReturnTypeCLinkage : DiagGroup<"return-type-c-linkage">;
def ReturnType : DiagGroup<"return-type", [ReturnTypeCLinkage]>;
@ -266,6 +274,8 @@ def TautologicalCompare : DiagGroup<"tautological-compare",
def HeaderHygiene : DiagGroup<"header-hygiene">;
def DuplicateDeclSpecifier : DiagGroup<"duplicate-decl-specifier">;
def CompareDistinctPointerType : DiagGroup<"compare-distinct-pointer-types">;
def GNUUnionCast : DiagGroup<"gnu-union-cast">;
def GNUVariableSizedTypeNotAtEnd : DiagGroup<"gnu-variable-sized-type-not-at-end">;
def Varargs : DiagGroup<"varargs">;
def Unsequenced : DiagGroup<"unsequenced">;
@ -541,15 +551,19 @@ def C11 : DiagGroup<"c11-extensions">;
def C99 : DiagGroup<"c99-extensions">;
// A warning group for warnings about GCC extensions.
def GNU : DiagGroup<"gnu", [GNUAlignofExpression, GNUBinaryLiteral,
GNUCaseRange, GNUComplexInteger,
GNUConditionalOmittedOperand,
GNUDesignator, GNUEmptyInitializer,
VLAExtension,
def GNU : DiagGroup<"gnu", [GNUAlignofExpression, GNUAnonymousStruct,
GNUBinaryLiteral, GNUCaseRange,
GNUComplexInteger, GNUCompoundLiteralInitializer,
GNUConditionalOmittedOperand, GNUDesignator,
GNUEmptyInitializer, GNUEmptyStruct,
VLAExtension, GNUFlexibleArrayInitializer,
GNUFlexibleArrayUnionMember, GNUFoldingConstant,
GNUImaginaryConstant, GNULabelsAsValue,
RedeclaredClassMember, GNURedeclaredEnum,
GNUStatementExpression, GNUStaticFloatInit,
ZeroLengthArray,
GNUZeroLineDirective, GNUZeroVariadicMacroArguments]>;
GNUUnionCast, GNUVariableSizedTypeNotAtEnd,
ZeroLengthArray, GNUZeroLineDirective,
GNUZeroVariadicMacroArguments]>;
// A warning group for warnings about code that clang accepts but gcc doesn't.
def GccCompat : DiagGroup<"gcc-compat">;

View File

@ -35,7 +35,7 @@ def err_expr_not_ice : Error<
"expression is not an %select{integer|integral}0 constant expression">;
def ext_expr_not_ice : Extension<
"expression is not an %select{integer|integral}0 constant expression; "
"folding it to a constant is a GNU extension">, InGroup<GNU>;
"folding it to a constant is a GNU extension">, InGroup<GNUFoldingConstant>;
def err_typecheck_converted_constant_expression : Error<
"value of type %0 is not implicitly convertible to %1">;
def err_typecheck_converted_constant_expression_disallowed : Error<
@ -98,7 +98,7 @@ def err_vla_decl_has_static_storage : Error<
def err_vla_decl_has_extern_linkage : Error<
"variable length array declaration can not have 'extern' linkage">;
def ext_vla_folded_to_constant : Extension<
"variable length array folded to constant array as an extension">;
"variable length array folded to constant array as an extension">, InGroup<GNUFoldingConstant>;
// C99 variably modified types
def err_variably_modified_template_arg : Error<
@ -143,7 +143,7 @@ def err_designator_into_flexible_array_member : Error<
def note_flexible_array_member : Note<
"initialized flexible array member %0 is here">;
def ext_flexible_array_init : Extension<
"flexible array initialization is a GNU extension">, InGroup<GNU>;
"flexible array initialization is a GNU extension">, InGroup<GNUFlexibleArrayInitializer>;
// Declarations.
def err_bad_variable_name : Error<
@ -3626,7 +3626,7 @@ def err_forward_ref_enum : Error<
def ext_ms_forward_ref_enum : Extension<
"forward references to 'enum' types are a Microsoft extension">, InGroup<Microsoft>;
def ext_forward_ref_enum_def : Extension<
"redeclaration of already-defined enum %0 is a GNU extension">, InGroup<GNU>;
"redeclaration of already-defined enum %0 is a GNU extension">, InGroup<GNURedeclaredEnum>;
def err_redefinition_of_enumerator : Error<"redefinition of enumerator %0">;
def err_duplicate_member : Error<"duplicate member %0">;
@ -3900,7 +3900,7 @@ def err_field_declared_as_function : Error<"field %0 declared as a function">;
def err_field_incomplete : Error<"field has incomplete type %0">;
def ext_variable_sized_type_in_struct : ExtWarn<
"field %0 with variable sized type %1 not at the end of a struct or class is"
" a GNU extension">, InGroup<GNU>;
" a GNU extension">, InGroup<GNUVariableSizedTypeNotAtEnd>;
def err_flexible_array_empty_struct : Error<
"flexible array %0 not allowed in otherwise empty struct">;
@ -3924,9 +3924,9 @@ def ext_flexible_array_union_ms : Extension<
def ext_flexible_array_empty_aggregate_gnu : Extension<
"flexible array member %0 in otherwise empty "
"%select{struct|interface|union|class|enum}1 is a GNU extension">,
InGroup<GNU>;
InGroup<GNUEmptyStruct>;
def ext_flexible_array_union_gnu : Extension<
"flexible array member %0 in a union is a GNU extension">, InGroup<GNU>;
"flexible array member %0 in a union is a GNU extension">, InGroup<GNUFlexibleArrayUnionMember>;
let CategoryName = "ARC Semantic Issue" in {
@ -4348,7 +4348,7 @@ def note_enum_specialized_here : Note<
def err_member_redeclared : Error<"class member cannot be redeclared">;
def ext_member_redeclared : ExtWarn<"class member cannot be redeclared">,
InGroup<GNU>;
InGroup<RedeclaredClassMember>;
def err_member_redeclared_in_instantiation : Error<
"multiple overloads of %0 instantiate to the same signature %1">;
def err_member_name_of_class : Error<"member %0 has the same name as its class">;
@ -4440,7 +4440,7 @@ def err_array_init_non_constant_array : Error<
def ext_array_init_copy : Extension<
"initialization of an array "
"%diff{of type $ from a compound literal of type $|"
"from a compound literal}0,1 is a GNU extension">, InGroup<GNU>;
"from a compound literal}0,1 is a GNU extension">, InGroup<GNUCompoundLiteralInitializer>;
// This is intentionally not disabled by -Wno-gnu.
def ext_array_init_parens : ExtWarn<
"parenthesized initialization of a member array is a GNU extension">,
@ -5576,7 +5576,7 @@ def ext_typecheck_cast_nonscalar : Extension<
"C99 forbids casting nonscalar type %0 to the same type">;
def ext_typecheck_cast_to_union : Extension<
"cast to union type is a GNU extension">,
InGroup<GNU>;
InGroup<GNUUnionCast>;
def err_typecheck_cast_to_union_no_type : Error<
"cast to union type from type %0 not present in union">;
def err_cast_pointer_from_non_pointer_int : Error<
@ -5647,9 +5647,9 @@ def err_expected_ident_or_lparen : Error<"expected identifier or '('">;
def err_typecheck_cond_incompatible_operands_null : Error<
"non-pointer operand type %0 incompatible with %select{NULL|nullptr}1">;
def ext_empty_struct_union : Extension<
"empty %select{struct|union}0 is a GNU extension">, InGroup<GNU>;
"empty %select{struct|union}0 is a GNU extension">, InGroup<GNUEmptyStruct>;
def ext_no_named_members_in_struct_union : Extension<
"%select{struct|union}0 without named members is a GNU extension">, InGroup<GNU>;
"%select{struct|union}0 without named members is a GNU extension">, InGroup<GNUEmptyStruct>;
def warn_zero_size_struct_union_compat : Warning<"%select{|empty }0"
"%select{struct|union}1 has size 0 in C, %select{size 1|non-zero size}2 in C++">,
InGroup<CXXCompat>, DefaultIgnore;
@ -5758,7 +5758,7 @@ def err_in_class_initializer_references_def_ctor : Error<
def ext_in_class_initializer_non_constant : Extension<
"in-class initializer for static data member is not a constant expression; "
"folding it to a constant is a GNU extension">, InGroup<GNU>;
"folding it to a constant is a GNU extension">, InGroup<GNUFoldingConstant>;
def err_thread_dynamic_init : Error<
"initializer for thread-local variable must be a constant expression">;
@ -5771,7 +5771,7 @@ def note_use_thread_local : Note<
def ext_anonymous_union : Extension<
"anonymous unions are a C11 extension">, InGroup<C11>;
def ext_gnu_anonymous_struct : Extension<
"anonymous structs are a GNU extension">, InGroup<GNU>;
"anonymous structs are a GNU extension">, InGroup<GNUAnonymousStruct>;
def ext_c11_anonymous_struct : Extension<
"anonymous structs are a C11 extension">, InGroup<C11>;
def err_anonymous_union_not_static : Error<

View File

@ -36,11 +36,8 @@
// CHECK-GNU: ext_gnu_array_range
// CHECK-GNU: ext_gnu_missing_equal_designator
// CHECK-GNU: ext_gnu_old_style_field_designator
// CHECK-GNU: -Wvla
// CHECK-GNU: -Wvla-extension
// CHECK-GNU: ext_vla
// CHECK-GNU: ext_array_init_copy
// CHECK-GNU: ext_empty_struct_union
// CHECK-GNU: ext_expr_not_ice
// There are more GNU extensions but we don't need to check them all.
// RUN: diagtool tree --flags-only -Wgnu | FileCheck -check-prefix CHECK-FLAGS-ONLY %s

View File

@ -156,4 +156,4 @@ CHECK-NEXT: warn_weak_import
The list of warnings in -Wpedantic should NEVER grow.
CHECK: Number in -Wpedantic (not covered by other -W flags): 29
CHECK: Number in -Wpedantic (not covered by other -W flags): 28

View File

@ -1,19 +1,32 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -DALIGNOF
// RUN: %clang_cc1 -fsyntax-only -verify %s -DNONE -Wno-gnu
// RUN: %clang_cc1 -fsyntax-only -verify %s -DALL -Wgnu
// RUN: %clang_cc1 -fsyntax-only -verify %s -DALL \
// RUN: %clang_cc1 -fsyntax-only -verify %s -DALL -Wno-gnu \
// RUN: -Wgnu-alignof-expression -Wgnu-case-range -Wgnu-complex-integer -Wgnu-conditional-omitted-operand \
// RUN: -Wgnu-empty-initializer -Wgnu-label-as-value -Wgnu-statement-expression
// RUN: -Wgnu-empty-initializer -Wgnu-label-as-value -Wgnu-statement-expression \
// RUN: -Wgnu-compound-literal-initializer -Wgnu-flexible-array-initializer \
// RUN: -Wgnu-redeclared-enum -Wgnu-folding-constant -Wgnu-empty-struct \
// RUN: -Wgnu-union-cast -Wgnu-variable-sized-type-not-at-end
// 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-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 -DSTATEMENTEXP -Wgnu-statement-expression
// RUN: -Wno-gnu-empty-initializer -Wno-gnu-label-as-value -Wno-gnu-statement-expression \
// RUN: -Wno-gnu-compound-literal-initializer -Wno-gnu-flexible-array-initializer \
// RUN: -Wno-gnu-redeclared-enum -Wno-gnu-folding-constant -Wno-gnu-empty-struct \
// RUN: -Wno-gnu-union-cast -Wno-gnu-variable-sized-type-not-at-end
// Additional disabled tests:
// %clang_cc1 -fsyntax-only -verify %s -DALIGNOF -Wno-gnu -Wgnu-alignof-expression
// %clang_cc1 -fsyntax-only -verify %s -DCASERANGE -Wno-gnu -Wgnu-case-range
// %clang_cc1 -fsyntax-only -verify %s -DCOMPLEXINT -Wno-gnu -Wgnu-complex-integer
// %clang_cc1 -fsyntax-only -verify %s -DOMITTEDOPERAND -Wno-gnu -Wgnu-conditional-omitted-operand
// %clang_cc1 -fsyntax-only -verify %s -DEMPTYINIT -Wno-gnu -Wgnu-empty-initializer
// %clang_cc1 -fsyntax-only -verify %s -DLABELVALUE -Wno-gnu -Wgnu-label-as-value
// %clang_cc1 -fsyntax-only -verify %s -DSTATEMENTEXP -Wno-gnu -Wgnu-statement-expression
// %clang_cc1 -fsyntax-only -verify %s -DCOMPOUNDLITERALINITIALIZER -Wno-gnu -Wgnu-compound-literal-initializer
// %clang_cc1 -fsyntax-only -verify %s -DFLEXIBLEARRAYINITIALIZER -Wno-gnu -Wgnu-flexible-array-initializer
// %clang_cc1 -fsyntax-only -verify %s -DREDECLAREDENUM -Wno-gnu -Wgnu-redeclared-enum
// %clang_cc1 -fsyntax-only -verify %s -DUNIONCAST -Wno-gnu -Wgnu-union-cast
// %clang_cc1 -fsyntax-only -verify %s -DVARIABLESIZEDTYPENOTATEND -Wno-gnu -Wgnu-variable-sized-type-not-at-end
// %clang_cc1 -fsyntax-only -verify %s -DFOLDINGCONSTANT -Wno-gnu -Wgnu-folding-constant
// %clang_cc1 -fsyntax-only -verify %s -DEMPTYSTRUCT -Wno-gnu -Wgnu-empty-struct
#if NONE
// expected-no-diagnostics
@ -72,6 +85,7 @@ foo:
goto *ptr;
}
#if ALL || STATEMENTEXP
// expected-warning@+5 {{use of GNU statement expression extension}}
#endif
@ -80,3 +94,78 @@ void statementexp()
{
int a = ({ 1; });
}
#if ALL || COMPOUNDLITERALINITIALIZER
// expected-warning@+4 {{initialization of an array of type 'int [5]' from a compound literal of type 'int [5]' is a GNU extension}}
#endif
typedef int int5[5];
int cli[5] = (int[]){1, 2, 3, 4, 5};
#if ALL || FLEXIBLEARRAYINITIALIZER
// expected-note@+6 {{initialized flexible array member 'y' is here}}
// expected-warning@+6 {{flexible array initialization is a GNU extension}}
#endif
struct fai {
int x;
int y[];
} fai = { 1, { 2, 3, 4 } };
#if ALL || FOLDINGCONSTANT
// expected-warning@+5 {{expression is not an integer constant expression; folding it to a constant is a GNU extension}}
// expected-warning@+7 {{variable length array folded to constant array as an extension}}
#endif
enum {
fic = (int)(0.75 * 1000 * 1000)
};
static const int size = 100;
void foo(void) { int data[size]; }
#if ALL || REDECLAREDENUM
// expected-note@+4 {{previous definition is here}}
// expected-warning@+8 {{redeclaration of already-defined enum 'RE' is a GNU extension}}
#endif
enum RE {
Val1,
Val2
};
enum RE;
#if ALL || UNIONCAST
// expected-warning@+4 {{cast to union type is a GNU extension}}
#endif
union uc { int i; unsigned : 3; };
union uc w = (union uc)2;
#if ALL || VARIABLESIZEDTYPENOTATEND
// expected-warning@+8 {{field 'hdr' with variable sized type 'struct vst' not at the end of a struct or class is a GNU extension}}
#endif
struct vst {
short tag_type;
char tag_data[];
};
struct vstnae {
struct vst hdr;
char data;
};
#if ALL || EMPTYSTRUCT
// expected-warning@+4 {{empty struct is a GNU extension}}
// expected-warning@+4 {{struct without named members is a GNU extension}}
#endif
const struct {} es;
struct {int:5;} swnm;

View File

@ -0,0 +1,76 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -DNONE -Wno-gnu
// RUN: %clang_cc1 -fsyntax-only -verify %s -DALL -Wgnu
// RUN: %clang_cc1 -fsyntax-only -verify %s -DALL -Wno-gnu \
// RUN: -Wgnu-anonymous-struct -Wredeclared-class-member \
// RUN: -Wgnu-flexible-array-union-member -Wgnu-folding-constant \
// RUN: -Wgnu-empty-struct
// RUN: %clang_cc1 -fsyntax-only -verify %s -DNONE -Wgnu \
// RUN: -Wno-gnu-anonymous-struct -Wno-redeclared-class-member \
// RUN: -Wno-gnu-flexible-array-union-member -Wno-gnu-folding-constant \
// RUN: -Wno-gnu-empty-struct
// Additional disabled tests:
// %clang_cc1 -fsyntax-only -verify %s -DANONYMOUSSTRUCT -Wno-gnu -Wgnu-anonymous-struct
// %clang_cc1 -fsyntax-only -verify %s -DREDECLAREDCLASSMEMBER -Wno-gnu -Wredeclared-class-member
// %clang_cc1 -fsyntax-only -verify %s -DFLEXIBLEARRAYUNIONMEMBER -Wno-gnu -Wgnu-flexible-array-union-member
// %clang_cc1 -fsyntax-only -verify %s -DFOLDINGCONSTANT -Wno-gnu -Wgnu-folding-constant
// %clang_cc1 -fsyntax-only -verify %s -DEMPTYSTRUCT -Wno-gnu -Wgnu-empty-struct
#if NONE
// expected-no-diagnostics
#endif
#if ALL || ANONYMOUSSTRUCT
// expected-warning@+5 {{anonymous structs are a GNU extension}}
#endif
struct as {
int x;
struct {
int a;
float b;
};
};
#if ALL || REDECLAREDCLASSMEMBER
// expected-note@+6 {{previous declaration is here}}
// expected-warning@+6 {{class member cannot be redeclared}}
#endif
namespace rcm {
class A {
class X;
class X;
class X {};
};
}
#if ALL || FLEXIBLEARRAYUNIONMEMBER
// expected-warning@+6 {{flexible array member 'c1' in a union is a GNU extension}}
#endif
struct faum {
int l;
union {
int c1[];
};
};
#if ALL || FOLDINGCONSTANT
// expected-warning@+4 {{in-class initializer for static data member is not a constant expression; folding it to a constant is a GNU extension}}
#endif
struct fic {
static const int B = int(0.75 * 1000 * 1000);
};
#if ALL || EMPTYSTRUCT
// expected-warning@+3 {{flexible array member 'a' in otherwise empty struct is a GNU extension}}
#endif
struct ofam {int a[];};