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