2015-06-25 Zhouyi Zhou <yizhouzhou@ict.ac.cn>
[official-gcc.git] / gcc / c-family / c-indentation.c
blobb05185c26f06b69a0f6c530aa97def76c158edba
1 /* Implementation of -Wmisleading-indentation
2 Copyright (C) 2015 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "alias.h"
25 #include "symtab.h"
26 #include "tree.h"
27 #include "stringpool.h"
28 #include "stor-layout.h"
29 #include "c-common.h"
31 extern cpp_options *cpp_opts;
33 /* Convert libcpp's notion of a column (a 1-based char count) to
34 the "visual column" (0-based column, respecting tabs), by reading the
35 relevant line.
36 Returns true if a conversion was possible, writing the result to OUT,
37 otherwise returns false. */
39 static bool
40 get_visual_column (expanded_location exploc, unsigned int *out)
42 int line_len;
43 const char *line = location_get_source_line (exploc, &line_len);
44 if (!line)
45 return false;
46 unsigned int vis_column = 0;
47 for (int i = 1; i < exploc.column; i++)
49 unsigned char ch = line[i - 1];
50 if (ch == '\t')
52 /* Round up to nearest tab stop. */
53 const unsigned int tab_width = cpp_opts->tabstop;
54 vis_column = ((vis_column + tab_width) / tab_width) * tab_width;
56 else
57 vis_column++;
60 *out = vis_column;
61 return true;
64 /* Is the token at LOC the first non-whitespace on its line?
65 Helper function for should_warn_for_misleading_indentation. */
67 static bool
68 is_first_nonwhitespace_on_line (expanded_location exploc)
70 int line_len;
71 const char *line = location_get_source_line (exploc, &line_len);
73 /* If we can't determine it, return false so that we don't issue a
74 warning. This is sometimes the case for input files
75 containing #line directives, and these are often for autogenerated
76 sources (e.g. from .md files), where it's not clear that it's
77 meaningful to look at indentation. */
78 if (!line)
79 return false;
81 for (int i = 1; i < exploc.column; i++)
83 unsigned char ch = line[i - 1];
84 if (!ISSPACE (ch))
85 return false;
87 return true;
90 /* Does the given source line appear to contain a #if directive?
91 (or #ifdef/#ifndef). Ignore the possibility of it being inside a
92 comment, for simplicity.
93 Helper function for detect_preprocessor_logic. */
95 static bool
96 line_contains_hash_if (const char *file, int line_num)
98 expanded_location exploc;
99 exploc.file = file;
100 exploc.line = line_num;
101 exploc.column = 1;
103 int line_len;
104 const char *line = location_get_source_line (exploc, &line_len);
105 if (!line)
106 return false;
108 int idx;
110 /* Skip leading whitespace. */
111 for (idx = 0; idx < line_len; idx++)
112 if (!ISSPACE (line[idx]))
113 break;
114 if (idx == line_len)
115 return false;
117 /* Require a '#' character. */
118 if (line[idx] != '#')
119 return false;
120 idx++;
122 /* Skip whitespace. */
123 while (idx < line_len)
125 if (!ISSPACE (line[idx]))
126 break;
127 idx++;
130 /* Match #if/#ifdef/#ifndef. */
131 if (idx + 2 <= line_len)
132 if (line[idx] == 'i')
133 if (line[idx + 1] == 'f')
134 return true;
136 return false;
140 /* Determine if there is preprocessor logic between
141 BODY_EXPLOC and NEXT_STMT_EXPLOC, to ensure that we don't
142 issue a warning for cases like this:
144 if (flagA)
145 foo ();
146 ^ BODY_EXPLOC
147 #if SOME_CONDITION_THAT_DOES_NOT_HOLD
148 if (flagB)
149 #endif
150 bar ();
151 ^ NEXT_STMT_EXPLOC
153 despite "bar ();" being visually aligned below "foo ();" and
154 being (as far as the parser sees) the next token.
156 Return true if such logic is detected. */
158 static bool
159 detect_preprocessor_logic (expanded_location body_exploc,
160 expanded_location next_stmt_exploc)
162 gcc_assert (next_stmt_exploc.file == body_exploc.file);
163 gcc_assert (next_stmt_exploc.line > body_exploc.line);
165 if (next_stmt_exploc.line - body_exploc.line < 4)
166 return false;
168 /* Is there a #if/#ifdef/#ifndef directive somewhere in the lines
169 between the given locations?
171 This is something of a layering violation, but by necessity,
172 given the nature of what we're testing for. For example,
173 in theory we could be fooled by a #if within a comment, but
174 it's unlikely to matter. */
175 for (int line = body_exploc.line + 1; line < next_stmt_exploc.line; line++)
176 if (line_contains_hash_if (body_exploc.file, line))
177 return true;
179 /* Not found. */
180 return false;
184 /* Helper function for warn_for_misleading_indentation; see
185 description of that function below. */
187 static bool
188 should_warn_for_misleading_indentation (location_t guard_loc,
189 location_t body_loc,
190 location_t next_stmt_loc,
191 enum cpp_ttype next_tok_type)
193 /* Don't attempt to compare the indentation of BODY_LOC and NEXT_STMT_LOC
194 if either are within macros. */
195 if (linemap_location_from_macro_expansion_p (line_table, body_loc)
196 || linemap_location_from_macro_expansion_p (line_table, next_stmt_loc))
197 return false;
199 /* Don't attempt to compare indentation if #line or # 44 "file"-style
200 directives are present, suggesting generated code.
202 All bets are off if these are present: the file that the #line
203 directive could have an entirely different coding layout to C/C++
204 (e.g. .md files).
206 To determine if a #line is present, in theory we could look for a
207 map with reason == LC_RENAME_VERBATIM. However, if there has
208 subsequently been a long line requiring a column number larger than
209 that representable by the original LC_RENAME_VERBATIM map, then
210 we'll have a map with reason LC_RENAME.
211 Rather than attempting to search all of the maps for a
212 LC_RENAME_VERBATIM, instead we have libcpp set a flag whenever one
213 is seen, and we check for the flag here.
215 if (line_table->seen_line_directive)
216 return false;
218 if (next_tok_type == CPP_CLOSE_BRACE)
219 return false;
221 /* Don't warn here about spurious semicolons. */
222 if (next_tok_type == CPP_SEMICOLON)
223 return false;
225 expanded_location body_exploc = expand_location (body_loc);
226 expanded_location next_stmt_exploc = expand_location (next_stmt_loc);
228 /* They must be in the same file. */
229 if (next_stmt_exploc.file != body_exploc.file)
230 return false;
232 /* If NEXT_STMT_LOC and BODY_LOC are on the same line, consider
233 the location of the guard.
235 Cases where we want to issue a warning:
237 if (flag)
238 foo (); bar ();
239 ^ WARN HERE
241 if (flag) foo (); bar ();
242 ^ WARN HERE
244 Cases where we don't want to issue a warning:
246 various_code (); if (flag) foo (); bar (); more_code ();
247 ^ DON'T WARN HERE. */
248 if (next_stmt_exploc.line == body_exploc.line)
250 expanded_location guard_exploc = expand_location (guard_loc);
251 if (guard_exploc.file != body_exploc.file)
252 return true;
253 if (guard_exploc.line < body_exploc.line)
254 /* The guard is on a line before a line that contains both
255 the body and the next stmt. */
256 return true;
257 else if (guard_exploc.line == body_exploc.line)
259 /* They're all on the same line. */
260 gcc_assert (guard_exploc.file == next_stmt_exploc.file);
261 gcc_assert (guard_exploc.line == next_stmt_exploc.line);
262 /* Heuristic: only warn if the guard is the first thing
263 on its line. */
264 if (is_first_nonwhitespace_on_line (guard_exploc))
265 return true;
269 /* If NEXT_STMT_LOC is on a line after BODY_LOC, consider
270 their relative locations, and of the guard.
272 Cases where we want to issue a warning:
273 if (flag)
274 foo ();
275 bar ();
276 ^ WARN HERE
278 Cases where we don't want to issue a warning:
279 if (flag)
280 foo ();
281 bar ();
282 ^ DON'T WARN HERE (autogenerated code?)
284 if (flagA)
285 foo ();
286 #if SOME_CONDITION_THAT_DOES_NOT_HOLD
287 if (flagB)
288 #endif
289 bar ();
290 ^ DON'T WARN HERE
292 if (flag) {
293 foo ();
294 } else
296 bar ();
298 baz ();
299 ^ DON'T WARN HERE
301 if (next_stmt_exploc.line > body_exploc.line)
303 /* Determine if GUARD_LOC and NEXT_STMT_LOC are aligned on the same
304 "visual column"... */
305 unsigned int next_stmt_vis_column;
306 unsigned int body_vis_column;
307 /* If we can't determine it, don't issue a warning. This is sometimes
308 the case for input files containing #line directives, and these
309 are often for autogenerated sources (e.g. from .md files), where
310 it's not clear that it's meaningful to look at indentation. */
311 if (!get_visual_column (next_stmt_exploc, &next_stmt_vis_column))
312 return false;
313 if (!get_visual_column (body_exploc, &body_vis_column))
314 return false;
315 if (next_stmt_vis_column == body_vis_column)
317 /* Don't warn if they aren't aligned on the same column
318 as the guard itself (suggesting autogenerated code that
319 doesn't bother indenting at all). */
320 expanded_location guard_exploc = expand_location (guard_loc);
321 unsigned int guard_vis_column;
322 if (!get_visual_column (guard_exploc, &guard_vis_column))
323 return false;
324 if (guard_vis_column == body_vis_column)
325 return false;
327 /* PR 66220: Don't warn if the guarding statement is more
328 indented than the next/body stmts. */
329 if (guard_vis_column > body_vis_column)
330 return false;
332 /* Don't warn if there is multiline preprocessor logic between
333 the two statements. */
334 if (detect_preprocessor_logic (body_exploc, next_stmt_exploc))
335 return false;
337 /* Otherwise, they are visually aligned: issue a warning. */
338 return true;
342 return false;
345 /* Called by the C/C++ frontends when we have a guarding statement at
346 GUARD_LOC containing a statement at BODY_LOC, where the block wasn't
347 written using braces, like this:
349 if (flag)
350 foo ();
352 along with the location of the next token, at NEXT_STMT_LOC,
353 so that we can detect followup statements that are within
354 the same "visual block" as the guarded statement, but which
355 aren't logically grouped within the guarding statement, such
358 GUARD_LOC
361 if (flag)
362 foo (); <- BODY_LOC
363 bar (); <- NEXT_STMT_LOC
365 In the above, "bar ();" isn't guarded by the "if", but
366 is indented to misleadingly suggest that it is in the same
367 block as "foo ();".
369 GUARD_KIND identifies the kind of clause e.g. "if", "else" etc. */
371 void
372 warn_for_misleading_indentation (location_t guard_loc,
373 location_t body_loc,
374 location_t next_stmt_loc,
375 enum cpp_ttype next_tok_type,
376 const char *guard_kind)
378 /* Early reject for the case where -Wmisleading-indentation is disabled,
379 to avoid doing work only to have the warning suppressed inside the
380 diagnostic machinery. */
381 if (!warn_misleading_indentation)
382 return;
384 if (should_warn_for_misleading_indentation (guard_loc,
385 body_loc,
386 next_stmt_loc,
387 next_tok_type))
388 if (warning_at (next_stmt_loc, OPT_Wmisleading_indentation,
389 "statement is indented as if it were guarded by..."))
390 inform (guard_loc,
391 "...this %qs clause, but it is not", guard_kind);