[PATCH] explicit GNU flags

Peter N Lewis peter at stairways.com.au
Fri Aug 16 02:39:01 PDT 2013


This patch supersedes my previous patch and defines explicit flags for each of the eight remaining generic -gnu features.

Flags are:

	-gnu-alignof-expression
	-gnu-case-range
	-gnu-complex-integer
	-gnu-conditional-omitted-operand
	-gnu-empty-initializer
	-gnu-label-as-value
	-gnu-local-label
	-gnu-statement-expression

I would have preferred to do each as an independent patch, but because they all touch the "def GNU : DiagGroup" line they would conflict which each other unless applied in exactly the right order. They are all related in any event, simply adding explicit control over the features covered by -gnu.

For conditional-omitted-operand, I changed the error message slightly, from:

	use of GNU ?: expression extension, eliding middle term

to

	use of GNU ?: conditional expression extension, omitting middle operand

to better match the GCC documentation of the feature and hence the flag name.

gnu-label-as-value covers both errors "use of GNU address-of-label extension" and "use of GNU indirect-goto extension" as it would seem to me that one is useless without the other, so they are functionally the same feature.

There does not seem to be any way to get the "use of GNU empty initializer extension" warning without also getting some other warning (such as "zero size arrays are an extension").

There are test cases for each of the flags.

I'd like to move on to some other similar patches now, so hopefully I can get either approval of this patch or some feedback or something.  


Index: include/clang/Basic/DiagnosticGroups.td
===================================================================
--- include/clang/Basic/DiagnosticGroups.td	(revision 188533)
+++ include/clang/Basic/DiagnosticGroups.td	(working copy)
@@ -21,6 +21,7 @@
 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 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 @@
                                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 : 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 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 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">;
 
Index: include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- include/clang/Basic/DiagnosticParseKinds.td	(revision 188533)
+++ include/clang/Basic/DiagnosticParseKinds.td	(working copy)
@@ -54,7 +54,7 @@
 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 @@
   "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 @@
   "_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 @@
   "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">;
Index: test/Sema/complex-integer.c
===================================================================
--- test/Sema/complex-integer.c	(revision 0)
+++ test/Sema/complex-integer.c	(revision 0)
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DNONE
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wgnu -DEXT
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wgnu-complex-integer -DEXT
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wgnu -Wno-gnu-complex-integer -DNONE
+
+#if NONE
+// expected-no-diagnostics
+#elif EXT
+// expected-warning at 12 {{complex integer types are a GNU extension}}
+#endif
+
+_Complex short int y;
Index: test/Sema/case-range.c
===================================================================
--- test/Sema/case-range.c	(revision 0)
+++ test/Sema/case-range.c	(revision 0)
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DNONE
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wgnu -DEXT
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wgnu-case-range -DEXT
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wgnu -Wno-gnu-case-range -DNONE
+
+#if NONE
+// expected-no-diagnostics
+#elif EXT
+// expected-warning at 14 {{use of GNU case range extension}}
+#endif
+
+void foo(int X) {
+  switch (X) {
+  case 42 ... 44: ;
+  }
+}
Index: test/Sema/conditional-omitted-operand.c
===================================================================
--- test/Sema/conditional-omitted-operand.c	(revision 0)
+++ test/Sema/conditional-omitted-operand.c	(revision 0)
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -verify %s -DNONE
+// RUN: %clang_cc1 -verify %s -Wgnu -DEXT
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wgnu-conditional-omitted-operand -DEXT
+// RUN: %clang_cc1 -verify %s -Wgnu -Wno-gnu-conditional-omitted-operand -DNONE
+
+#if NONE
+// expected-no-diagnostics
+#elif EXT
+// expected-warning at 12 {{use of GNU ?: conditional expression extension, omitting middle operand}}
+#endif
+
+static const char* s = 	(const char*)0 ?: "Null";
Index: test/Sema/local-label.c
===================================================================
--- test/Sema/local-label.c	(revision 0)
+++ test/Sema/local-label.c	(revision 0)
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DNONE
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wgnu -DEXT
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wgnu-local-label -DEXT
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wgnu -Wno-gnu-local-label -DNONE
+
+#if NONE
+// expected-no-diagnostics
+#elif EXT
+// expected-warning at 14 {{use of GNU locally declared label extension}}
+#endif
+
+void f() {
+	{
+		__label__ foo;
+		goto foo;
+foo:
+		;
+	}
+}
Index: test/Sema/alignof-expression.c
===================================================================
--- test/Sema/alignof-expression.c	(revision 0)
+++ test/Sema/alignof-expression.c	(revision 0)
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -DERR %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -DERR -Wgnu %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -DNONE -Wno-gnu-alignof-expression %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -DNONE -Wno-gnu %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -DNONE -Wgnu -Wno-gnu-alignof-expression %s
+
+char align;
+
+#if NONE
+// expected-no-diagnostics
+#elif ERR
+// expected-warning at 15{{'_Alignof' applied to an expression is a GNU extension}}
+#endif
+
+_Static_assert(_Alignof(align) == 1, "k's alignment is wrong");
Index: test/Sema/empty-initializer.c
===================================================================
--- test/Sema/empty-initializer.c	(revision 0)
+++ test/Sema/empty-initializer.c	(revision 0)
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DNONE
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wgnu -DZERO -DEMPTY
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wgnu-empty-initializer -DEMPTY
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wzero-length-array -DZERO
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wgnu -Wno-gnu-empty-initializer -DZERO
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wgnu -Wno-zero-length-array -DEMPTY
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wgnu -Wno-zero-length-array -Wno-gnu-empty-initializer -DNONE
+
+#if NONE
+// expected-no-diagnostics
+#else
+#if ZERO
+// expected-warning at 20 {{zero size arrays are an extension}}
+#endif
+#if EMPTY
+// expected-warning at 20 {{use of GNU empty initializer extension}}
+#endif
+#endif
+
+int i[] = {};
Index: test/Sema/label-as-value.c
===================================================================
--- test/Sema/label-as-value.c	(revision 0)
+++ test/Sema/label-as-value.c	(revision 0)
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DNONE
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wgnu -DEXT
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wgnu-label-as-value -DEXT
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wgnu -Wno-gnu-label-as-value -DNONE
+
+#if NONE
+// expected-no-diagnostics
+#elif EXT
+// expected-warning at 15 {{use of GNU address-of-label extension}}
+// expected-warning at 17 {{use of GNU indirect-goto extension}}
+#endif
+
+void f() {
+	void *ptr;
+	ptr = &&foo;
+foo:
+	goto *ptr;
+}
Index: test/Sema/statement-expression.c
===================================================================
--- test/Sema/statement-expression.c	(revision 0)
+++ test/Sema/statement-expression.c	(revision 0)
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DNONE
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wgnu -DEXT
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wgnu-statement-expression -DEXT
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wgnu -Wno-gnu-statement-expression -DNONE
+
+#if NONE
+// expected-no-diagnostics
+#elif EXT
+// expected-warning at 14 {{use of GNU statement expression extension}}
+#endif
+
+void foo()
+{
+	int a = ({ 1; });
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: explicit-gnu-flags.diff
Type: application/octet-stream
Size: 11951 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130816/ff085fb9/attachment.obj>


More information about the cfe-commits mailing list