All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] restricted pointers
@ 2017-04-05 21:09 Luc Van Oostenryck
  2017-04-05 21:09 ` [PATCH 1/9] remove never-used MOD_TYPEDEF Luc Van Oostenryck
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Luc Van Oostenryck @ 2017-04-05 21:09 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

The goal of this series is to add minimal support for C99's
'restrict' type qualifier.
As preparatory steps this series also contains:
- a cleanup of the #define MOD_...
- a change on how errors inhibit warnings
and as bonus it also contains:
- support for '_Atomic' type *qualifier*


This series is available at:
	git://github.com/lucvoo/sparse.git restricted-pointers
based on commit:
	14964df5373292af78b29529d4fc7e1a26b67a97 (sparse-next @ 2017-03-31)
up to commit:
	d109442871cfd2065ae7d3440981ab800054f241


Luc Van Oostenryck (9):
  remove never-used MOD_TYPEDEF
  avoid warnings about using 0 instead of NULL
  finer control over error vs. warnings
  MOD_ACCESSED is not a type modifier ...
  reorganize the definition of the modifiers
  MOD_STORAGE redundancy
  MOD_QUALIFIER
  associate MOD_RESTRICT with restrict-qualified variables
  add support for C11's _Atomic as type qualifier


-- Luc Van Oostenryck

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

* [PATCH 1/9] remove never-used MOD_TYPEDEF
  2017-04-05 21:09 [PATCH 0/9] restricted pointers Luc Van Oostenryck
@ 2017-04-05 21:09 ` Luc Van Oostenryck
  2017-04-05 21:09 ` [PATCH 2/9] avoid warnings about using 0 instead of NULL Luc Van Oostenryck
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Luc Van Oostenryck @ 2017-04-05 21:09 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 gdbhelpers   | 3 ---
 show-parse.c | 1 -
 symbol.h     | 2 --
 3 files changed, 6 deletions(-)

diff --git a/gdbhelpers b/gdbhelpers
index 86347863a..87ab5b8e9 100644
--- a/gdbhelpers
+++ b/gdbhelpers
@@ -128,9 +128,6 @@ define gdb_show_ctype
 	if ($arg0->modifiers & MOD_LONGLONGLONG)
 		printf "MOD_LONGLONGLONG "
 	end
-	if ($arg0->modifiers & MOD_TYPEDEF)
-		printf "MOD_TYPEDEF "
-	end
 	if ($arg0->modifiers & MOD_INLINE)
 		printf "MOD_INLINE "
 	end
diff --git a/show-parse.c b/show-parse.c
index d365d737f..2adeae961 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -132,7 +132,6 @@ const char *modifier_string(unsigned long mod)
 		{MOD_LONG,		"[long]"},
 		{MOD_LONGLONG,		"[long long]"},
 		{MOD_LONGLONGLONG,	"[long long long]"},
-		{MOD_TYPEDEF,		"[typedef]"},
 		{MOD_TLS,		"[tls]"},
 		{MOD_INLINE,		"inline"},
 		{MOD_ADDRESSABLE,	"[addressable]"},
diff --git a/symbol.h b/symbol.h
index 36f8345b5..b8b81fdeb 100644
--- a/symbol.h
+++ b/symbol.h
@@ -216,8 +216,6 @@ struct symbol {
 #define MOD_LONGLONGLONG	0x1000
 #define MOD_PURE	0x2000
 
-#define MOD_TYPEDEF	0x10000

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

* [PATCH 2/9] avoid warnings about using 0 instead of NULL
  2017-04-05 21:09 [PATCH 0/9] restricted pointers Luc Van Oostenryck
  2017-04-05 21:09 ` [PATCH 1/9] remove never-used MOD_TYPEDEF Luc Van Oostenryck
@ 2017-04-05 21:09 ` Luc Van Oostenryck
  2017-04-05 21:09 ` [PATCH 3/9] finer control over error vs. warnings Luc Van Oostenryck
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Luc Van Oostenryck @ 2017-04-05 21:09 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

These warning wehere not emitted because of previous errors.
But ...
---
 validation/function-redecl.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/validation/function-redecl.c b/validation/function-redecl.c
index 7fbceb43a..475f18e79 100644
--- a/validation/function-redecl.c
+++ b/validation/function-redecl.c
@@ -1,5 +1,5 @@
 #define __user	__attribute__((address_space(1)))

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

* [PATCH 3/9] finer control over error vs. warnings
  2017-04-05 21:09 [PATCH 0/9] restricted pointers Luc Van Oostenryck
  2017-04-05 21:09 ` [PATCH 1/9] remove never-used MOD_TYPEDEF Luc Van Oostenryck
  2017-04-05 21:09 ` [PATCH 2/9] avoid warnings about using 0 instead of NULL Luc Van Oostenryck
@ 2017-04-05 21:09 ` Luc Van Oostenryck
  2017-04-05 21:09 ` [PATCH 4/9] MOD_ACCESSED is not a type modifier Luc Van Oostenryck
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Luc Van Oostenryck @ 2017-04-05 21:09 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

Until now once an error is emitted, warnings are no more emitted,
only others errors are.

While it make some sense as once an error is encountered, things
can be left in an incoherent state and could cause lots of useless
warninsg because of this incoherence.
However, it's also quite annoying as even unrelated warnings are
so silenced.

Fix this by:
- use a specific flag for this: 'has_error'
- make the distinction between the current phase and some previous
  phases (but for now we only care about parsing vs evaluation)
- if an error have been emitted in a previous phase (at parsing)
  warning are suppressed for the current phase and all future
  phases
- if an error is emitted in the current phase (evaluation) the
  flag is reset after each functions/symbols

So, for example, a type error in function a() won't suppress
warnings for function b(), while a parsing error still inhibit
all further warnings.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 evaluate.c | 1 +
 lib.c      | 7 +++++--
 lib.h      | 4 ++++
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/evaluate.c b/evaluate.c
index 47eeaef2e..2cc4b1eeb 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -3214,6 +3214,7 @@ void evaluate_symbol_list(struct symbol_list *list)
 	struct symbol *sym;
 
 	FOR_EACH_PTR(list, sym) {
+		has_error &= ~ERROR_CURR_PHASE;
 		evaluate_symbol(sym);
 		check_duplicates(sym);
 	} END_FOR_EACH_PTR(sym);
diff --git a/lib.c b/lib.c
index 272d2c88a..d6c893e71 100644
--- a/lib.c
+++ b/lib.c
@@ -47,6 +47,7 @@
 
 int verbose, optimize, optimize_size, preprocessing;
 int die_if_error = 0;
