linux-sparse.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] add basic support for C11
@ 2017-01-05  3:22 Luc Van Oostenryck
  2017-01-05  3:22 ` [PATCH 1/5] C11: teach sparse about '_Thread_local' Luc Van Oostenryck
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Luc Van Oostenryck @ 2017-01-05  3:22 UTC (permalink / raw)
  To: linux-sparse; +Cc: Luc Van Oostenryck

Add support for the new C11 keywords:
_Thread_local, _Noreturn, _Alignof() & _Alignas().
Also accept '-std=c11' or '-std=gnu11' as option and
define the associated macros like '__STDC_VERSION__'.


This serie can also be found as:
  git://github.com/lucvoo/sparse.git sent/c11-basic


Luc Van Oostenryck (5):
  C11: teach sparse about '_Thread_local'
  C11: teach sparse about '_Noreturn'
  C11: teach sparse about '_Alignof()'
  C11: teach sparse about '_Alignas()'
  C11: teach sparse about '--std={c11,gnu11}'

 expression.c                  |  1 +
 ident-list.h                  |  1 +
 lib.c                         | 21 ++++++++++++++++
 parse.c                       | 58 +++++++++++++++++++++++++++++++++++++++++++
 validation/c11-alignas.c      | 40 +++++++++++++++++++++++++++++
 validation/c11-alignof.c      | 12 +++++++++
 validation/c11-noreturn.c     |  9 +++++++
 validation/c11-stdc-version.c | 11 ++++++++
 validation/c11-thread-local.c |  9 +++++++
 9 files changed, 162 insertions(+)
 create mode 100644 validation/c11-alignas.c
 create mode 100644 validation/c11-alignof.c
 create mode 100644 validation/c11-noreturn.c
 create mode 100644 validation/c11-stdc-version.c
 create mode 100644 validation/c11-thread-local.c

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/5] C11: teach sparse about '_Thread_local'
  2017-01-05  3:22 [PATCH 0/5] add basic support for C11 Luc Van Oostenryck
@ 2017-01-05  3:22 ` Luc Van Oostenryck
  2017-01-05  3:22 ` [PATCH 2/5] C11: teach sparse about '_Noreturn' Luc Van Oostenryck
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Luc Van Oostenryck @ 2017-01-05  3:22 UTC (permalink / raw)
  To: linux-sparse; +Cc: Luc Van Oostenryck

This is simply a new name for GCC's '__thread' which was already
supported.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 parse.c                       | 1 +
 validation/c11-thread-local.c | 9 +++++++++
 2 files changed, 10 insertions(+)
 create mode 100644 validation/c11-thread-local.c

diff --git a/parse.c b/parse.c
index b52c6abe..7fc145db 100644
--- a/parse.c
+++ b/parse.c
@@ -443,6 +443,7 @@ static struct init_keyword {
 	{ "static",	NS_TYPEDEF, .op = &static_op },
 	{ "extern",	NS_TYPEDEF, .op = &extern_op },
 	{ "__thread",	NS_TYPEDEF, .op = &thread_op },
+	{ "_Thread_local",	NS_TYPEDEF, .op = &thread_op },
 
 	/* Statement */
 	{ "if",		NS_KEYWORD, .op = &if_op },
diff --git a/validation/c11-thread-local.c b/validation/c11-thread-local.c
new file mode 100644
index 00000000..464c3e16
--- /dev/null
+++ b/validation/c11-thread-local.c
@@ -0,0 +1,9 @@
+static _Thread_local int foo;
+
+/*
+ * check-name: c11-thread-local
+ * check-command: test-parsing -std=c11 $file
+ *
+ * check-output-ignore
+ * check-output-contains: \[tls\]
+ */
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/5] C11: teach sparse about '_Noreturn'
  2017-01-05  3:22 [PATCH 0/5] add basic support for C11 Luc Van Oostenryck
  2017-01-05  3:22 ` [PATCH 1/5] C11: teach sparse about '_Thread_local' Luc Van Oostenryck
