1 /* Implementation of -Wmisleading-indentation
2 Copyright (C) 2015-2023 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
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
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/>. */
22 #include "coretypes.h"
25 #include "c-indentation.h"
27 #include "diagnostic.h"
29 /* Round up VIS_COLUMN to nearest tab stop. */
32 next_tab_stop (unsigned int vis_column
, unsigned int tab_width
)
34 vis_column
= ((vis_column
+ tab_width
) / tab_width
) * tab_width
;
38 /* Convert libcpp's notion of a column (a 1-based char count) to
39 the "visual column" (0-based column, respecting tabs), by reading the
42 Returns true if a conversion was possible, writing the result to OUT,
43 otherwise returns false. If FIRST_NWS is not NULL, then write to it
44 the visual column corresponding to the first non-whitespace character
45 on the line (up to or before EXPLOC). */
48 get_visual_column (file_cache
&fc
,
49 expanded_location exploc
,
51 unsigned int *first_nws
,
52 unsigned int tab_width
)
54 char_span line
= fc
.get_source_line (exploc
.file
, exploc
.line
);
57 if ((size_t)exploc
.column
> line
.length ())
59 unsigned int vis_column
= 0;
60 for (int i
= 1; i
< exploc
.column
; i
++)
62 unsigned char ch
= line
[i
- 1];
64 if (first_nws
!= NULL
&& !ISSPACE (ch
))
66 *first_nws
= vis_column
;
71 vis_column
= next_tab_stop (vis_column
, tab_width
);
76 if (first_nws
!= NULL
)
77 *first_nws
= vis_column
;
83 /* Attempt to determine the first non-whitespace character in line LINE_NUM
86 If this is possible, return true and write its "visual column" to
88 Otherwise, return false, leaving *FIRST_NWS untouched. */
91 get_first_nws_vis_column (file_cache
&fc
,
92 const char *file
, int line_num
,
93 unsigned int *first_nws
,
94 unsigned int tab_width
)
96 gcc_assert (first_nws
);
98 char_span line
= fc
.get_source_line (file
, line_num
);
101 unsigned int vis_column
= 0;
102 for (size_t i
= 1; i
< line
.length (); i
++)
104 unsigned char ch
= line
[i
- 1];
108 *first_nws
= vis_column
;
113 vis_column
= next_tab_stop (vis_column
, tab_width
);
118 /* No non-whitespace characters found. */
122 /* Determine if there is an unindent/outdent between
123 BODY_EXPLOC and NEXT_STMT_EXPLOC, to ensure that we don't
124 issue a warning for cases like the following:
126 (1) Preprocessor logic
131 #if SOME_CONDITION_THAT_DOES_NOT_HOLD
137 "bar ();" is visually aligned below "foo ();" and
138 is (as far as the parser sees) the next token, but
139 this isn't misleading to a human reader.
141 (2) Empty macro with bad indentation
143 In the following, the
145 is poorly indented, and ought to be on the same column as
146 "engine_ref_debug(e, 0, -1)"
147 However, it is not misleadingly indented, due to the presence
150 #define engine_ref_debug(X, Y, Z)
156 engine_ref_debug(e, 0, -1)
160 Return true if such an unindent/outdent is detected. */
163 detect_intervening_unindent (file_cache
&fc
,
167 unsigned int vis_column
,
168 unsigned int tab_width
)
171 gcc_assert (next_stmt_line
> body_line
);
173 for (int line
= body_line
+ 1; line
< next_stmt_line
; line
++)
175 unsigned int line_vis_column
;
176 if (get_first_nws_vis_column (fc
, file
, line
, &line_vis_column
, tab_width
))
177 if (line_vis_column
< vis_column
)
186 /* Helper function for warn_for_misleading_indentation; see
187 description of that function below. */
190 should_warn_for_misleading_indentation (const token_indent_info
&guard_tinfo
,
191 const token_indent_info
&body_tinfo
,
192 const token_indent_info
&next_tinfo
)
194 /* Don't attempt to compare indentation if #line or # 44 "file"-style
195 directives are present, suggesting generated code.
197 All bets are off if these are present: the file that the #line
198 directive could have an entirely different coding layout to C/C++
201 To determine if a #line is present, in theory we could look for a
202 map with reason == LC_RENAME_VERBATIM. However, if there has
203 subsequently been a long line requiring a column number larger than
204 that representable by the original LC_RENAME_VERBATIM map, then
205 we'll have a map with reason LC_RENAME.
206 Rather than attempting to search all of the maps for a
207 LC_RENAME_VERBATIM, instead we have libcpp set a flag whenever one
208 is seen, and we check for the flag here.
210 if (line_table
->seen_line_directive
)
213 /* We can't usefully warn about do-while and switch statements since the
214 bodies of these statements are always explicitly delimited at both ends,
215 so control flow is quite obvious. */
216 if (guard_tinfo
.keyword
== RID_DO
217 || guard_tinfo
.keyword
== RID_SWITCH
)
220 /* If the token following the body is a close brace or an "else"
221 then while indentation may be sloppy, there is not much ambiguity
222 about control flow, e.g.
234 enum cpp_ttype next_tok_type
= next_tinfo
.type
;
235 if (next_tok_type
== CPP_CLOSE_BRACE
236 || next_tinfo
.keyword
== RID_ELSE
)
239 /* Likewise, if the body of the guard is a compound statement then control
240 flow is quite visually explicit regardless of the code's possibly poor
249 Things only get muddy when the body of the guard does not have
256 enum cpp_ttype body_type
= body_tinfo
.type
;
257 if (body_type
== CPP_OPEN_BRACE
)
260 /* Don't warn here about spurious semicolons. */
261 if (next_tok_type
== CPP_SEMICOLON
)
264 location_t guard_loc
= guard_tinfo
.location
;
265 location_t body_loc
= body_tinfo
.location
;
266 location_t next_stmt_loc
= next_tinfo
.location
;
268 /* Resolve each token location to the respective macro expansion
269 point that produced the token. */
270 if (linemap_location_from_macro_expansion_p (line_table
, guard_loc
))
271 guard_loc
= linemap_resolve_location (line_table
, guard_loc
,
272 LRK_MACRO_EXPANSION_POINT
, NULL
);
273 if (linemap_location_from_macro_expansion_p (line_table
, body_loc
))
274 body_loc
= linemap_resolve_location (line_table
, body_loc
,
275 LRK_MACRO_EXPANSION_POINT
, NULL
);
276 if (linemap_location_from_macro_expansion_p (line_table
, next_stmt_loc
))
277 next_stmt_loc
= linemap_resolve_location (line_table
, next_stmt_loc
,
278 LRK_MACRO_EXPANSION_POINT
, NULL
);
280 /* When all three tokens are produced from a single macro expansion, we
281 instead consider their loci inside that macro's definition. */
282 if (guard_loc
== body_loc
&& body_loc
== next_stmt_loc
)
284 const line_map
*guard_body_common_map
285 = first_map_in_common (line_table
,
286 guard_tinfo
.location
, body_tinfo
.location
,
287 &guard_loc
, &body_loc
);
288 const line_map
*body_next_common_map
289 = first_map_in_common (line_table
,
290 body_tinfo
.location
, next_tinfo
.location
,
291 &body_loc
, &next_stmt_loc
);
293 /* Punt on complicated nesting of macros. */
294 if (guard_body_common_map
!= body_next_common_map
)
297 guard_loc
= linemap_resolve_location (line_table
, guard_loc
,
298 LRK_MACRO_DEFINITION_LOCATION
, NULL
);
299 body_loc
= linemap_resolve_location (line_table
, body_loc
,
300 LRK_MACRO_DEFINITION_LOCATION
, NULL
);
301 next_stmt_loc
= linemap_resolve_location (line_table
, next_stmt_loc
,
302 LRK_MACRO_DEFINITION_LOCATION
,
306 expanded_location body_exploc
= expand_location (body_loc
);
307 expanded_location next_stmt_exploc
= expand_location (next_stmt_loc
);
308 expanded_location guard_exploc
= expand_location (guard_loc
);
310 /* PR c++/68819: if the column number is zero, we presumably
311 had a location_t > LINE_MAP_MAX_LOCATION_WITH_COLS, and so
312 we have no column information. */
313 if (!guard_exploc
.column
|| !body_exploc
.column
|| !next_stmt_exploc
.column
)
315 static bool issued_note
= false;
318 /* Notify the user the first time this happens. */
321 "%<-Wmisleading-indentation%> is disabled from this point"
322 " onwards, since column-tracking was disabled due to"
323 " the size of the code/headers");
324 if (!flag_large_source_files
)
326 "adding %<-flarge-source-files%> will allow for more"
327 " column-tracking support, at the expense of compilation"
333 /* Give up if the loci are not all distinct. */
334 if (guard_loc
== body_loc
|| body_loc
== next_stmt_loc
)
337 const unsigned int tab_width
= global_dc
->m_tabstop
;
339 /* They must be in the same file. */
340 if (next_stmt_exploc
.file
!= body_exploc
.file
)
343 file_cache
&fc
= global_dc
->get_file_cache ();
345 /* If NEXT_STMT_LOC and BODY_LOC are on the same line, consider
346 the location of the guard.
348 Cases where we want to issue a warning:
354 if (flag) foo (); bar ();
365 Cases where we don't want to issue a warning:
367 various_code (); if (flag) foo (); bar (); more_code ();
368 ^ DON'T WARN HERE. */
369 if (next_stmt_exploc
.line
== body_exploc
.line
)
371 if (guard_exploc
.file
!= body_exploc
.file
)
373 if (guard_exploc
.line
< body_exploc
.line
)
374 /* The guard is on a line before a line that contains both
375 the body and the next stmt. */
377 else if (guard_exploc
.line
== body_exploc
.line
)
379 /* They're all on the same line. */
380 gcc_assert (guard_exploc
.file
== next_stmt_exploc
.file
);
381 gcc_assert (guard_exploc
.line
== next_stmt_exploc
.line
);
382 unsigned int guard_vis_column
;
383 unsigned int guard_line_first_nws
;
384 if (!get_visual_column (fc
,
387 &guard_line_first_nws
, tab_width
))
389 /* Heuristic: only warn if the guard is the first thing
391 if (guard_vis_column
== guard_line_first_nws
)
396 /* If NEXT_STMT_LOC is on a line after BODY_LOC, consider
397 their relative locations, and of the guard.
399 Cases where we want to issue a warning:
405 Cases where we don't want to issue a warning:
409 ^ DON'T WARN HERE (autogenerated code?)
413 #if SOME_CONDITION_THAT_DOES_NOT_HOLD
431 if (next_stmt_exploc
.line
> body_exploc
.line
)
433 /* Determine if GUARD_LOC and NEXT_STMT_LOC are aligned on the same
434 "visual column"... */
435 unsigned int next_stmt_vis_column
;
436 unsigned int next_stmt_line_first_nws
;
437 unsigned int body_vis_column
;
438 unsigned int body_line_first_nws
;
439 unsigned int guard_vis_column
;
440 unsigned int guard_line_first_nws
;
441 /* If we can't determine it, don't issue a warning. This is sometimes
442 the case for input files containing #line directives, and these
443 are often for autogenerated sources (e.g. from .md files), where
444 it's not clear that it's meaningful to look at indentation. */
445 if (!get_visual_column (fc
,
447 &next_stmt_vis_column
,
448 &next_stmt_line_first_nws
, tab_width
))
450 if (!get_visual_column (fc
,
453 &body_line_first_nws
, tab_width
))
455 if (!get_visual_column (fc
,
458 &guard_line_first_nws
, tab_width
))
461 /* If the line where the next stmt starts has non-whitespace
462 on it before the stmt, then don't warn:
469 if (next_stmt_line_first_nws
< next_stmt_vis_column
)
472 if ((body_type
!= CPP_SEMICOLON
473 && next_stmt_vis_column
== body_vis_column
)
474 /* As a special case handle the case where the body is a semicolon
475 that may be hidden by a preceding comment, e.g. */
481 /* by looking instead at the column of the first non-whitespace
482 character on the body line. */
483 || (body_type
== CPP_SEMICOLON
484 && body_exploc
.line
> guard_exploc
.line
485 && body_line_first_nws
!= body_vis_column
486 && next_stmt_vis_column
> guard_line_first_nws
))
488 /* Don't warn if they are aligned on the same column
489 as the guard itself (suggesting autogenerated code that doesn't
490 bother indenting at all).
491 For "else" clauses, we consider the column of the first
492 non-whitespace character on the guard line instead of the column
493 of the actual guard token itself because it is more sensible.
510 If we just used the column of the "else" token, we would warn on
511 the first example and not warn on the second. But we want the
512 exact opposite to happen: to not warn on the first example (which
513 is probably autogenerated) and to warn on the second (whose
514 indentation is misleading). Using the column of the first
515 non-whitespace character on the guard line makes that
517 unsigned int guard_column
= (guard_tinfo
.keyword
== RID_ELSE
518 ? guard_line_first_nws
520 if (guard_column
== body_vis_column
)
523 /* We may have something like:
532 in which case the columns are not aligned but the code is not
533 misleadingly indented. If the column of the body isn't indented
534 more than the guard line then don't warn. */
535 if (body_vis_column
<= guard_line_first_nws
)
538 /* Don't warn if there is an unindent between the two statements. */
539 int vis_column
= MIN (next_stmt_vis_column
, body_vis_column
);
540 if (detect_intervening_unindent (fc
,
541 body_exploc
.file
, body_exploc
.line
,
542 next_stmt_exploc
.line
,
543 vis_column
, tab_width
))
546 /* Otherwise, they are visually aligned: issue a warning. */
550 /* Also issue a warning for code having the form:
570 where the semicolon at the end of each guard is most likely spurious.
577 where the next statement is aligned with the guard.
579 if (body_type
== CPP_SEMICOLON
)
581 if (body_exploc
.line
== guard_exploc
.line
)
583 if (next_stmt_vis_column
> guard_line_first_nws
584 || (next_tok_type
== CPP_OPEN_BRACE
585 && next_stmt_vis_column
== guard_line_first_nws
))
594 /* Return the string identifier corresponding to the given guard token. */
597 guard_tinfo_to_string (enum rid keyword
)
618 /* Called by the C/C++ frontends when we have a guarding statement at
619 GUARD_LOC containing a statement at BODY_LOC, where the block wasn't
620 written using braces, like this:
625 along with the location of the next token, at NEXT_STMT_LOC,
626 so that we can detect followup statements that are within
627 the same "visual block" as the guarded statement, but which
628 aren't logically grouped within the guarding statement, such
636 bar (); <- NEXT_STMT_LOC
638 In the above, "bar ();" isn't guarded by the "if", but
639 is indented to misleadingly suggest that it is in the same
642 GUARD_KIND identifies the kind of clause e.g. "if", "else" etc. */
645 warn_for_misleading_indentation (const token_indent_info
&guard_tinfo
,
646 const token_indent_info
&body_tinfo
,
647 const token_indent_info
&next_tinfo
)
649 /* Early reject for the case where -Wmisleading-indentation is disabled,
650 to avoid doing work only to have the warning suppressed inside the
651 diagnostic machinery. */
652 if (!warn_misleading_indentation
)
655 if (should_warn_for_misleading_indentation (guard_tinfo
,
659 auto_diagnostic_group d
;
660 if (warning_at (guard_tinfo
.location
, OPT_Wmisleading_indentation
,
661 "this %qs clause does not guard...",
662 guard_tinfo_to_string (guard_tinfo
.keyword
)))
663 inform (next_tinfo
.location
,
664 "...this statement, but the latter is misleadingly indented"
665 " as if it were guarded by the %qs",
666 guard_tinfo_to_string (guard_tinfo
.keyword
));
674 /* Verify that next_tab_stop works as expected. */
677 test_next_tab_stop ()
679 const unsigned int tab_width
= 8;
681 ASSERT_EQ (next_tab_stop (0, tab_width
), 8);
682 ASSERT_EQ (next_tab_stop (1, tab_width
), 8);
683 ASSERT_EQ (next_tab_stop (7, tab_width
), 8);
685 ASSERT_EQ (next_tab_stop (8, tab_width
), 16);
686 ASSERT_EQ (next_tab_stop (9, tab_width
), 16);
687 ASSERT_EQ (next_tab_stop (15, tab_width
), 16);
689 ASSERT_EQ (next_tab_stop (16, tab_width
), 24);
690 ASSERT_EQ (next_tab_stop (17, tab_width
), 24);
691 ASSERT_EQ (next_tab_stop (23, tab_width
), 24);
694 /* Verify that the given call to get_visual_column succeeds, with
695 the given results. */
698 assert_get_visual_column_succeeds (const location
&loc
,
700 const char *file
, int line
, int column
,
701 const unsigned int tab_width
,
702 unsigned int expected_visual_column
,
703 unsigned int expected_first_nws
)
705 expanded_location exploc
;
708 exploc
.column
= column
;
711 unsigned int actual_visual_column
;
712 unsigned int actual_first_nws
;
713 bool result
= get_visual_column (fc
,
715 &actual_visual_column
,
716 &actual_first_nws
, tab_width
);
717 ASSERT_TRUE_AT (loc
, result
);
718 ASSERT_EQ_AT (loc
, actual_visual_column
, expected_visual_column
);
719 ASSERT_EQ_AT (loc
, actual_first_nws
, expected_first_nws
);
722 /* Verify that the given call to get_visual_column succeeds, with
723 the given results. */
725 #define ASSERT_GET_VISUAL_COLUMN_SUCCEEDS(FILE_CACHE, \
726 FILENAME, LINE, COLUMN, \
728 EXPECTED_VISUAL_COLUMN, \
729 EXPECTED_FIRST_NWS) \
730 SELFTEST_BEGIN_STMT \
731 assert_get_visual_column_succeeds (SELFTEST_LOCATION, \
733 FILENAME, LINE, COLUMN, \
735 EXPECTED_VISUAL_COLUMN, \
736 EXPECTED_FIRST_NWS); \
739 /* Verify that the given call to get_visual_column fails gracefully. */
742 assert_get_visual_column_fails (const location
&loc
,
744 const char *file
, int line
, int column
,
745 const unsigned int tab_width
)
747 expanded_location exploc
;
750 exploc
.column
= column
;
753 unsigned int actual_visual_column
;
754 unsigned int actual_first_nws
;
755 bool result
= get_visual_column (fc
,
757 &actual_visual_column
,
758 &actual_first_nws
, tab_width
);
759 ASSERT_FALSE_AT (loc
, result
);
762 /* Verify that the given call to get_visual_column fails gracefully. */
764 #define ASSERT_GET_VISUAL_COLUMN_FAILS(FILE_CACHE, \
765 FILENAME, LINE, COLUMN, \
767 SELFTEST_BEGIN_STMT \
768 assert_get_visual_column_fails (SELFTEST_LOCATION, \
770 FILENAME, LINE, COLUMN, \
774 /* Verify that get_visual_column works as expected. */
777 test_get_visual_column ()
779 /* Create a tempfile with a mixture of tabs and spaces.
781 Both lines have either a space or a tab, then " line N",
782 for 8 characters in total.
784 1-based "columns" (w.r.t. to line 1):
785 .....................0000000001111.
786 .....................1234567890123. */
787 const char *content
= (" line 1\n"
790 temp_source_file
tmp (SELFTEST_LOCATION
, ".txt", content
);
793 const unsigned int tab_width
= 8;
794 const char *file
= tmp
.get_filename ();
796 /* Line 1 (space-based indentation). */
799 ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (fc
, file
, line
, 1, tab_width
, 0, 0);
800 ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (fc
, file
, line
, 2, tab_width
, 1, 1);
801 ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (fc
, file
, line
, 3, tab_width
, 2, 2);
802 /* first_nws should have stopped increasing. */
803 ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (fc
, file
, line
, 4, tab_width
, 3, 2);
804 /* Verify the end-of-line boundary. */
805 ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (fc
, file
, line
, 8, tab_width
, 7, 2);
806 ASSERT_GET_VISUAL_COLUMN_FAILS (fc
, file
, line
, 9, tab_width
);
809 /* Line 2 (tab-based indentation). */
812 ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (fc
, file
, line
, 1, tab_width
, 0, 0);
813 ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (fc
, file
, line
, 2, tab_width
, 8, 8);
814 ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (fc
, file
, line
, 3, tab_width
, 9, 9);
815 /* first_nws should have stopped increasing. */
816 ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (fc
, file
, line
, 4, tab_width
, 10, 9);
817 /* Verify the end-of-line boundary. */
818 ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (fc
, file
, line
, 8, tab_width
, 14, 9);
819 ASSERT_GET_VISUAL_COLUMN_FAILS (fc
, file
, line
, 9, tab_width
);
823 /* Run all of the selftests within this file. */
826 c_indentation_cc_tests ()
828 test_next_tab_stop ();
829 test_get_visual_column ();
832 } // namespace selftest
834 #endif /* CHECKING_P */