1/* Implementation of -Wmisleading-indentation
2   Copyright (C) 2015-2020 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3.  If not see
18<http://www.gnu.org/licenses/>.  */
19
20#include "config.h"
21#include "system.h"
22#include "coretypes.h"
23#include "tm.h"
24#include "c-common.h"
25#include "c-indentation.h"
26#include "selftest.h"
27
28extern cpp_options *cpp_opts;
29
30/* Round up VIS_COLUMN to nearest tab stop. */
31
32static unsigned int
33next_tab_stop (unsigned int vis_column, unsigned int tab_width)
34{
35  vis_column = ((vis_column + tab_width) / tab_width) * tab_width;
36  return vis_column;
37}
38
39/* Convert libcpp's notion of a column (a 1-based char count) to
40   the "visual column" (0-based column, respecting tabs), by reading the
41   relevant line.
42
43   Returns true if a conversion was possible, writing the result to OUT,
44   otherwise returns false.  If FIRST_NWS is not NULL, then write to it
45   the visual column corresponding to the first non-whitespace character
46   on the line (up to or before EXPLOC).  */
47
48static bool
49get_visual_column (expanded_location exploc, location_t loc,
50		   unsigned int *out,
51		   unsigned int *first_nws,
52		   unsigned int tab_width)
53{
54  /* PR c++/68819: if the column number is zero, we presumably
55     had a location_t > LINE_MAP_MAX_LOCATION_WITH_COLS, and so
56     we have no column information.
57     Act as if no conversion was possible, triggering the
58     error-handling path in the caller.  */
59  if (!exploc.column)
60    {
61      static bool issued_note = false;
62      if (!issued_note)
63	{
64	  /* Notify the user the first time this happens.  */
65	  issued_note = true;
66	  inform (loc,
67		  "%<-Wmisleading-indentation%> is disabled from this point"
68		  " onwards, since column-tracking was disabled due to"
69		  " the size of the code/headers");
70	}
71      return false;
72    }
73
74  char_span line = location_get_source_line (exploc.file, exploc.line);
75  if (!line)
76    return false;
77  if ((size_t)exploc.column > line.length ())
78    return false;
79  unsigned int vis_column = 0;
80  for (int i = 1; i < exploc.column; i++)
81    {
82      unsigned char ch = line[i - 1];
83
84      if (first_nws != NULL && !ISSPACE (ch))
85	{
86	  *first_nws = vis_column;
87	  first_nws = NULL;
88	}
89
90      if (ch == '\t')
91	vis_column = next_tab_stop (vis_column, tab_width);
92      else
93       vis_column++;
94    }
95
96  if (first_nws != NULL)
97    *first_nws = vis_column;
98
99  *out = vis_column;
100  return true;
101}
102
103/* Attempt to determine the first non-whitespace character in line LINE_NUM
104   of source line FILE.
105
106   If this is possible, return true and write its "visual column" to
107   *FIRST_NWS.
108   Otherwise, return false, leaving *FIRST_NWS untouched.  */
109
110static bool
111get_first_nws_vis_column (const char *file, int line_num,
112			  unsigned int *first_nws,
113			  unsigned int tab_width)
114{
115  gcc_assert (first_nws);
116
117  char_span line = location_get_source_line (file, line_num);
118  if (!line)
119    return false;
120  unsigned int vis_column = 0;
121  for (size_t i = 1; i < line.length (); i++)
122    {
123      unsigned char ch = line[i - 1];
124
125      if (!ISSPACE (ch))
126	{
127	  *first_nws = vis_column;
128	  return true;
129	}
130
131      if (ch == '\t')
132	vis_column = next_tab_stop (vis_column, tab_width);
133      else
134	vis_column++;
135    }
136
137  /* No non-whitespace characters found.  */
138  return false;
139}
140
141/* Determine if there is an unindent/outdent between
142   BODY_EXPLOC and NEXT_STMT_EXPLOC, to ensure that we don't
143   issue a warning for cases like the following:
144
145   (1) Preprocessor logic
146
147	if (flagA)
148	  foo ();
149	  ^ BODY_EXPLOC
150      #if SOME_CONDITION_THAT_DOES_NOT_HOLD
151	if (flagB)
152      #endif
153	  bar ();
154	  ^ NEXT_STMT_EXPLOC
155
156   "bar ();" is visually aligned below "foo ();" and
157   is (as far as the parser sees) the next token, but
158   this isn't misleading to a human reader.
159
160   (2) Empty macro with bad indentation
161
162   In the following, the
163     "if (i > 0)"
164   is poorly indented, and ought to be on the same column as
165      "engine_ref_debug(e, 0, -1)"
166   However, it is not misleadingly indented, due to the presence
167   of that macro.
168
169      #define engine_ref_debug(X, Y, Z)
170
171      if (locked)
172        i = foo (0);
173      else
174        i = foo (1);
175      engine_ref_debug(e, 0, -1)
176        if (i > 0)
177        return 1;
178
179   Return true if such an unindent/outdent is detected.  */
180
181static bool
182detect_intervening_unindent (const char *file,
183			     int body_line,
184			     int next_stmt_line,
185			     unsigned int vis_column,
186			     unsigned int tab_width)
187{
188  gcc_assert (file);
189  gcc_assert (next_stmt_line > body_line);
190
191  for (int line = body_line + 1; line < next_stmt_line; line++)
192    {
193      unsigned int line_vis_column;
194      if (get_first_nws_vis_column (file, line, &line_vis_column, tab_width))
195	if (line_vis_column < vis_column)
196	  return true;
197    }
198
199  /* Not found.  */
200  return false;
201}
202
203
204/* Helper function for warn_for_misleading_indentation; see
205   description of that function below.  */
206
207static bool
208should_warn_for_misleading_indentation (const token_indent_info &guard_tinfo,
209					const token_indent_info &body_tinfo,
210					const token_indent_info &next_tinfo)
211{
212  location_t guard_loc = guard_tinfo.location;
213  location_t body_loc = body_tinfo.location;
214  location_t next_stmt_loc = next_tinfo.location;
215
216  enum cpp_ttype body_type = body_tinfo.type;
217  enum cpp_ttype next_tok_type = next_tinfo.type;
218
219  /* Don't attempt to compare the indentation of BODY_LOC and NEXT_STMT_LOC
220     if either are within macros.  */
221  if (linemap_location_from_macro_expansion_p (line_table, body_loc)
222      || linemap_location_from_macro_expansion_p (line_table, next_stmt_loc))
223    return false;
224
225  /* Don't attempt to compare indentation if #line or # 44 "file"-style
226     directives are present, suggesting generated code.
227
228     All bets are off if these are present: the file that the #line
229     directive could have an entirely different coding layout to C/C++
230     (e.g. .md files).
231
232     To determine if a #line is present, in theory we could look for a
233     map with reason == LC_RENAME_VERBATIM.  However, if there has
234     subsequently been a long line requiring a column number larger than
235     that representable by the original LC_RENAME_VERBATIM map, then
236     we'll have a map with reason LC_RENAME.
237     Rather than attempting to search all of the maps for a
238     LC_RENAME_VERBATIM, instead we have libcpp set a flag whenever one
239     is seen, and we check for the flag here.
240  */
241  if (line_table->seen_line_directive)
242    return false;
243
244  /* We can't usefully warn about do-while and switch statements since the
245     bodies of these statements are always explicitly delimited at both ends,
246     so control flow is quite obvious.  */
247  if (guard_tinfo.keyword == RID_DO
248      || guard_tinfo.keyword == RID_SWITCH)
249    return false;
250
251  /* If the token following the body is a close brace or an "else"
252     then while indentation may be sloppy, there is not much ambiguity
253     about control flow, e.g.
254
255     if (foo)       <- GUARD
256       bar ();      <- BODY
257       else baz (); <- NEXT
258
259     {
260     while (foo)  <- GUARD
261     bar ();      <- BODY
262     }            <- NEXT
263     baz ();
264  */
265  if (next_tok_type == CPP_CLOSE_BRACE
266      || next_tinfo.keyword == RID_ELSE)
267    return false;
268
269  /* Likewise, if the body of the guard is a compound statement then control
270     flow is quite visually explicit regardless of the code's possibly poor
271     indentation, e.g.
272
273     while (foo)  <- GUARD
274       {          <- BODY
275       bar ();
276       }
277       baz ();    <- NEXT
278
279    Things only get muddy when the body of the guard does not have
280    braces, e.g.
281
282    if (foo)  <- GUARD
283      bar (); <- BODY
284      baz (); <- NEXT
285  */
286  if (body_type == CPP_OPEN_BRACE)
287    return false;
288
289  /* Don't warn here about spurious semicolons.  */
290  if (next_tok_type == CPP_SEMICOLON)
291    return false;
292
293  expanded_location body_exploc = expand_location (body_loc);
294  expanded_location next_stmt_exploc = expand_location (next_stmt_loc);
295  expanded_location guard_exploc = expand_location (guard_loc);
296
297  const unsigned int tab_width = cpp_opts->tabstop;
298
299  /* They must be in the same file.  */
300  if (next_stmt_exploc.file != body_exploc.file)
301    return false;
302
303  /* If NEXT_STMT_LOC and BODY_LOC are on the same line, consider
304     the location of the guard.
305
306     Cases where we want to issue a warning:
307
308       if (flag)
309         foo ();  bar ();
310                  ^ WARN HERE
311
312       if (flag) foo (); bar ();
313                         ^ WARN HERE
314
315
316       if (flag) ; {
317                   ^ WARN HERE
318
319       if (flag)
320        ; {
321          ^ WARN HERE
322
323     Cases where we don't want to issue a warning:
324
325       various_code (); if (flag) foo (); bar (); more_code ();
326                                          ^ DON'T WARN HERE.  */
327  if (next_stmt_exploc.line == body_exploc.line)
328    {
329      if (guard_exploc.file != body_exploc.file)
330	return true;
331      if (guard_exploc.line < body_exploc.line)
332	/* The guard is on a line before a line that contains both
333	   the body and the next stmt.  */
334	return true;
335      else if (guard_exploc.line == body_exploc.line)
336	{
337	  /* They're all on the same line.  */
338	  gcc_assert (guard_exploc.file == next_stmt_exploc.file);
339	  gcc_assert (guard_exploc.line == next_stmt_exploc.line);
340	  unsigned int guard_vis_column;
341	  unsigned int guard_line_first_nws;
342	  if (!get_visual_column (guard_exploc, guard_loc,
343				  &guard_vis_column,
344				  &guard_line_first_nws, tab_width))
345	    return false;
346	  /* Heuristic: only warn if the guard is the first thing
347	     on its line.  */
348	  if (guard_vis_column == guard_line_first_nws)
349	    return true;
350	}
351    }
352
353  /* If NEXT_STMT_LOC is on a line after BODY_LOC, consider
354     their relative locations, and of the guard.
355
356     Cases where we want to issue a warning:
357        if (flag)
358          foo ();
359          bar ();
360          ^ WARN HERE
361
362     Cases where we don't want to issue a warning:
363        if (flag)
364        foo ();
365        bar ();
366        ^ DON'T WARN HERE (autogenerated code?)
367
368	if (flagA)
369	  foo ();
370      #if SOME_CONDITION_THAT_DOES_NOT_HOLD
371	if (flagB)
372      #endif
373	  bar ();
374	  ^ DON'T WARN HERE
375
376	if (flag)
377	  ;
378	  foo ();
379	  ^ DON'T WARN HERE
380
381	#define emit
382	if (flag)
383	     foo ();
384	emit bar ();
385	     ^ DON'T WARN HERE
386
387  */
388  if (next_stmt_exploc.line > body_exploc.line)
389    {
390      /* Determine if GUARD_LOC and NEXT_STMT_LOC are aligned on the same
391	 "visual column"...  */
392      unsigned int next_stmt_vis_column;
393      unsigned int next_stmt_line_first_nws;
394      unsigned int body_vis_column;
395      unsigned int body_line_first_nws;
396      unsigned int guard_vis_column;
397      unsigned int guard_line_first_nws;
398      /* If we can't determine it, don't issue a warning.  This is sometimes
399	 the case for input files containing #line directives, and these
400	 are often for autogenerated sources (e.g. from .md files), where
401	 it's not clear that it's meaningful to look at indentation.  */
402      if (!get_visual_column (next_stmt_exploc, next_stmt_loc,
403			      &next_stmt_vis_column,
404			      &next_stmt_line_first_nws, tab_width))
405	return false;
406      if (!get_visual_column (body_exploc, body_loc,
407			      &body_vis_column,
408			      &body_line_first_nws, tab_width))
409	return false;
410      if (!get_visual_column (guard_exploc, guard_loc,
411			      &guard_vis_column,
412			      &guard_line_first_nws, tab_width))
413	return false;
414
415      /* If the line where the next stmt starts has non-whitespace
416	 on it before the stmt, then don't warn:
417	  #define emit
418	  if (flag)
419	       foo ();
420	  emit bar ();
421	       ^ DON'T WARN HERE
422	 (PR c/69122).  */
423      if (next_stmt_line_first_nws < next_stmt_vis_column)
424	return false;
425
426      if ((body_type != CPP_SEMICOLON
427	   && next_stmt_vis_column == body_vis_column)
428	  /* As a special case handle the case where the body is a semicolon
429	     that may be hidden by a preceding comment, e.g.  */
430
431	  // if (p)
432	  //   /* blah */;
433	  //   foo (1);
434
435	  /*  by looking instead at the column of the first non-whitespace
436	      character on the body line.  */
437	  || (body_type == CPP_SEMICOLON
438	      && body_exploc.line > guard_exploc.line
439	      && body_line_first_nws != body_vis_column
440	      && next_stmt_vis_column > guard_line_first_nws))
441	{
442          /* Don't warn if they are aligned on the same column
443	     as the guard itself (suggesting autogenerated code that doesn't
444	     bother indenting at all).
445	     For "else" clauses, we consider the column of the first
446	     non-whitespace character on the guard line instead of the column
447	     of the actual guard token itself because it is more sensible.
448	     Consider:
449
450	     if (p) {
451	     foo (1);
452	     } else     // GUARD
453	     foo (2);   // BODY
454	     foo (3);   // NEXT
455
456	     and:
457
458	     if (p)
459	       foo (1);
460	     } else       // GUARD
461	       foo (2);   // BODY
462	       foo (3);   // NEXT
463
464	     If we just used the column of the "else" token, we would warn on
465	     the first example and not warn on the second.  But we want the
466	     exact opposite to happen: to not warn on the first example (which
467	     is probably autogenerated) and to warn on the second (whose
468	     indentation is misleading).  Using the column of the first
469	     non-whitespace character on the guard line makes that
470	     happen.  */
471	  unsigned int guard_column = (guard_tinfo.keyword == RID_ELSE
472				       ? guard_line_first_nws
473				       : guard_vis_column);
474	  if (guard_column == body_vis_column)
475	    return false;
476
477	  /* We may have something like:
478
479	     if (p)
480	       {
481	       foo (1);
482	       } else  // GUARD
483	     foo (2);  // BODY
484	     foo (3);  // NEXT
485
486	     in which case the columns are not aligned but the code is not
487	     misleadingly indented.  If the column of the body isn't indented
488	     more than the guard line then don't warn.  */
489	  if (body_vis_column <= guard_line_first_nws)
490	    return false;
491
492	  /* Don't warn if there is an unindent between the two statements. */
493	  int vis_column = MIN (next_stmt_vis_column, body_vis_column);
494	  if (detect_intervening_unindent (body_exploc.file, body_exploc.line,
495					   next_stmt_exploc.line,
496					   vis_column, tab_width))
497	    return false;
498
499	  /* Otherwise, they are visually aligned: issue a warning.  */
500	  return true;
501	}
502
503	/* Also issue a warning for code having the form:
504
505	   if (flag);
506	     foo ();
507
508	   while (flag);
509	   {
510	     ...
511	   }
512
513	   for (...);
514	     {
515	       ...
516	     }
517
518	   if (flag)
519	     ;
520	   else if (flag);
521	     foo ();
522
523	   where the semicolon at the end of each guard is most likely spurious.
524
525	   But do not warn on:
526
527	   for (..);
528	   foo ();
529
530	   where the next statement is aligned with the guard.
531	*/
532	if (body_type == CPP_SEMICOLON)
533	  {
534	    if (body_exploc.line == guard_exploc.line)
535	      {
536		if (next_stmt_vis_column > guard_line_first_nws
537		    || (next_tok_type == CPP_OPEN_BRACE
538			&& next_stmt_vis_column == guard_line_first_nws))
539		  return true;
540	      }
541	  }
542    }
543
544  return false;
545}
546
547/* Return the string identifier corresponding to the given guard token.  */
548
549const char *
550guard_tinfo_to_string (enum rid keyword)
551{
552  switch (keyword)
553    {
554    case RID_FOR:
555      return "for";
556    case RID_ELSE:
557      return "else";
558    case RID_IF:
559      return "if";
560    case RID_WHILE:
561      return "while";
562    case RID_DO:
563      return "do";
564    case RID_SWITCH:
565      return "switch";
566    default:
567      gcc_unreachable ();
568    }
569}
570
571/* Called by the C/C++ frontends when we have a guarding statement at
572   GUARD_LOC containing a statement at BODY_LOC, where the block wasn't
573   written using braces, like this:
574
575     if (flag)
576       foo ();
577
578   along with the location of the next token, at NEXT_STMT_LOC,
579   so that we can detect followup statements that are within
580   the same "visual block" as the guarded statement, but which
581   aren't logically grouped within the guarding statement, such
582   as:
583
584     GUARD_LOC
585     |
586     V
587     if (flag)
588       foo (); <- BODY_LOC
589       bar (); <- NEXT_STMT_LOC
590
591   In the above, "bar ();" isn't guarded by the "if", but
592   is indented to misleadingly suggest that it is in the same
593   block as "foo ();".
594
595   GUARD_KIND identifies the kind of clause e.g. "if", "else" etc.  */
596
597void
598warn_for_misleading_indentation (const token_indent_info &guard_tinfo,
599				 const token_indent_info &body_tinfo,
600				 const token_indent_info &next_tinfo)
601{
602  /* Early reject for the case where -Wmisleading-indentation is disabled,
603     to avoid doing work only to have the warning suppressed inside the
604     diagnostic machinery.  */
605  if (!warn_misleading_indentation)
606    return;
607
608  if (should_warn_for_misleading_indentation (guard_tinfo,
609					      body_tinfo,
610					      next_tinfo))
611    {
612      auto_diagnostic_group d;
613      if (warning_at (guard_tinfo.location, OPT_Wmisleading_indentation,
614		      "this %qs clause does not guard...",
615		      guard_tinfo_to_string (guard_tinfo.keyword)))
616	inform (next_tinfo.location,
617		"...this statement, but the latter is misleadingly indented"
618		" as if it were guarded by the %qs",
619		guard_tinfo_to_string (guard_tinfo.keyword));
620    }
621}
622
623#if CHECKING_P
624
625namespace selftest {
626
627/* Verify that next_tab_stop works as expected.  */
628
629static void
630test_next_tab_stop ()
631{
632  const unsigned int tab_width = 8;
633
634  ASSERT_EQ (next_tab_stop (0, tab_width), 8);
635  ASSERT_EQ (next_tab_stop (1, tab_width), 8);
636  ASSERT_EQ (next_tab_stop (7, tab_width), 8);
637
638  ASSERT_EQ (next_tab_stop (8, tab_width), 16);
639  ASSERT_EQ (next_tab_stop (9, tab_width), 16);
640  ASSERT_EQ (next_tab_stop (15, tab_width), 16);
641
642  ASSERT_EQ (next_tab_stop (16, tab_width), 24);
643  ASSERT_EQ (next_tab_stop (17, tab_width), 24);
644  ASSERT_EQ (next_tab_stop (23, tab_width), 24);
645}
646
647/* Verify that the given call to get_visual_column succeeds, with
648   the given results.  */
649
650static void
651assert_get_visual_column_succeeds (const location &loc,
652				   const char *file, int line, int column,
653				   const unsigned int tab_width,
654				   unsigned int expected_visual_column,
655				   unsigned int expected_first_nws)
656{
657  expanded_location exploc;
658  exploc.file = file;
659  exploc.line = line;
660  exploc.column = column;
661  exploc.data = NULL;
662  exploc.sysp = false;
663  unsigned int actual_visual_column;
664  unsigned int actual_first_nws;
665  bool result = get_visual_column (exploc, UNKNOWN_LOCATION,
666				   &actual_visual_column,
667				   &actual_first_nws, tab_width);
668  ASSERT_TRUE_AT (loc, result);
669  ASSERT_EQ_AT (loc, actual_visual_column, expected_visual_column);
670  ASSERT_EQ_AT (loc, actual_first_nws, expected_first_nws);
671}
672
673/* Verify that the given call to get_visual_column succeeds, with
674   the given results.  */
675
676#define ASSERT_GET_VISUAL_COLUMN_SUCCEEDS(FILENAME, LINE, COLUMN,	\
677					  TAB_WIDTH,			\
678					  EXPECTED_VISUAL_COLUMN,	\
679					  EXPECTED_FIRST_NWS)		\
680  SELFTEST_BEGIN_STMT							\
681    assert_get_visual_column_succeeds (SELFTEST_LOCATION,		\
682				       FILENAME, LINE, COLUMN,		\
683				       TAB_WIDTH,			\
684				       EXPECTED_VISUAL_COLUMN,		\
685				       EXPECTED_FIRST_NWS);		\
686  SELFTEST_END_STMT
687
688/* Verify that the given call to get_visual_column fails gracefully.  */
689
690static void
691assert_get_visual_column_fails (const location &loc,
692				const char *file, int line, int column,
693				const unsigned int tab_width)
694{
695  expanded_location exploc;
696  exploc.file = file;
697  exploc.line = line;
698  exploc.column = column;
699  exploc.data = NULL;
700  exploc.sysp = false;
701  unsigned int actual_visual_column;
702  unsigned int actual_first_nws;
703  bool result = get_visual_column (exploc, UNKNOWN_LOCATION,
704				   &actual_visual_column,
705				   &actual_first_nws, tab_width);
706  ASSERT_FALSE_AT (loc, result);
707}
708
709/* Verify that the given call to get_visual_column fails gracefully.  */
710
711#define ASSERT_GET_VISUAL_COLUMN_FAILS(FILENAME, LINE, COLUMN,	\
712				       TAB_WIDTH)		\
713  SELFTEST_BEGIN_STMT						\
714    assert_get_visual_column_fails (SELFTEST_LOCATION,		\
715				    FILENAME, LINE, COLUMN,	\
716				    TAB_WIDTH);		\
717  SELFTEST_END_STMT
718
719/* Verify that get_visual_column works as expected.  */
720
721static void
722test_get_visual_column ()
723{
724  /* Create a tempfile with a mixture of tabs and spaces.
725
726     Both lines have either a space or a tab, then " line N",
727     for 8 characters in total.
728
729     1-based "columns" (w.r.t. to line 1):
730     .....................0000000001111.
731     .....................1234567890123.  */
732  const char *content = ("  line 1\n"
733			 "\t line 2\n");
734  line_table_test ltt;
735  temp_source_file tmp (SELFTEST_LOCATION, ".txt", content);
736
737  const unsigned int tab_width = 8;
738  const char *file = tmp.get_filename ();
739
740  /* Line 1 (space-based indentation).  */
741  {
742    const int line = 1;
743    ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (file, line, 1, tab_width, 0, 0);
744    ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (file, line, 2, tab_width, 1, 1);
745    ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (file, line, 3, tab_width, 2, 2);
746    /* first_nws should have stopped increasing.  */
747    ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (file, line, 4, tab_width, 3, 2);
748    /* Verify the end-of-line boundary.  */
749    ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (file, line, 8, tab_width, 7, 2);
750    ASSERT_GET_VISUAL_COLUMN_FAILS (file, line, 9, tab_width);
751  }
752
753  /* Line 2 (tab-based indentation).  */
754  {
755    const int line = 2;
756    ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (file, line, 1, tab_width, 0, 0);
757    ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (file, line, 2, tab_width, 8, 8);
758    ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (file, line, 3, tab_width, 9, 9);
759    /* first_nws should have stopped increasing.  */
760    ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (file, line, 4, tab_width, 10, 9);
761    /* Verify the end-of-line boundary.  */
762    ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (file, line, 8, tab_width, 14, 9);
763    ASSERT_GET_VISUAL_COLUMN_FAILS (file, line, 9, tab_width);
764  }
765}
766
767/* Run all of the selftests within this file.  */
768
769void
770c_indentation_c_tests ()
771{
772  test_next_tab_stop ();
773  test_get_visual_column ();
774}
775
776} // namespace selftest
777
778#endif /* CHECKING_P */
779