diff options
author | Patrick Palka <ppalka@redhat.com> | 2020-09-17 14:27:22 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2020-09-17 14:27:22 -0400 |
commit | 4839de55e2c98619f4919254abb87e2f393aaead (patch) | |
tree | 6b191cd26456d813b29ea6204c1730004879fa5d /gcc/c-family/c-indentation.c | |
parent | 71e3d1970c00a74be16c0f5a3fcaced359077135 (diff) | |
download | gcc-4839de55e2c98619f4919254abb87e2f393aaead.zip gcc-4839de55e2c98619f4919254abb87e2f393aaead.tar.gz gcc-4839de55e2c98619f4919254abb87e2f393aaead.tar.bz2 |
c-family: Macro support in -Wmisleading-indentation [PR80076]
Currently the -Wmisleading-indentation warning doesn't do any analysis
when the guarded statement or the statement after it is produced by a
macro. This means we warn for:
if (flag)
foo ();
bar ();
but not for:
#define BAR bar
if (flag)
foo ();
BAR ();
This patch extends the -Wmisleading-indentation implementation to
support analyzing such statements and their tokens. This is done in the
"natural" way by resolving the location of each of the three tokens to
the token's macro expansion point. (Additionally, if the tokens all
resolve to the same macro expansion point then we instead use their
locations within the macro definition.) When these resolved locations
are all different, then we can proceed with applying the warning
heuristics to them as if no macros were involved.
gcc/c-family/ChangeLog:
PR c/80076
* c-indentation.c (should_warn_for_misleading_indentation): Move
declarations of local variables closer to their first use.
Handle virtual token locations by resolving them to their
respective macro expansion points. If all three tokens are
produced from the same macro expansion, then instead use their
loci within the macro definition.
gcc/objc/ChangeLog:
PR c/80076
* objc-gnu-runtime-abi-01.c
(gnu_runtime_abi_01_get_class_super_ref): Reduce indentation of
misleadingly indented return statements.
* objc-next-runtime-abi-01.c
(next_runtime_abi_01_get_class_super_ref): Likewise.
gcc/ChangeLog:
PR c/80076
* gensupport.c (alter_attrs_for_subst_insn) <case SET_ATTR>:
Reduce indentation of misleadingly indented code fragment.
* lra-constraints.c (multi_block_pseudo_p): Likewise.
* sel-sched-ir.c (merge_fences): Likewise.
libcpp/ChangeLog:
PR c/80076
* include/line-map.h (first_map_in_common): Declare.
* line-map.c (first_map_in_common): Remove static.
gcc/testsuite/ChangeLog:
PR c/80076
* c-c++-common/Wmisleading-indentation-5.c: New test.
Diffstat (limited to 'gcc/c-family/c-indentation.c')
-rw-r--r-- | gcc/c-family/c-indentation.c | 61 |
1 files changed, 48 insertions, 13 deletions
diff --git a/gcc/c-family/c-indentation.c b/gcc/c-family/c-indentation.c index d814f6f..8b88a8a 100644 --- a/gcc/c-family/c-indentation.c +++ b/gcc/c-family/c-indentation.c @@ -213,19 +213,6 @@ should_warn_for_misleading_indentation (const token_indent_info &guard_tinfo, const token_indent_info &body_tinfo, const token_indent_info &next_tinfo) { - location_t guard_loc = guard_tinfo.location; - location_t body_loc = body_tinfo.location; - location_t next_stmt_loc = next_tinfo.location; - - enum cpp_ttype body_type = body_tinfo.type; - enum cpp_ttype next_tok_type = next_tinfo.type; - - /* Don't attempt to compare the indentation of BODY_LOC and NEXT_STMT_LOC - if either are within macros. */ - if (linemap_location_from_macro_expansion_p (line_table, body_loc) - || linemap_location_from_macro_expansion_p (line_table, next_stmt_loc)) - return false; - /* Don't attempt to compare indentation if #line or # 44 "file"-style directives are present, suggesting generated code. @@ -266,6 +253,7 @@ should_warn_for_misleading_indentation (const token_indent_info &guard_tinfo, } <- NEXT baz (); */ + enum cpp_ttype next_tok_type = next_tinfo.type; if (next_tok_type == CPP_CLOSE_BRACE || next_tinfo.keyword == RID_ELSE) return false; @@ -287,6 +275,7 @@ should_warn_for_misleading_indentation (const token_indent_info &guard_tinfo, bar (); <- BODY baz (); <- NEXT */ + enum cpp_ttype body_type = body_tinfo.type; if (body_type == CPP_OPEN_BRACE) return false; @@ -294,6 +283,52 @@ should_warn_for_misleading_indentation (const token_indent_info &guard_tinfo, if (next_tok_type == CPP_SEMICOLON) return false; + location_t guard_loc = guard_tinfo.location; + location_t body_loc = body_tinfo.location; + location_t next_stmt_loc = next_tinfo.location; + + /* Resolve each token location to the respective macro expansion + point that produced the token. */ + if (linemap_location_from_macro_expansion_p (line_table, guard_loc)) + guard_loc = linemap_resolve_location (line_table, guard_loc, + LRK_MACRO_EXPANSION_POINT, NULL); + if (linemap_location_from_macro_expansion_p (line_table, body_loc)) + body_loc = linemap_resolve_location (line_table, body_loc, + LRK_MACRO_EXPANSION_POINT, NULL); + if (linemap_location_from_macro_expansion_p (line_table, next_stmt_loc)) + next_stmt_loc = linemap_resolve_location (line_table, next_stmt_loc, + LRK_MACRO_EXPANSION_POINT, NULL); + + /* When all three tokens are produced from a single macro expansion, we + instead consider their loci inside that macro's definition. */ + if (guard_loc == body_loc && body_loc == next_stmt_loc) + { + const line_map *guard_body_common_map + = first_map_in_common (line_table, + guard_tinfo.location, body_tinfo.location, + &guard_loc, &body_loc); + const line_map *body_next_common_map + = first_map_in_common (line_table, + body_tinfo.location, next_tinfo.location, + &body_loc, &next_stmt_loc); + + /* Punt on complicated nesting of macros. */ + if (guard_body_common_map != body_next_common_map) + return false; + + guard_loc = linemap_resolve_location (line_table, guard_loc, + LRK_MACRO_DEFINITION_LOCATION, NULL); + body_loc = linemap_resolve_location (line_table, body_loc, + LRK_MACRO_DEFINITION_LOCATION, NULL); + next_stmt_loc = linemap_resolve_location (line_table, next_stmt_loc, + LRK_MACRO_DEFINITION_LOCATION, + NULL); + } + + /* Give up if the loci are not all distinct. */ + if (guard_loc == body_loc || body_loc == next_stmt_loc) + return false; + expanded_location body_exploc = expand_location (body_loc); expanded_location next_stmt_exploc = expand_location (next_stmt_loc); expanded_location guard_exploc = expand_location (guard_loc); |