+int has_error = 0;
 
 #ifndef __GNUC__
 # define __GNUC__ 2
@@ -133,7 +134,7 @@ static void do_error(struct position pos, const char * fmt, va_list args)
         die_if_error = 1;
 	show_info = 1;
 	/* Shut up warnings after an error */
-	max_warnings = 0;
+	has_error |= ERROR_CURR_PHASE;
 	if (errors > 100) {
 		static int once = 0;
 		show_info = 0;
@@ -158,7 +159,7 @@ void warning(struct position pos, const char * fmt, ...)
 		return;
 	}
 
-	if (!max_warnings) {
+	if (!max_warnings || has_error) {
 		show_info = 0;
 		return;
 	}
@@ -1208,6 +1209,8 @@ struct symbol_list * sparse(char *filename)
 {
 	struct symbol_list *res = __sparse(filename);
 
+	if (has_error & ERROR_CURR_PHASE)
+		has_error = ERROR_PREV_PHASE;
 	/* Evaluate the complete symbol list */
 	evaluate_symbol_list(res);
 
diff --git a/lib.h b/lib.h
index 134e56040..7ed889c60 100644
--- a/lib.h
+++ b/lib.h
@@ -97,6 +97,10 @@ extern void sparse_error(struct position, const char *, ...) FORMAT_ATTR(2);
 extern void error_die(struct position, const char *, ...) FORMAT_ATTR(2) NORETURN_ATTR;
 extern void expression_error(struct expression *, const char *, ...) FORMAT_ATTR(2);
 
+#define	ERROR_CURR_PHASE	(1 << 0)
+#define	ERROR_PREV_PHASE	(1 << 1)
+extern int has_error;
+
 extern void add_pre_buffer(const char *fmt, ...) FORMAT_ATTR(1);
 
 extern int preprocess_only;
-- 
2.12.0


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

* [PATCH 4/9] MOD_ACCESSED is not a type modifier ...
  2017-04-05 21:09 [PATCH 0/9] restricted pointers Luc Van Oostenryck
                   ` (2 preceding siblings ...)
  2017-04-05 21:09 ` [PATCH 3/9] finer control over error vs. warnings Luc Van Oostenryck
@ 2017-04-05 21:09 ` Luc Van Oostenryck
  2017-04-05 21:09 ` [PATCH 5/9] reorganize the definition of the modifiers Luc Van Oostenryck
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Luc Van Oostenryck @ 2017-04-05 21:09 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

but is used to track which inline functions are
effectively used. So better remove it from the MOD_...
and implement the same functionality via a flag
in struct symbol.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 gdbhelpers   | 3 ---
 parse.c      | 2 +-
 show-parse.c | 1 -
 symbol.c     | 4 ++--
 symbol.h     | 4 ++--
 5 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/gdbhelpers b/gdbhelpers
index 87ab5b8e9..3d1148a87 100644
--- a/gdbhelpers
+++ b/gdbhelpers
@@ -140,9 +140,6 @@ define gdb_show_ctype
 	if ($arg0->modifiers & MOD_NODEREF)
 		printf "MOD_NODEREF "
 	end
-	if ($arg0->modifiers & MOD_ACCESSED)
-		printf "MOD_ACCESSED "
-	end
 	if ($arg0->modifiers & MOD_TOPLEVEL)
 		printf "MOD_TOPLEVEL "
 	end
diff --git a/parse.c b/parse.c
index 80f0337cc..4c3ebbaac 100644
--- a/parse.c
+++ b/parse.c
@@ -2144,7 +2144,7 @@ static struct statement *start_function(struct symbol *sym)
 	start_function_scope();
 	ret = alloc_symbol(sym->pos, SYM_NODE);
 	ret->ctype = sym->ctype.base_type->ctype;
-	ret->ctype.modifiers &= ~(MOD_STORAGE | MOD_CONST | MOD_VOLATILE | MOD_TLS | MOD_INLINE | MOD_ADDRESSABLE | MOD_NOCAST | MOD_NODEREF | MOD_ACCESSED | MOD_TOPLEVEL);
+	ret->ctype.modifiers &= ~(MOD_STORAGE | MOD_CONST | MOD_VOLATILE | MOD_TLS | MOD_INLINE | MOD_ADDRESSABLE | MOD_NOCAST | MOD_NODEREF | MOD_TOPLEVEL);
 	ret->ctype.modifiers |= (MOD_AUTO | MOD_REGISTER);
 	bind_symbol(ret, &return_ident, NS_ITERATOR);
 	stmt->ret = ret;
diff --git a/show-parse.c b/show-parse.c
index 2adeae961..3364aec5e 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -137,7 +137,6 @@ const char *modifier_string(unsigned long mod)
 		{MOD_ADDRESSABLE,	"[addressable]"},
 		{MOD_NOCAST,		"[nocast]"},
 		{MOD_NODEREF,		"[noderef]"},
-		{MOD_ACCESSED,		"[accessed]"},
 		{MOD_TOPLEVEL,		"[toplevel]"},
 		{MOD_ASSIGNED,		"[assigned]"},
 		{MOD_TYPE,		"[type]"},
diff --git a/symbol.c b/symbol.c
index 08c85f40e..2e7fcf16e 100644
--- a/symbol.c
+++ b/symbol.c
@@ -48,9 +48,9 @@ struct symbol_list *translation_unit_used_list = NULL;
 void access_symbol(struct symbol *sym)
 {
 	if (sym->ctype.modifiers & MOD_INLINE) {
-		if (!(sym->ctype.modifiers & MOD_ACCESSED)) {
+		if (!sym->accessed) {
 			add_symbol(&translation_unit_used_list, sym);
-			sym->ctype.modifiers |= MOD_ACCESSED;
+			sym->accessed = 1;
 		}
 	}
 }
diff --git a/symbol.h b/symbol.h
index b8b81fdeb..5192cacd9 100644
--- a/symbol.h
+++ b/symbol.h
@@ -173,6 +173,7 @@ struct symbol {
 					string:1,
 					designated_init:1,
 					forced_arg:1,
+					accessed:1,
 					transparent_union:1;
 			struct expression *array_size;
 			struct ctype ctype;
@@ -222,7 +223,6 @@ struct symbol {
 
 #define MOD_NOCAST	0x100000
 #define MOD_NODEREF	0x200000
-#define MOD_ACCESSED	0x400000
 #define MOD_TOPLEVEL	0x800000	// scoping..
 
 #define MOD_ASSIGNED	0x2000000
@@ -242,7 +242,7 @@ struct symbol {
 #define MOD_SPECIFIER	(MOD_CHAR | MOD_SHORT | MOD_LONG_ALL | MOD_SIGNEDNESS)
 #define MOD_SIZE	(MOD_CHAR | MOD_SHORT | MOD_LONG_ALL)
 #define MOD_IGNORE (MOD_TOPLEVEL | MOD_STORAGE | MOD_ADDRESSABLE |	\
-	MOD_ASSIGNED | MOD_USERTYPE | MOD_ACCESSED | MOD_EXPLICITLY_SIGNED)
+	MOD_ASSIGNED | MOD_USERTYPE | MOD_EXPLICITLY_SIGNED)
 #define MOD_PTRINHERIT (MOD_VOLATILE | MOD_CONST | MOD_NODEREF | MOD_NORETURN | MOD_NOCAST)
 /* modifiers preserved by typeof() operator */
 #define MOD_TYPEOF	(MOD_VOLATILE | MOD_CONST | MOD_NOCAST | MOD_SPECIFIER)
-- 
2.12.0


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

* [PATCH 5/9] reorganize the definition of the modifiers
  2017-04-05 21:09 [PATCH 0/9] restricted pointers Luc Van Oostenryck
                   ` (3 preceding siblings ...)
  2017-04-05 21:09 ` [PATCH 4/9] MOD_ACCESSED is not a type modifier Luc Van Oostenryck
@ 2017-04-05 21:09 ` Luc Van Oostenryck
  2017-04-05 21:09 ` [PATCH 6/9] MOD_STORAGE redundancy Luc Van Oostenryck
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Luc Van Oostenryck @ 2017-04-05 21:09 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

Now they are grouped a bit more logically.

Note: MOD_ASSIGNED & MOD_ADDRESSABLE are not type modifiers
      but properties of the symbol. As such they should be
      moved to struct symbol. However, as they should be
      correctly propagated to the symbol components if any,
      better to leave them as is.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 symbol.h | 65 ++++++++++++++++++++++++++++++++--------------------------------
 1 file changed, 32 insertions(+), 33 deletions(-)

diff --git a/symbol.h b/symbol.h
index 5192cacd9..b6c777253 100644
--- a/symbol.h
+++ b/symbol.h
@@ -200,39 +200,38 @@ struct symbol {
 };
 
 /* Modifiers */
-#define MOD_AUTO	0x0001
-#define MOD_REGISTER	0x0002
-#define MOD_STATIC	0x0004
-#define MOD_EXTERN	0x0008
-
-#define MOD_CONST	0x0010
-#define MOD_VOLATILE	0x0020
-#define MOD_SIGNED	0x0040
-#define MOD_UNSIGNED	0x0080
-
-#define MOD_CHAR	0x0100
-#define MOD_SHORT	0x0200
-#define MOD_LONG	0x0400
-#define MOD_LONGLONG	0x0800
-#define MOD_LONGLONGLONG	0x1000
-#define MOD_PURE	0x2000
-
-#define MOD_TLS		0x20000
-#define MOD_INLINE	0x40000
-#define MOD_ADDRESSABLE	0x80000
-
-#define MOD_NOCAST	0x100000
-#define MOD_NODEREF	0x200000
-#define MOD_TOPLEVEL	0x800000	// scoping..
-
-#define MOD_ASSIGNED	0x2000000
-#define MOD_TYPE	0x4000000
-#define MOD_SAFE	0x8000000	// non-null/non-trapping pointer
-
-#define MOD_USERTYPE	0x10000000
-#define MOD_NORETURN	0x20000000
-#define MOD_EXPLICITLY_SIGNED	0x40000000
-#define MOD_BITWISE	0x80000000
+#define MOD_AUTO		0x00000001
+#define MOD_REGISTER		0x00000002
+#define MOD_STATIC		0x00000004
+#define MOD_EXTERN		0x00000008
+#define MOD_TOPLEVEL		0x00000010	// scoping..
+#define MOD_TLS			0x00000020
+#define MOD_INLINE		0x00000040
+
+#define MOD_ASSIGNED		0x00000080
+#define MOD_ADDRESSABLE		0x00000100
+
+#define MOD_CONST		0x00000200
+#define MOD_VOLATILE		0x00000400
+
+#define MOD_SIGNED		0x00002000
+#define MOD_UNSIGNED		0x00004000
+#define MOD_EXPLICITLY_SIGNED	0x00008000
+
+#define MOD_TYPE		0x00010000
+#define MOD_USERTYPE		0x00020000
+#define MOD_CHAR		0x00040000
+#define MOD_SHORT		0x00080000
+#define MOD_LONG		0x00100000
+#define MOD_LONGLONG		0x00200000
+#define MOD_LONGLONGLONG	0x00400000
+
+#define MOD_SAFE		0x00800000	// non-null/non-trapping pointer
+#define MOD_PURE		0x01000000
+#define MOD_BITWISE		0x02000000
+#define MOD_NOCAST		0x04000000
+#define MOD_NODEREF		0x08000000
+#define MOD_NORETURN		0x10000000
 
 
 #define MOD_NONLOCAL	(MOD_EXTERN | MOD_TOPLEVEL)
-- 
2.12.0


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

* [PATCH 6/9] MOD_STORAGE redundancy
  2017-04-05 21:09 [PATCH 0/9] restricted pointers Luc Van Oostenryck
                   ` (4 preceding siblings ...)
  2017-04-05 21:09 ` [PATCH 5/9] reorganize the definition of the modifiers Luc Van Oostenryck
@ 2017-04-05 21:09 ` Luc Van Oostenryck
  2017-04-05 21:09 ` [PATCH 7/9] MOD_QUALIFIER Luc Van Oostenryck
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Luc Van Oostenryck @ 2017-04-05 21:09 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

---
 parse.c  | 2 +-
 symbol.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/parse.c b/parse.c
index 4c3ebbaac..7d86ccce3 100644
--- a/parse.c
+++ b/parse.c
@@ -2144,7 +2144,7 @@ static struct statement *start_function(struct symbol *sym)
 	start_function_scope();
 	ret = alloc_symbol(sym->pos, SYM_NODE);
 	ret->ctype = sym->ctype.base_type->ctype;
-	ret->ctype.modifiers &= ~(MOD_STORAGE | MOD_CONST | MOD_VOLATILE | MOD_TLS | MOD_INLINE | MOD_ADDRESSABLE | MOD_NOCAST | MOD_NODEREF | MOD_TOPLEVEL);
+	ret->ctype.modifiers &= ~(MOD_STORAGE | MOD_TLS | MOD_CONST | MOD_VOLATILE | MOD_ADDRESSABLE | MOD_NOCAST | MOD_NODEREF);
 	ret->ctype.modifiers |= (MOD_AUTO | MOD_REGISTER);
 	bind_symbol(ret, &return_ident, NS_ITERATOR);
 	stmt->ret = ret;
diff --git a/symbol.h b/symbol.h
index b6c777253..a90efc898 100644
--- a/symbol.h
+++ b/symbol.h
@@ -240,7 +240,7 @@ struct symbol {
 #define MOD_LONG_ALL	(MOD_LONG | MOD_LONGLONG | MOD_LONGLONGLONG)
 #define MOD_SPECIFIER	(MOD_CHAR | MOD_SHORT | MOD_LONG_ALL | MOD_SIGNEDNESS)
 #define MOD_SIZE	(MOD_CHAR | MOD_SHORT | MOD_LONG_ALL)
-#define MOD_IGNORE (MOD_TOPLEVEL | MOD_STORAGE | MOD_ADDRESSABLE |	\
+#define MOD_IGNORE	(MOD_STORAGE | MOD_ADDRESSABLE |	\
 	MOD_ASSIGNED | MOD_USERTYPE | MOD_EXPLICITLY_SIGNED)
 #define MOD_PTRINHERIT (MOD_VOLATILE | MOD_CONST | MOD_NODEREF | MOD_NORETURN | MOD_NOCAST)
 /* modifiers preserved by typeof() operator */
-- 
2.12.0


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

* [PATCH 7/9] MOD_QUALIFIER
  2017-04-05 21:09 [PATCH 0/9] restricted pointers Luc Van Oostenryck
                   ` (5 preceding siblings ...)
  2017-04-05 21:09 ` [PATCH 6/9] MOD_STORAGE redundancy Luc Van Oostenryck
@ 2017-04-05 21:09 ` Luc Van Oostenryck
  2017-04-05 21:09 ` [PATCH 8/9] associate MOD_RESTRICT with restrict-qualified variables Luc Van Oostenryck
  2017-04-05 21:09 ` [PATCH 9/9] add support for C11's _Atomic as type qualifier Luc Van Oostenryck
  8 siblings, 0 replies; 10+ messages in thread
From: Luc Van Oostenryck @ 2017-04-05 21:09 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

---
 evaluate.c | 2 +-
 expand.c   | 2 +-
 parse.c    | 2 +-
 symbol.h   | 5 +++--
 4 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/evaluate.c b/evaluate.c
index 47eeaef2e..b93982e19 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -627,7 +627,7 @@ static struct symbol *evaluate_ptr_add(struct expression *expr, struct symbol *i
 
 static void examine_fn_arguments(struct symbol *fn);
 
-#define MOD_IGN (MOD_VOLATILE | MOD_CONST | MOD_PURE)
+#define MOD_IGN (MOD_QUALIFIER | MOD_PURE)
 
 const char *type_difference(struct ctype *c1, struct ctype *c2,
 	unsigned long mod1, unsigned long mod2)
diff --git a/expand.c b/expand.c
index 11f7255bf..7af91e8e5 100644
--- a/expand.c
+++ b/expand.c
@@ -479,7 +479,7 @@ static int expand_comma(struct expression *expr)
 	return cost;
 }
 
-#define MOD_IGN (MOD_VOLATILE | MOD_CONST)
+#define MOD_IGN (MOD_QUALIFIER)
 
 static int compare_types(int op, struct symbol *left, struct symbol *right)
 {
diff --git a/parse.c b/parse.c
index 7d86ccce3..897d4caa4 100644
--- a/parse.c
+++ b/parse.c
@@ -2144,7 +2144,7 @@ static struct statement *start_function(struct symbol *sym)
 	start_function_scope();
 	ret = alloc_symbol(sym->pos, SYM_NODE);
 	ret->ctype = sym->ctype.base_type->ctype;
-	ret->ctype.modifiers &= ~(MOD_STORAGE | MOD_TLS | MOD_CONST | MOD_VOLATILE | MOD_ADDRESSABLE | MOD_NOCAST | MOD_NODEREF);
+	ret->ctype.modifiers &= ~(MOD_STORAGE | MOD_TLS | MOD_QUALIFIER | MOD_ADDRESSABLE | MOD_NOCAST | MOD_NODEREF);
 	ret->ctype.modifiers |= (MOD_AUTO | MOD_REGISTER);
 	bind_symbol(ret, &return_ident, NS_ITERATOR);
 	stmt->ret = ret;
diff --git a/symbol.h b/symbol.h
index a90efc898..16d58594e 100644
--- a/symbol.h
+++ b/symbol.h
@@ -242,9 +242,10 @@ struct symbol {
 #define MOD_SIZE	(MOD_CHAR | MOD_SHORT | MOD_LONG_ALL)
 #define MOD_IGNORE	(MOD_STORAGE | MOD_ADDRESSABLE |	\
 	MOD_ASSIGNED | MOD_USERTYPE | MOD_EXPLICITLY_SIGNED)
-#define MOD_PTRINHERIT (MOD_VOLATILE | MOD_CONST | MOD_NODEREF | MOD_NORETURN | MOD_NOCAST)
+#define	MOD_QUALIFIER	(MOD_CONST | MOD_VOLATILE)
+#define MOD_PTRINHERIT	(MOD_QUALIFIER | MOD_NODEREF | MOD_NORETURN | MOD_NOCAST)
 /* modifiers preserved by typeof() operator */
-#define MOD_TYPEOF	(MOD_VOLATILE | MOD_CONST | MOD_NOCAST | MOD_SPECIFIER)
+#define MOD_TYPEOF	(MOD_QUALIFIER | MOD_NOCAST | MOD_SPECIFIER)
 
 
 /* Current parsing/evaluation function */
-- 
2.12.0


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

* [PATCH 8/9] associate MOD_RESTRICT with restrict-qualified variables
  2017-04-05 21:09 [PATCH 0/9] restricted pointers Luc Van Oostenryck
                   ` (6 preceding siblings ...)
  2017-04-05 21:09 ` [PATCH 7/9] MOD_QUALIFIER Luc Van Oostenryck
@ 2017-04-05 21:09 ` Luc Van Oostenryck
  2017-04-05 21:09 ` [PATCH 9/9] add support for C11's _Atomic as type qualifier Luc Van Oostenryck
  8 siblings, 0 replies; 10+ messages in thread
From: Luc Van Oostenryck @ 2017-04-05 21:09 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 gdbhelpers                   |  3 ++
 parse.c                      | 16 +++++---
 show-parse.c                 |  1 +
 symbol.h                     |  3 +-
 validation/optim/restrict.c  | 73 ++++++++++++++++++++++++++++++++++
 validation/reload-aliasing.c | 42 ++++++++++++++++++++
 validation/restrict.c        | 93 ++++++++++++++++++++++++++++++++++++++++++++
 validation/typeof-mods.c     | 14 +++++++
 8 files changed, 239 insertions(+), 6 deletions(-)
 create mode 100644 validation/optim/restrict.c
 create mode 100644 validation/reload-aliasing.c
 create mode 100644 validation/restrict.c

diff --git a/gdbhelpers b/gdbhelpers
index 3d1148a87..f6399d3bc 100644
--- a/gdbhelpers
+++ b/gdbhelpers
@@ -107,6 +107,9 @@ define gdb_show_ctype
 	if ($arg0->modifiers & MOD_VOLATILE)
 		printf "MOD_VOLATILE "
 	end
+	if ($arg0->modifiers & MOD_RESTRICT)
+		printf "MOD_RESTRICT "
+	end
 	if ($arg0->modifiers & MOD_SIGNED)
 		printf "MOD_SIGNED "
 	end
diff --git a/parse.c b/parse.c
index 897d4caa4..14fc2b9d1 100644
--- a/parse.c
+++ b/parse.c
@@ -58,6 +58,7 @@ static declarator_t
 	typedef_specifier, inline_specifier, auto_specifier,
 	register_specifier, static_specifier, extern_specifier,
 	thread_specifier, const_qualifier, volatile_qualifier;
+static declarator_t restrict_qualifier;
 
 static struct token *parse_if_statement(struct token *token, struct statement *stmt);
 static struct token *parse_return_statement(struct token *token, struct statement *stmt);
@@ -173,6 +174,7 @@ static struct symbol_op volatile_op = {
 
 static struct symbol_op restrict_op = {
 	.type = KW_QUALIFIER,
+	.declarator = restrict_qualifier,
 };
 
 static struct symbol_op typeof_op = {
@@ -416,6 +418,9 @@ static struct init_keyword {
 	{ "volatile",	NS_TYPEDEF, .op = &volatile_op },
 	{ "__volatile",		NS_TYPEDEF, .op = &volatile_op },
 	{ "__volatile__", 	NS_TYPEDEF, .op = &volatile_op },
+	{ "restrict",	NS_TYPEDEF, .op = &restrict_op},
+	{ "__restrict",	NS_TYPEDEF, .op = &restrict_op},
+	{ "__restrict__",	NS_TYPEDEF, .op = &restrict_op},
 
 	/* Typedef.. */
 	{ "typedef",	NS_TYPEDEF, .op = &typedef_op },
@@ -461,11 +466,6 @@ static struct init_keyword {
 
 	{ "_Alignas",	NS_TYPEDEF, .op = &alignas_op },
 
-	/* Ignored for now.. */
-	{ "restrict",	NS_TYPEDEF, .op = &restrict_op},
-	{ "__restrict",	NS_TYPEDEF, .op = &restrict_op},
-	{ "__restrict__",	NS_TYPEDEF, .op = &restrict_op},
-
 	/* Storage class */
 	{ "auto",	NS_TYPEDEF, .op = &auto_op },
 	{ "register",	NS_TYPEDEF, .op = &register_op },
@@ -1458,6 +1458,12 @@ static struct token *volatile_qualifier(struct token *next, struct decl_state *c
 	return next;
 }
 
+static struct token *restrict_qualifier(struct token *next, struct decl_state *ctx)
+{
+	apply_qualifier(&next->pos, &ctx->ctype, MOD_RESTRICT);
+	return next;
+}
+
 static void apply_ctype(struct position pos, struct ctype *thistype, struct ctype *ctype)
 {
 	unsigned long mod = thistype->modifiers;
diff --git a/show-parse.c b/show-parse.c
index 3364aec5e..825db6921 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -125,6 +125,7 @@ const char *modifier_string(unsigned long mod)
 		{MOD_EXTERN,		"extern"},
 		{MOD_CONST,		"const"},
 		{MOD_VOLATILE,		"volatile"},
+		{MOD_RESTRICT,		"restrict"},
 		{MOD_SIGNED,		"[signed]"},
 		{MOD_UNSIGNED,		"[unsigned]"},
 		{MOD_CHAR,		"[char]"},
diff --git a/symbol.h b/symbol.h
index 16d58594e..ca0ec00c1 100644
--- a/symbol.h
+++ b/symbol.h
@@ -213,6 +213,7 @@ struct symbol {
 
 #define MOD_CONST		0x00000200
 #define MOD_VOLATILE		0x00000400
+#define MOD_RESTRICT		0x00000800
 
 #define MOD_SIGNED		0x00002000
 #define MOD_UNSIGNED		0x00004000
@@ -242,7 +243,7 @@ struct symbol {
 #define MOD_SIZE	(MOD_CHAR | MOD_SHORT | MOD_LONG_ALL)
 #define MOD_IGNORE	(MOD_STORAGE | MOD_ADDRESSABLE |	\
 	MOD_ASSIGNED | MOD_USERTYPE | MOD_EXPLICITLY_SIGNED)
-#define	MOD_QUALIFIER	(MOD_CONST | MOD_VOLATILE)
+#define	MOD_QUALIFIER	(MOD_CONST | MOD_VOLATILE | MOD_RESTRICT)
 #define MOD_PTRINHERIT	(MOD_QUALIFIER | MOD_NODEREF | MOD_NORETURN | MOD_NOCAST)
 /* modifiers preserved by typeof() operator */
 #define MOD_TYPEOF	(MOD_QUALIFIER | MOD_NOCAST | MOD_SPECIFIER)
diff --git a/validation/optim/restrict.c b/validation/optim/restrict.c
new file mode 100644
index 000000000..de6289e2b
--- /dev/null
+++ b/validation/optim/restrict.c
@@ -0,0 +1,73 @@
+extern int g, h;
+
+void f00u(int *s)
+{
+	g = *s;
+	h = *s;
+}
+
+void f00r(int *restrict s)
+{
+	g = *s;
+	h = *s;
+}
+
+
+void f01u(int *a, int *b, int *s)
+{
+	*a = *s;
+	*b = *s;
+}
+
+void f01r(int *restrict a, int *restrict b, int *restrict s)
+{
+	*a = *s;
+	*b = *s;
+}
+
+/*
+ * check-name: optim/restrict
+ * check-command: test-linearize -Wno-decl $file
+ * check-known-to-fail
+ *
+ * check-output-start
+f00u:
+.L0:
+	<entry-point>
+	load.32     %r2 <- 0[%arg1]
+	store.32    %r2 -> 0[g]
+	load.32     %r4 <- 0[%arg1]
+	store.32    %r4 -> 0[h]
+	ret
+
+
+f00r:
+.L2:
+	<entry-point>
+	load.32     %r6 <- 0[%arg1]
+	store.32    %r6 -> 0[g]
+	store.32    %r6 -> 0[h]
+	ret
+
+
+f01u:
+.L4:
+	<entry-point>
+	load.32     %r10 <- 0[%arg3]
+	store.32    %r10 -> 0[%arg1]
+	load.32     %r13 <- 0[%arg3]
+	store.32    %r13 -> 0[%arg2]
+	ret
+
+
+f01r:
+.L6:
+	<entry-point>
+	load.32     %r16 <- 0[%arg3]
+	store.32    %r16 -> 0[%arg1]
+	store.32    %r16 -> 0[%arg2]
+	ret
+
+
+ * check-output-end
+ */
diff --git a/validation/reload-aliasing.c b/validation/reload-aliasing.c
new file mode 100644
index 000000000..659cff836
--- /dev/null
+++ b/validation/reload-aliasing.c
@@ -0,0 +1,42 @@
+extern int g, h;
+
+void f00(int *s)
+{
+	g = *s;
+	h = *s;
+}
+
+void f01(int *a, int *b, int *s)
+{
+	*a = *s;
+	*b = *s;
+}
+
+/*
+ * check-name: reload-aliasing.c
+ * check-command: test-linearize -Wno-decl $file
+ * check-known-to-fail
+ *
+ * check-output-start
+f00:
+.L0:
+	<entry-point>
+	load.32     %r2 <- 0[%arg1]
+	store.32    %r2 -> 0[g]
+	load.32     %r4 <- 0[%arg1]
+	store.32    %r4 -> 0[h]
+	ret
+
+
+f01:
+.L2:
+	<entry-point>
+	load.32     %r6 <- 0[%arg3]
+	store.32    %r6 -> 0[%arg1]
+	load.32     %r9 <- 0[%arg3]
+	store.32    %r9 -> 0[%arg2]
+	ret
+
+
+ * check-output-end
+ */
diff --git a/validation/restrict.c b/validation/restrict.c
new file mode 100644
index 000000000..f431f6d0f
--- /dev/null
+++ b/validation/restrict.c
@@ -0,0 +1,93 @@
+void f00(void *restrict  dst);
+void f01(void *restrict *dst);
+void f02(void *restrict *dst);
+void f03(void *restrict *dst);
+
+void *restrict rp;
+void * up;
+
+void f00(void *dst)	  { }	/* check-should-pass */
+void f01(typeof(&rp) dst) { }	/* check-should-pass */
+void f02(void **dst)	  { }	/* check-should-fail */
+void f03(typeof(&up) dst) { }	/* check-should-fail */
+
+void foo(void)
+{
+	rp = up;		/* check-should-pass */
+	up = rp;		/* check-should-pass */
+}
+
+void ref(void)
+{
+	void *const qp;
+	void * up;
+	extern void *const *pqp;
+	extern void **pup;
+
+	pqp = &qp;		/* check-should-pass */
+	pqp = &up;		/* check-should-pass */
+	pqp = pup;
+
+	pup = &up;		/* check-should-pass */
+
+	pup = &qp;		/* check-should-fail */
+	pup = pqp;		/* check-should-fail */
+}
+
+void bar(void)
+{
+	extern void *restrict *prp;
+	extern void **pup;
+
+	prp = &rp;		/* check-should-pass */
+	prp = &up;		/* check-should-pass */
+	prp = pup;
+
+	pup = &up;		/* check-should-pass */
+
+	pup = &rp;		/* check-should-fail */
+	pup = prp;		/* check-should-fail */
+}
+
+void baz(void)
+{
+	extern typeof(&rp) prp;
+	extern typeof(&up) pup;
+
+	prp = &rp;		/* check-should-pass */
+	prp = &up;		/* check-should-pass */
+	prp = pup;
+
+	pup = &up;		/* check-should-pass */
+
+	pup = &rp;		/* check-should-fail */
+	pup = prp;		/* check-should-fail */
+}
+
+/*
+ * check-name: restrict qualifier
+ * check-command: sparse -Wno-decl $file;
+ *
+ * check-error-start
+restrict.c:11:6: error: symbol 'f02' redeclared with different type (originally declared at restrict.c:3) - incompatible argument 1 (different modifiers)
+restrict.c:12:6: error: symbol 'f03' redeclared with different type (originally declared at restrict.c:4) - incompatible argument 1 (different modifiers)
+restrict.c:33:13: warning: incorrect type in assignment (different modifiers)
+restrict.c:33:13:    expected void **extern [assigned] pup
+restrict.c:33:13:    got void *const *<noident>
+restrict.c:34:13: warning: incorrect type in assignment (different modifiers)
+restrict.c:34:13:    expected void **extern [assigned] pup
+restrict.c:34:13:    got void *const *extern [assigned] pqp
+restrict.c:48:13: warning: incorrect type in assignment (different modifiers)
+restrict.c:48:13:    expected void **extern [assigned] pup
+restrict.c:48:13:    got void *restrict *<noident>
+restrict.c:49:13: warning: incorrect type in assignment (different modifiers)
+restrict.c:49:13:    expected void **extern [assigned] pup
+restrict.c:49:13:    got void *restrict *extern [assigned] prp
+restrict.c:63:13: warning: incorrect type in assignment (different modifiers)
+restrict.c:63:13:    expected void **extern [assigned] pup
+restrict.c:63:13:    got void *restrict *<noident>
+restrict.c:64:13: warning: incorrect type in assignment (different modifiers)
+restrict.c:64:13:    expected void **extern [assigned] pup
+restrict.c:64:13:    got void *restrict *extern [assigned] prp
+ * check-error-end
+ */
diff --git a/validation/typeof-mods.c b/validation/typeof-mods.c
index 9822e96f6..878a111a2 100644
--- a/validation/typeof-mods.c
+++ b/validation/typeof-mods.c
@@ -43,6 +43,20 @@ static void test_volatile(void)
 	obj = *ptr;
 }
 
+static void test_restrict(void)
+{
+	int *restrict obj, *restrict *ptr;
+	typeof(obj) var = obj;
+	typeof(ptr) ptr2 = ptr;
+	typeof(*ptr) var2 = obj;
+	typeof(*ptr) *ptr3 = ptr;
+	typeof(obj) *ptr4 = ptr;
+	obj = obj;
+	ptr = ptr;
+	ptr = &obj;
+	obj = *ptr;
+}
+
 static void test_bitwise(void)
 {
 	typedef int __bitwise type_t;
-- 
2.12.0


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

* [PATCH 9/9] add support for C11's _Atomic as type qualifier
  2017-04-05 21:09 [PATCH 0/9] restricted pointers Luc Van Oostenryck
                   ` (7 preceding siblings ...)
  2017-04-05 21:09 ` [PATCH 8/9] associate MOD_RESTRICT with restrict-qualified variables Luc Van Oostenryck
@ 2017-04-05 21:09 ` Luc Van Oostenryck
  8 siblings, 0 replies; 10+ messages in thread
From: Luc Van Oostenryck @ 2017-04-05 21:09 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

This only add the parsing and checks as a type qualifier;
there is no operational semantic associated with it.

Note: this only support _Atomic as *type qualifier*, not
      as a *type specifier* (partly because there an
      ambiguity on how to parse '_Atomic' when followed
      by an open parenthesis (can be valid as qualifier
      and as specifier)).

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 gdbhelpers               |  3 ++
 parse.c                  | 13 +++++++
 show-parse.c             |  1 +
 symbol.h                 |  3 +-
 validation/c11-atomic.c  | 93 ++++++++++++++++++++++++++++++++++++++++++++++++
 validation/typeof-mods.c | 14 ++++++++
 6 files changed, 126 insertions(+), 1 deletion(-)
 create mode 100644 validation/c11-atomic.c

diff --git a/gdbhelpers b/gdbhelpers
index f6399d3bc..2fe9336dd 100644
--- a/gdbhelpers
+++ b/gdbhelpers
@@ -110,6 +110,9 @@ define gdb_show_ctype
 	if ($arg0->modifiers & MOD_RESTRICT)
 		printf "MOD_RESTRICT "
 	end
+	if ($arg0->modifiers & MOD_ATOMIC)
+		printf "MOD_ATOMIC "
+	end
 	if ($arg0->modifiers & MOD_SIGNED)
 		printf "MOD_SIGNED "
 	end
diff --git a/parse.c b/parse.c
index 14fc2b9d1..beb358a2b 100644
--- a/parse.c
+++ b/parse.c
@@ -59,6 +59,7 @@ static declarator_t
 	register_specifier, static_specifier, extern_specifier,
 	thread_specifier, const_qualifier, volatile_qualifier;
 static declarator_t restrict_qualifier;
+static declarator_t atomic_qualifier;
 
 static struct token *parse_if_statement(struct token *token, struct statement *stmt);
 static struct token *parse_return_statement(struct token *token, struct statement *stmt);
@@ -177,6 +178,11 @@ static struct symbol_op restrict_op = {
 	.declarator = restrict_qualifier,
 };
 
+static struct symbol_op atomic_op = {
+	.type = KW_QUALIFIER,
+	.declarator = atomic_qualifier,
+};
+
 static struct symbol_op typeof_op = {
 	.type = KW_SPECIFIER,
 	.declarator = typeof_specifier,
@@ -421,6 +427,7 @@ static struct init_keyword {
 	{ "restrict",	NS_TYPEDEF, .op = &restrict_op},
 	{ "__restrict",	NS_TYPEDEF, .op = &restrict_op},
 	{ "__restrict__",	NS_TYPEDEF, .op = &restrict_op},
+	{ "_Atomic",	NS_TYPEDEF, .op = &atomic_op},
 
 	/* Typedef.. */
 	{ "typedef",	NS_TYPEDEF, .op = &typedef_op },
@@ -1464,6 +1471,12 @@ static struct token *restrict_qualifier(struct token *next, struct decl_state *c
 	return next;
 }
 
+static struct token *atomic_qualifier(struct token *next, struct decl_state *ctx)
+{
+	apply_qualifier(&next->pos, &ctx->ctype, MOD_ATOMIC);
+	return next;
+}
+
 static void apply_ctype(struct position pos, struct ctype *thistype, struct ctype *ctype)
 {
 	unsigned long mod = thistype->modifiers;
diff --git a/show-parse.c b/show-parse.c
index 825db6921..a4ce6f68d 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -126,6 +126,7 @@ const char *modifier_string(unsigned long mod)
 		{MOD_CONST,		"const"},
 		{MOD_VOLATILE,		"volatile"},
 		{MOD_RESTRICT,		"restrict"},
+		{MOD_ATOMIC,		"[atomic]"},
 		{MOD_SIGNED,		"[signed]"},
 		{MOD_UNSIGNED,		"[unsigned]"},
 		{MOD_CHAR,		"[char]"},
diff --git a/symbol.h b/symbol.h
index ca0ec00c1..58f9df79a 100644
--- a/symbol.h
+++ b/symbol.h
@@ -214,6 +214,7 @@ struct symbol {
 #define MOD_CONST		0x00000200
 #define MOD_VOLATILE		0x00000400
 #define MOD_RESTRICT		0x00000800
+#define MOD_ATOMIC		0x00001000
 
 #define MOD_SIGNED		0x00002000
 #define MOD_UNSIGNED		0x00004000
@@ -243,7 +244,7 @@ struct symbol {
 #define MOD_SIZE	(MOD_CHAR | MOD_SHORT | MOD_LONG_ALL)
 #define MOD_IGNORE	(MOD_STORAGE | MOD_ADDRESSABLE |	\
 	MOD_ASSIGNED | MOD_USERTYPE | MOD_EXPLICITLY_SIGNED)
-#define	MOD_QUALIFIER	(MOD_CONST | MOD_VOLATILE | MOD_RESTRICT)
+#define	MOD_QUALIFIER	(MOD_CONST | MOD_VOLATILE | MOD_RESTRICT | MOD_ATOMIC)
 #define MOD_PTRINHERIT	(MOD_QUALIFIER | MOD_NODEREF | MOD_NORETURN | MOD_NOCAST)
 /* modifiers preserved by typeof() operator */
 #define MOD_TYPEOF	(MOD_QUALIFIER | MOD_NOCAST | MOD_SPECIFIER)
diff --git a/validation/c11-atomic.c b/validation/c11-atomic.c
new file mode 100644
index 000000000..bea3dab8f
--- /dev/null
+++ b/validation/c11-atomic.c
@@ -0,0 +1,93 @@
+void f00(int _Atomic  dst);
+void f01(int _Atomic *dst);
+void f02(int _Atomic *dst);
+void f03(int _Atomic *dst);
+
+int _Atomic qo;
+int         uo;
+
+void f00(int dst)	  { }	/* check-should-pass */
+void f01(typeof(&qo) dst) { }	/* check-should-pass */
+void f02(int *dst)	  { }	/* check-should-fail */
+void f03(typeof(&uo) dst) { }	/* check-should-fail */
+
+void foo(void)
+{
+	qo = uo;		/* check-should-pass */
+	uo = qo;		/* check-should-pass */
+}
+
+void ref(void)
+{
+	const int qo;
+	int uo;
+	extern const int *pqo;
+	extern       int *puo;
+
+	pqo = &qo;		/* check-should-pass */
+	pqo = &uo;		/* check-should-pass */
+	pqo = puo;
+
+	puo = &uo;		/* check-should-pass */
+
+	puo = &qo;		/* check-should-fail */
+	puo = pqo;		/* check-should-fail */
+}
+
+void bar(void)
+{
+	extern int _Atomic *pqo;
+	extern int         *puo;
+
+	pqo = &qo;		/* check-should-pass */
+	pqo = &uo;		/* check-should-pass */
+	pqo = puo;
+
+	puo = &uo;		/* check-should-pass */
+
+	puo = &qo;		/* check-should-fail */
+	puo = pqo;		/* check-should-fail */
+}
+
+void baz(void)
+{
+	extern typeof(&qo) pqo;
+	extern typeof(&uo) puo;
+
+	pqo = &qo;		/* check-should-pass */
+	pqo = &uo;		/* check-should-pass */
+	pqo = puo;
+
+	puo = &uo;		/* check-should-pass */
+
+	puo = &qo;		/* check-should-fail */
+	puo = pqo;		/* check-should-fail */
+}
+
+/*
+ * check-name: C11 _Atomic type qualifier
+ * check-command: sparse -Wno-decl $file;
+ *
+ * check-error-start
+c11-atomic.c:11:6: error: symbol 'f02' redeclared with different type (originally declared at c11-atomic.c:3) - incompatible argument 1 (different modifiers)
+c11-atomic.c:12:6: error: symbol 'f03' redeclared with different type (originally declared at c11-atomic.c:4) - incompatible argument 1 (different modifiers)
+c11-atomic.c:33:13: warning: incorrect type in assignment (different modifiers)
+c11-atomic.c:33:13:    expected int *extern [assigned] puo
+c11-atomic.c:33:13:    got int const *<noident>
+c11-atomic.c:34:13: warning: incorrect type in assignment (different modifiers)
+c11-atomic.c:34:13:    expected int *extern [assigned] puo
+c11-atomic.c:34:13:    got int const *extern [assigned] pqo
+c11-atomic.c:48:13: warning: incorrect type in assignment (different modifiers)
+c11-atomic.c:48:13:    expected int *extern [assigned] puo
+c11-atomic.c:48:13:    got int [atomic] *<noident>
+c11-atomic.c:49:13: warning: incorrect type in assignment (different modifiers)
+c11-atomic.c:49:13:    expected int *extern [assigned] puo
+c11-atomic.c:49:13:    got int [atomic] *extern [assigned] pqo
+c11-atomic.c:63:13: warning: incorrect type in assignment (different modifiers)
+c11-atomic.c:63:13:    expected int *extern [assigned] puo
+c11-atomic.c:63:13:    got int [atomic] *<noident>
+c11-atomic.c:64:13: warning: incorrect type in assignment (different modifiers)
+c11-atomic.c:64:13:    expected int *extern [assigned] puo
+c11-atomic.c:64:13:    got int [atomic] *extern [assigned] pqo
+ * check-error-end
+ */
diff --git a/validation/typeof-mods.c b/validation/typeof-mods.c
index 878a111a2..aa880f373 100644
--- a/validation/typeof-mods.c
+++ b/validation/typeof-mods.c
@@ -57,6 +57,20 @@ static void test_restrict(void)
 	obj = *ptr;
 }
 
+static void test_atomic(void)
+{
+	int _Atomic obj, *ptr;
+	typeof(obj) var = obj;
+	typeof(ptr) ptr2 = ptr;
+	typeof(*ptr) var2 = obj;
+	typeof(*ptr) *ptr3 = ptr;
+	typeof(obj) *ptr4 = ptr;
+	obj = obj;
+	ptr = ptr;
+	ptr = &obj;
+	obj = *ptr;
+}
+
 static void test_bitwise(void)
 {
 	typedef int __bitwise type_t;
-- 
2.12.0


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

end of thread, other threads:[~2017-04-05 21:09 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-05 21:09 [PATCH 0/9] restricted pointers Luc Van Oostenryck
2017-04-05 21:09 ` [PATCH 1/9] remove never-used MOD_TYPEDEF Luc Van Oostenryck
2017-04-05 21:09 ` [PATCH 2/9] avoid warnings about using 0 instead of NULL Luc Van Oostenryck
2017-04-05 21:09 ` [PATCH 3/9] finer control over error vs. warnings Luc Van Oostenryck
2017-04-05 21:09 ` [PATCH 4/9] MOD_ACCESSED is not a type modifier Luc Van Oostenryck
2017-04-05 21:09 ` [PATCH 5/9] reorganize the definition of the modifiers Luc Van Oostenryck
2017-04-05 21:09 ` [PATCH 6/9] MOD_STORAGE redundancy Luc Van Oostenryck
2017-04-05 21:09 ` [PATCH 7/9] MOD_QUALIFIER Luc Van Oostenryck
2017-04-05 21:09 ` [PATCH 8/9] associate MOD_RESTRICT with restrict-qualified variables Luc Van Oostenryck
2017-04-05 21:09 ` [PATCH 9/9] add support for C11's _Atomic as type qualifier Luc Van Oostenryck

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.