@ 2017-01-05  3:22 ` Luc Van Oostenryck
  2017-01-05  3:22 ` [PATCH 3/5] C11: teach sparse about '_Alignof()' Luc Van Oostenryck
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Luc Van Oostenryck @ 2017-01-05  3:22 UTC (permalink / raw)
  To: linux-sparse; +Cc: Luc Van Oostenryck

This is mainly a new name for GCC's 'noreturn' attribute but defined
as a new function specifier.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 parse.c                   | 14 ++++++++++++++
 validation/c11-noreturn.c |  9 +++++++++
 2 files changed, 23 insertions(+)
 create mode 100644 validation/c11-noreturn.c

diff --git a/parse.c b/parse.c
index 7fc145db..f131d0e6 100644
--- a/parse.c
+++ b/parse.c
@@ -122,6 +122,12 @@ static struct symbol_op inline_op = {
 	.declarator = inline_specifier,
 };
 
+static declarator_t noreturn_specifier;
+static struct symbol_op noreturn_op = {
+	.type = KW_MODIFIER,
+	.declarator = noreturn_specifier,
+};
+
 static struct symbol_op auto_op = {
 	.type = KW_MODIFIER,
 	.declarator = auto_specifier,
@@ -432,6 +438,8 @@ static struct init_keyword {
 	{ "__inline",	NS_TYPEDEF, .op = &inline_op },
 	{ "__inline__",	NS_TYPEDEF, .op = &inline_op },
 
+	{ "_Noreturn",	NS_TYPEDEF, .op = &noreturn_op },
+
 	/* Ignored for now.. */
 	{ "restrict",	NS_TYPEDEF, .op = &restrict_op},
 	{ "__restrict",	NS_TYPEDEF, .op = &restrict_op},
@@ -1368,6 +1376,12 @@ static struct token *inline_specifier(struct token *next, struct decl_state *ctx
 	return next;
 }
 
+static struct token *noreturn_specifier(struct token *next, struct decl_state *ctx)
+{
+	apply_qualifier(&next->pos, &ctx->ctype, MOD_NORETURN);
+	return next;
+}
+
 static struct token *const_qualifier(struct token *next, struct decl_state *ctx)
 {
 	apply_qualifier(&next->pos, &ctx->ctype, MOD_CONST);
diff --git a/validation/c11-noreturn.c b/validation/c11-noreturn.c
new file mode 100644
index 00000000..bc20de82
--- /dev/null
+++ b/validation/c11-noreturn.c
@@ -0,0 +1,9 @@
+static _Noreturn void foo(void) { while (1) ; }
+
+/*
+ * check-name: c11-noreturn
+ * check-command: test-parsing -std=c11 $file
+ *
+ * check-output-ignore
+ * check-output-contains: \[noreturn\]
+ */
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/5] C11: teach sparse about '_Alignof()'
  2017-01-05  3:22 [PATCH 0/5] add basic support for C11 Luc Van Oostenryck
  2017-01-05  3:22 ` [PATCH 1/5] C11: teach sparse about '_Thread_local' Luc Van Oostenryck
  2017-01-05  3:22 ` [PATCH 2/5] C11: teach sparse about '_Noreturn' Luc Van Oostenryck
@ 2017-01-05  3:22 ` Luc Van Oostenryck
  2017-01-05  3:22 ` [PATCH 4/5] C11: teach sparse about '_Alignas()' Luc Van Oostenryck
  2017-01-05  3:22 ` [PATCH 5/5] C11: teach sparse about '--std={c11,gnu11}' Luc Van Oostenryck
  4 siblings, 0 replies; 6+ messages in thread
From: Luc Van Oostenryck @ 2017-01-05  3:22 UTC (permalink / raw)
  To: linux-sparse; +Cc: Luc Van Oostenryck

This is a new name for GCC's '__alignof()' operator which was
already supported.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 expression.c             |  1 +
 ident-list.h             |  1 +
 validation/c11-alignof.c | 12 ++++++++++++
 3 files changed, 14 insertions(+)
 create mode 100644 validation/c11-alignof.c

diff --git a/expression.c b/expression.c
index 7293d472..638639df 100644
--- a/expression.c
+++ b/expression.c
@@ -617,6 +617,7 @@ static struct token *unary_expression(struct token *token, struct expression **t
 				{ &sizeof_ident, EXPR_SIZEOF },
 				{ &__alignof___ident, EXPR_ALIGNOF },
 				{ &__alignof_ident, EXPR_ALIGNOF },
+				{ &_Alignof_ident, EXPR_ALIGNOF },
 				{ &__sizeof_ptr___ident, EXPR_PTRSIZEOF },
 			};
 			int i;
diff --git a/ident-list.h b/ident-list.h
index b65b667d..8cc66a50 100644
--- a/ident-list.h
+++ b/ident-list.h
@@ -31,6 +31,7 @@ IDENT(L);
 /* Extended gcc identifiers */
 IDENT(asm); IDENT_RESERVED(__asm); IDENT_RESERVED(__asm__);
 IDENT(alignof); IDENT_RESERVED(__alignof); IDENT_RESERVED(__alignof__); 
+IDENT_RESERVED(_Alignof);
 IDENT_RESERVED(__sizeof_ptr__);
 IDENT_RESERVED(__builtin_types_compatible_p);
 IDENT_RESERVED(__builtin_offsetof);
diff --git a/validation/c11-alignof.c b/validation/c11-alignof.c
new file mode 100644
index 00000000..238ef994
--- /dev/null
+++ b/validation/c11-alignof.c
@@ -0,0 +1,12 @@
+static int foo(void)
+{
+	return _Alignof(short);
+}
+
+/*
+ * check-name: c11-alignof
+ * check-command: test-linearize -std=c11 $file
+ *
+ * check-output-ignore
+ * check-output-contains: ret\\.32 *\$2
+ */
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/5] C11: teach sparse about '_Alignas()'
  2017-01-05  3:22 [PATCH 0/5] add basic support for C11 Luc Van Oostenryck
                   ` (2 preceding siblings ...)
  2017-01-05  3:22 ` [PATCH 3/5] C11: teach sparse about '_Alignof()' Luc Van Oostenryck
@ 2017-01-05  3:22 ` Luc Van Oostenryck
  2017-01-05  3:22 ` [PATCH 5/5] C11: teach sparse about '--std={c11,gnu11}' Luc Van Oostenryck
  4 siblings, 0 replies; 6+ messages in thread
From: Luc Van Oostenryck @ 2017-01-05  3:22 UTC (permalink / raw)
  To: linux-sparse; +Cc: Luc Van Oostenryck

This is quite similar to GCC's 'attribute(aligned(..))' but defined
as a new specifier and also accepting a typename as argument.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 parse.c                  | 43 +++++++++++++++++++++++++++++++++++++++++++
 validation/c11-alignas.c | 40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 83 insertions(+)
 create mode 100644 validation/c11-alignas.c

diff --git a/parse.c b/parse.c
index f131d0e6..6eca5686 100644
--- a/parse.c
+++ b/parse.c
@@ -128,6 +128,12 @@ static struct symbol_op noreturn_op = {
 	.declarator = noreturn_specifier,
 };
 
+static declarator_t alignas_specifier;
+static struct symbol_op alignas_op = {
+	.type = KW_MODIFIER,
+	.declarator = alignas_specifier,
+};
+
 static struct symbol_op auto_op = {
 	.type = KW_MODIFIER,
 	.declarator = auto_specifier,
@@ -440,6 +446,8 @@ static struct init_keyword {
 
 	{ "_Noreturn",	NS_TYPEDEF, .op = &noreturn_op },
 
+	{ "_Alignas",	NS_TYPEDEF, .op = &alignas_op },
+
 	/* Ignored for now.. */
 	{ "restrict",	NS_TYPEDEF, .op = &restrict_op},
 	{ "__restrict",	NS_TYPEDEF, .op = &restrict_op},
@@ -1382,6 +1390,41 @@ static struct token *noreturn_specifier(struct token *next, struct decl_state *c
 	return next;
 }
 
+static struct token *alignas_specifier(struct token *token, struct decl_state *ctx)
+{
+	int alignment = 0;
+
+	if (!match_op(token, '(')) {
+		sparse_error(token->pos, "expected '(' after _Alignas");
+		return token;
+	}
+	if (lookup_type(token->next)) {
+		struct symbol *sym = NULL;
+		token = typename(token->next, &sym, NULL);
+		sym = examine_symbol_type(sym);
+		alignment = sym->ctype.alignment;
+		token = expect(token, ')', "after _Alignas(...");
+	} else {
+		struct expression *expr = NULL;
+		token = parens_expression(token, &expr, "after _Alignas");
+		if (!expr)
+			return token;
+		alignment = const_expression_value(expr);
+	}
+
+	if (alignment < 0) {
+		warning(token->pos, "non-positive alignment");
+		return token;
+	}
+	if (alignment & (alignment-1)) {
+		warning(token->pos, "non-power-of-2 alignment");
+		return token;
+	}
+	if (alignment > ctx->ctype.alignment)
+		ctx->ctype.alignment = alignment;
+	return token;
+}
+
 static struct token *const_qualifier(struct token *next, struct decl_state *ctx)
 {
 	apply_qualifier(&next->pos, &ctx->ctype, MOD_CONST);
diff --git a/validation/c11-alignas.c b/validation/c11-alignas.c
new file mode 100644
index 00000000..4b264a5d
--- /dev/null
+++ b/validation/c11-alignas.c
@@ -0,0 +1,40 @@
+static _Alignas(8)	int v;
+static _Alignas(long)	int t;
+static _Alignas(void *)	int p;
+static _Alignas(int[4])	int a;
+static _Alignas(0)	int z;
+static _Alignas(3)	int bnpow2;
+static _Alignas(-1)	int bneg;
+static _Alignas(-2)	int bnegpow2;
+static _Alignas(v)	int bnc;
+static _Alignas(+)	int bsyn;
+
+static int check(void)
+{
+	if (_Alignof(v) != 8)
+		return -1;
+	if (_Alignof(t) != _Alignof(long))
+		return -1;
+	if (_Alignof(p) != _Alignof(void *))
+		return -1;
+	if (_Alignof(a) != _Alignof(int))
+		return -1;
+
+	return 0;
+}
+
+/*
+ * check-name: c11-alignas
+ * check-command: test-linearize -std=c11 $file
+ *
+ * check-error-start
+c11-alignas.c:6:25: warning: non-power-of-2 alignment
+c11-alignas.c:7:25: warning: non-positive alignment
+c11-alignas.c:8:25: warning: non-positive alignment
+c11-alignas.c:9:17: error: bad constant expression
+c11-alignas.c:10:17: error: Syntax error in unary expression
+ * check-error-end
+ *
+ * check-output-ignore
+ * check-output-contains: ret\\.32 *\$0
+ */
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 5/5] C11: teach sparse about '--std={c11,gnu11}'
  2017-01-05  3:22 [PATCH 0/5] add basic support for C11 Luc Van Oostenryck
                   ` (3 preceding siblings ...)
  2017-01-05  3:22 ` [PATCH 4/5] C11: teach sparse about '_Alignas()' Luc Van Oostenryck
@ 2017-01-05  3:22 ` Luc Van Oostenryck
  4 siblings, 0 replies; 6+ messages in thread
From: Luc Van Oostenryck @ 2017-01-05  3:22 UTC (permalink / raw)
  To: linux-sparse; +Cc: Luc Van Oostenryck

Now that support have been added for C11 new syntax we can accept
'--std={c11,gnu11}' no more dying with "Unsupported C dialect" message.
Also adjust __STDC_VERSION__ accordingly and define the few
associated feature macros (__STD_NO_ATOMICS__, ...).

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 lib.c                         | 21 +++++++++++++++++++++
 validation/c11-stdc-version.c | 11 +++++++++++
 2 files changed, 32 insertions(+)
 create mode 100644 validation/c11-stdc-version.c

diff --git a/lib.c b/lib.c
index e5b0bb63..49ff6906 100644
--- a/lib.c
+++ b/lib.c
@@ -250,6 +250,8 @@ int preprocess_only;
 static enum { STANDARD_C89,
               STANDARD_C94,
               STANDARD_C99,
+              STANDARD_C11,
+              STANDARD_GNU11,
               STANDARD_GNU89,
               STANDARD_GNU99, } standard = STANDARD_GNU89;
 
@@ -574,6 +576,8 @@ static void handle_switch_W_finalize(void)
 			case STANDARD_C99:
 			case STANDARD_GNU89:
 			case STANDARD_GNU99:
+			case STANDARD_C11:
+			case STANDARD_GNU11:
 				Wdeclarationafterstatement = 0;
 				break;
 
@@ -679,6 +683,14 @@ static char **handle_switch_s(char *arg, char **next)
 		else if (!strcmp (arg, "gnu99") || !strcmp (arg, "gnu9x"))
 			standard = STANDARD_GNU99;
 
+		else if (!strcmp(arg, "c11") ||
+			 !strcmp(arg, "c1x") ||
+			 !strcmp(arg, "iso9899:2011"))
+			standard = STANDARD_C11;
+
+		else if (!strcmp(arg, "gnu11"))
+			standard = STANDARD_GNU11;
+
 		else
 			die ("Unsupported C dialect");
 	}
@@ -971,6 +983,15 @@ void create_builtin_stream(void)
 			add_pre_buffer("#weak_define __STDC_VERSION__ 199901L\n");
 			break;
 
+		case STANDARD_C11:
+			add_pre_buffer("#weak_define __STRICT_ANSI__ 1\n");
+		case STANDARD_GNU11:
+			add_pre_buffer("#weak_define __STDC_NO_ATOMICS__ 1\n");
+			add_pre_buffer("#weak_define __STDC_NO_COMPLEX__ 1\n");
+			add_pre_buffer("#weak_define __STDC_NO_THREADS__ 1\n");
+			add_pre_buffer("#weak_define __STDC_VERSION__ 201112L\n");
+			break;
+
 		default:
 			assert (0);
 	}
diff --git a/validation/c11-stdc-version.c b/validation/c11-stdc-version.c
new file mode 100644
index 00000000..3acedd19
--- /dev/null
+++ b/validation/c11-stdc-version.c
@@ -0,0 +1,11 @@
+__STDC_VERSION__
+
+/*
+ * check-name: c11-stdc-version
+ * check-command: sparse -E -std=c11 $file
+ *
+ * check-output-start
+
+201112L
+ * check-output-end
+ */
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-01-05  3:30 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-01-05  3:22 [PATCH 0/5] add basic support for C11 Luc Van Oostenryck
2017-01-05  3:22 ` [PATCH 1/5] C11: teach sparse about '_Thread_local' Luc Van Oostenryck
2017-01-05  3:22 ` [PATCH 2/5] C11: teach sparse about '_Noreturn' Luc Van Oostenryck
2017-01-05  3:22 ` [PATCH 3/5] C11: teach sparse about '_Alignof()' Luc Van Oostenryck
2017-01-05  3:22 ` [PATCH 4/5] C11: teach sparse about '_Alignas()' Luc Van Oostenryck
2017-01-05  3:22 ` [PATCH 5/5] C11: teach sparse about '--std={c11,gnu11}' Luc Van Oostenryck

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).