summaryrefslogtreecommitdiff
path: root/source/d/gcc/patches/revert-asm-inline/5-8-c-c-asm-Use-nicer-error-for-duplicate-asm-qualifiers.patch
blob: 6f8175c8948c91ccf20f26b40eb30be06bc5dbcf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
From patchwork Thu Dec 27 14:59:10 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [5/8] c/c++, asm: Use nicer error for duplicate asm qualifiers
X-Patchwork-Submitter: Segher Boessenkool <segher@kernel.crashing.org>
X-Patchwork-Id: 13822
Message-Id: <30a12d359164450406601e125d128fc43af4d605.1545922222.git.segher@kernel.crashing.org>
To: gcc-patches@gcc.gnu.org
Cc: Segher Boessenkool <segher@kernel.crashing.org>
Date: Thu, 27 Dec 2018 14:59:10 +0000
From: Segher Boessenkool <segher@kernel.crashing.org>
List-Id: <gcc-patches.gcc.gnu.org>

Also as suggested by Jason.

Segher

2018-12-10  Segher Boessenkool  <segher@kernel.crashing.org>

c/
	* c-parser.c (c_parser_asm_statement): Keep track of the location each
	asm qualifier is first seen; use that to give nicer "duplicate asm
	qualifier" messages.  Delete 'quals" variable, instead pass the
	"is_volatile_ flag to build_asm_stmt directly.
	* c-tree.h (build_asm_stmt): Make the first arg bool instead of tree.
	* c-typeck.c (build_asm_stmt): Ditto; adjust.

cp/
	* parser.c (cp_parser_asm_definition): Rewrite the loop to work without
	"done" boolean variable.
	* parser.c (cp_parser_asm_definition): Keep track of the location each
	asm qualifier is first seen; use that to give nicer "duplicate asm
	qualifier" messages.
---
 gcc/c/c-parser.c | 57 ++++++++++++++++++++++++++++++++++++--------------------
 gcc/c/c-tree.h   |  2 +-
 gcc/c/c-typeck.c |  4 ++--
 gcc/cp/parser.c  | 45 ++++++++++++++++++++++++++++++++------------
 4 files changed, 73 insertions(+), 35 deletions(-)

-- 
1.8.3.1

diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index b632f68..ca04910 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -6292,41 +6292,54 @@ c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
 static tree
 c_parser_asm_statement (c_parser *parser)
 {
-  tree quals, str, outputs, inputs, clobbers, labels, ret;
-  bool simple, is_volatile, is_inline, is_goto;
+  tree str, outputs, inputs, clobbers, labels, ret;
+  bool simple;
   location_t asm_loc = c_parser_peek_token (parser)->location;
   int section, nsections;
 
   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
   c_parser_consume_token (parser);
 
-  quals = NULL_TREE;
-  is_volatile = false;
-  is_inline = false;
-  is_goto = false;
+  /* Handle the asm-qualifier-list.  */
+  location_t volatile_loc = UNKNOWN_LOCATION;
+  location_t inline_loc = UNKNOWN_LOCATION;
+  location_t goto_loc = UNKNOWN_LOCATION;
   for (;;)
     {
-      switch (c_parser_peek_token (parser)->keyword)
+      c_token *token = c_parser_peek_token (parser);
+      location_t loc = token->location;
+      switch (token->keyword)
 	{
 	case RID_VOLATILE:
-	  if (is_volatile)
-	    break;
-	  is_volatile = true;
-	  quals = c_parser_peek_token (parser)->value;
+	  if (volatile_loc)
+	    {
+	      error_at (loc, "duplicate asm qualifier %qE", token->value);
+	      inform (volatile_loc, "first seen here");
+	    }
+	  else
+	    volatile_loc = loc;
 	  c_parser_consume_token (parser);
 	  continue;
 
 	case RID_INLINE:
-	  if (is_inline)
-	    break;
-	  is_inline = true;
+	  if (inline_loc)
+	    {
+	      error_at (loc, "duplicate asm qualifier %qE", token->value);
+	      inform (inline_loc, "first seen here");
+	    }
+	  else
+	    inline_loc = loc;
 	  c_parser_consume_token (parser);
 	  continue;
 
 	case RID_GOTO:
-	  if (is_goto)
-	    break;
-	  is_goto = true;
+	  if (goto_loc)
+	    {
+	      error_at (loc, "duplicate asm qualifier %qE", token->value);
+	      inform (goto_loc, "first seen here");
+	    }
+	  else
+	    goto_loc = loc;
 	  c_parser_consume_token (parser);
 	  continue;
 
@@ -6336,6 +6349,10 @@ c_parser_asm_statement (c_parser *parser)
       break;
     }
 
+  bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
+  bool is_inline = (inline_loc != UNKNOWN_LOCATION);
+  bool is_goto = (goto_loc != UNKNOWN_LOCATION);
+
   /* ??? Follow the C++ parser rather than using the
      lex_untranslated_string kludge.  */
   parser->lex_untranslated_string = true;
@@ -6410,9 +6427,9 @@ c_parser_asm_statement (c_parser *parser)
   if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
     c_parser_skip_to_end_of_block_or_statement (parser);
 
-  ret = build_asm_stmt (quals, build_asm_expr (asm_loc, str, outputs, inputs,
-					       clobbers, labels, simple,
-					       is_inline));
+  ret = build_asm_stmt (is_volatile,
+			build_asm_expr (asm_loc, str, outputs, inputs,
+					clobbers, labels, simple, is_inline));
 
  error:
   parser->lex_untranslated_string = false;
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 7f34bdc..aa66aa2 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -679,7 +679,7 @@ extern tree c_start_case (location_t, location_t, tree, bool);
 extern void c_finish_case (tree, tree);
 extern tree build_asm_expr (location_t, tree, tree, tree, tree, tree, bool,
 			    bool);
-extern tree build_asm_stmt (tree, tree);
+extern tree build_asm_stmt (bool, tree);
 extern int c_types_compatible_p (tree, tree);
 extern tree c_begin_compound_stmt (bool);
 extern tree c_end_compound_stmt (location_t, tree, bool);
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 3ebb28e..7b90b5c 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -9979,9 +9979,9 @@ process_init_element (location_t loc, struct c_expr value, bool implicit,
    (guaranteed to be 'volatile' or null) and ARGS (represented using
    an ASM_EXPR node).  */
 tree
-build_asm_stmt (tree cv_qualifier, tree args)
+build_asm_stmt (bool is_volatile, tree args)
 {
-  if (!ASM_VOLATILE_P (args) && cv_qualifier)
+  if (is_volatile)
     ASM_VOLATILE_P (args) = 1;
   return add_stmt (args);
 }
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 7660565..44fdace 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -19106,12 +19106,9 @@ cp_parser_asm_definition (cp_parser* parser)
   tree clobbers = NULL_TREE;
   tree labels = NULL_TREE;
   tree asm_stmt;
-  bool volatile_p = false;
   bool extended_p = false;
   bool invalid_inputs_p = false;
   bool invalid_outputs_p = false;
-  bool inline_p = false;
-  bool goto_p = false;
   required_token missing = RT_NONE;
 
   /* Look for the `asm' keyword.  */
@@ -19125,29 +19122,50 @@ cp_parser_asm_definition (cp_parser* parser)
     }
 
   /* Handle the asm-qualifier-list.  */
+  location_t volatile_loc = UNKNOWN_LOCATION;
+  location_t inline_loc = UNKNOWN_LOCATION;
+  location_t goto_loc = UNKNOWN_LOCATION;
   if (cp_parser_allow_gnu_extensions_p (parser))
     for (;;)
       {
+	cp_token *token = cp_lexer_peek_token (parser->lexer);
+	location_t loc = token->location;
 	switch (cp_lexer_peek_token (parser->lexer)->keyword)
 	  {
 	  case RID_VOLATILE:
-	    if (volatile_p)
-	      break;
-	    volatile_p = true;
+	    if (volatile_loc)
+	      {
+		error_at (loc, "duplicate asm qualifier %qT", token->u.value);
+		inform (volatile_loc, "first seen here");
+	      }
+	    else
+	      volatile_loc = loc;
 	    cp_lexer_consume_token (parser->lexer);
 	    continue;
 
 	  case RID_INLINE:
-	    if (inline_p || !parser->in_function_body)
+	    if (!parser->in_function_body)
 	      break;
-	    inline_p = true;
+	    if (inline_loc)
+	      {
+		error_at (loc, "duplicate asm qualifier %qT", token->u.value);
+		inform (inline_loc, "first seen here");
+	      }
+	    else
+	      inline_loc = loc;
 	    cp_lexer_consume_token (parser->lexer);
 	    continue;
 
 	  case RID_GOTO:
-	    if (goto_p || !parser->in_function_body)
+	    if (!parser->in_function_body)
 	      break;
-	    goto_p = true;
+	    if (goto_loc)
+	      {
+		error_at (loc, "duplicate asm qualifier %qT", token->u.value);
+		inform (goto_loc, "first seen here");
+	      }
+	    else
+	      goto_loc = loc;
 	    cp_lexer_consume_token (parser->lexer);
 	    continue;
 
@@ -19157,6 +19175,10 @@ cp_parser_asm_definition (cp_parser* parser)
 	break;
       }
 
+  bool volatile_p = (volatile_loc != UNKNOWN_LOCATION);
+  bool inline_p = (inline_loc != UNKNOWN_LOCATION);
+  bool goto_p = (goto_loc != UNKNOWN_LOCATION);
+
   /* Look for the opening `('.  */
   if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
     return;
@@ -19248,8 +19270,7 @@ cp_parser_asm_definition (cp_parser* parser)
 					     CPP_CLOSE_PAREN))
 	    clobbers = cp_parser_asm_clobber_list (parser);
 	}
-      else if (goto_p
-	       && cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+      else if (goto_p && cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
 	/* The labels are coming next.  */
 	labels_p = true;