annotate gcc/doc/ux.texi @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1 @c Copyright (C) 2018-2020 Free Software Foundation, Inc.
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2 @c Free Software Foundation, Inc.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3 @c This is part of the GCC manual.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4 @c For copying conditions, see the file gcc.texi.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
5
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
6 @node User Experience Guidelines
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
7 @chapter User Experience Guidelines
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
8 @cindex user experience guidelines
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
9 @cindex guidelines, user experience
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
10
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
11 To borrow a slogan from
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
12 @uref{https://elm-lang.org/news/compilers-as-assistants, Elm},
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
13
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
14 @quotation
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
15 @strong{Compilers should be assistants, not adversaries.} A compiler should
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
16 not just detect bugs, it should then help you understand why there is a bug.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
17 It should not berate you in a robot voice, it should give you specific hints
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
18 that help you write better code. Ultimately, a compiler should make
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
19 programming faster and more fun!
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
20 @author Evan Czaplicki
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
21 @end quotation
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
22
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
23 This chapter provides guidelines on how to implement diagnostics and
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
24 command-line options in ways that we hope achieve the above ideal.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
25
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
26 @menu
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
27 * Guidelines for Diagnostics:: How to implement diagnostics.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
28 * Guidelines for Options:: Guidelines for command-line options.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
29 @end menu
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
30
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
31
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
32 @node Guidelines for Diagnostics
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
33 @section Guidelines for Diagnostics
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
34 @cindex guidelines for diagnostics
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
35 @cindex diagnostics, guidelines for
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
36
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
37 @subsection Talk in terms of the user's code
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
38
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
39 Diagnostics should be worded in terms of the user's source code, and the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
40 source language, rather than GCC's own implementation details.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
41
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
42 @subsection Diagnostics are actionable
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
43 @cindex diagnostics, actionable
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
44
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
45 A good diagnostic is @dfn{actionable}: it should assist the user in
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
46 taking action.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
47
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
48 Consider what an end user will want to do when encountering a diagnostic.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
49
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
50 Given an error, an end user will think: ``How do I fix this?''
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
51
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
52 Given a warning, an end user will think:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
53
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
54 @itemize @bullet
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
55 @item
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
56 ``Is this a real problem?''
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
57 @item
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
58 ``Do I care?''
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
59 @item
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
60 if they decide it's genuine: ``How do I fix this?''
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
61 @end itemize
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
62
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
63 A good diagnostic provides pertinent information to allow the user to
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
64 easily answer the above questions.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
65
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
66 @subsection The user's attention is important
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
67
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
68 A perfect compiler would issue a warning on every aspect of the user's
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
69 source code that ought to be fixed, and issue no other warnings.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
70 Naturally, this ideal is impossible to achieve.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
71
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
72 @cindex signal-to-noise ratio (metaphorical usage for diagnostics)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
73 @cindex diagnostics, false positive
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
74 @cindex diagnostics, true positive
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
75 @cindex false positive
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
76 @cindex true positive
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
77
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
78 Warnings should have a good @dfn{signal-to-noise ratio}: we should have few
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
79 @dfn{false positives} (falsely issuing a warning when no warning is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
80 warranted) and few @dfn{false negatives} (failing to issue a warning when
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
81 one @emph{is} justified).
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
82
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
83 Note that a false positive can mean, in practice, a warning that the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
84 user doesn't agree with. Ideally a diagnostic should contain enough
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
85 information to allow the user to make an informed choice about whether
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
86 they should care (and how to fix it), but a balance must be drawn against
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
87 overloading the user with irrelevant data.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
88
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
89 @subsection Precision of Wording
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
90
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
91 Provide the user with details that allow them to identify what the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
92 problem is. For example, the vaguely-worded message:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
93
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
94 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
95 demo.c:1:1: warning: 'noinline' attribute ignored [-Wattributes]
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
96 1 | int foo __attribute__((noinline));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
97 | ^~~
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
98 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
99
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
100 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
101 doesn't tell the user why the attribute was ignored, or what kind of
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
102 entity the compiler thought the attribute was being applied to (the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
103 source location for the diagnostic is also poor;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
104 @pxref{input_location_example,,discussion of @code{input_location}}).
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
105 A better message would be:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
106
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
107 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
108 demo.c:1:24: warning: attribute 'noinline' on variable 'foo' was
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
109 ignored [-Wattributes]
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
110 1 | int foo __attribute__((noinline));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
111 | ~~~ ~~~~~~~~~~~~~~~^~~~~~~~~
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
112 demo.c:1:24: note: attribute 'noinline' is only applicable to functions
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
113 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
114
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
115 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
116 which spells out the missing information (and fixes the location
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
117 information, as discussed below).
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
118
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
119 The above example uses a note to avoid a combinatorial explosion of possible
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
120 messages.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
121
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
122 @subsection Try the diagnostic on real-world code
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
123
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
124 It's worth testing a new warning on many instances of real-world code,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
125 written by different people, and seeing what it complains about, and
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
126 what it doesn't complain about.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
127
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
128 This may suggest heuristics that silence common false positives.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
129
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
130 It may also suggest ways to improve the precision of the message.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
132 @subsection Make mismatches clear
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
133
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
134 Many diagnostics relate to a mismatch between two different places in the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
135 user's source code. Examples include:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
136 @itemize @bullet
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
137 @item
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
138 a type mismatch, where the type at a usage site does not match the type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
139 at a declaration
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
140
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
141 @item
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
142 the argument count at a call site does not match the parameter count
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
143 at the declaration
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
144
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
145 @item
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
146 something is erroneously duplicated (e.g.@: an error, due to breaking a
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
147 uniqueness requirement, or a warning, if it's suggestive of a bug)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
148
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
149 @item
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
150 an ``opened'' syntactic construct (such as an open-parenthesis) is not
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
151 closed
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
152
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
153 @c TODO: more examples?
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
154 @end itemize
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
155
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
156 In each case, the diagnostic should indicate @strong{both} pertinent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
157 locations (so that the user can easily see the problem and how to fix it).
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
158
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
159 The standard way to do this is with a note (via @code{inform}). For
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
160 example:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
161
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
162 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
163 auto_diagnostic_group d;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
164 if (warning_at (loc, OPT_Wduplicated_cond,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
165 "duplicated %<if%> condition"))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
166 inform (EXPR_LOCATION (t), "previously used here");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
167 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
168
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
169 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
170 which leads to:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
171
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
172 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
173 demo.c: In function 'test':
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
174 demo.c:5:17: warning: duplicated 'if' condition [-Wduplicated-cond]
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
175 5 | else if (flag > 3)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
176 | ~~~~~^~~
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
177 demo.c:3:12: note: previously used here
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
178 3 | if (flag > 3)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
179 | ~~~~~^~~
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
180 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
181
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
182 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
183 The @code{inform} call should be guarded by the return value from the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
184 @code{warning_at} call so that the note isn't emitted when the warning
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
185 is suppressed.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
186
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
187 For cases involving punctuation where the locations might be near
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
188 each other, they can be conditionally consolidated via
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
189 @code{gcc_rich_location::add_location_if_nearby}:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
190
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
191 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
192 auto_diagnostic_group d;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
193 gcc_rich_location richloc (primary_loc);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
194 bool added secondary = richloc.add_location_if_nearby (secondary_loc);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
195 error_at (&richloc, "main message");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
196 if (!added secondary)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
197 inform (secondary_loc, "message for secondary");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
198 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
199
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
200 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
201 This will emit either one diagnostic with two locations:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
202 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
203 demo.c:42:10: error: main message
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
204 (foo)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
205 ~ ^
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
206 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
207
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
208 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
209 or two diagnostics:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
210
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
211 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
212 demo.c:42:4: error: main message
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
213 foo)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
214 ^
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
215 demo.c:40:2: note: message for secondary
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
216 (
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
217 ^
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
218 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
219
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
220 @subsection Location Information
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
221 @cindex diagnostics, locations
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
222 @cindex location information
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
223 @cindex source code, location information
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
224 @cindex caret
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
225
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
226 GCC's @code{location_t} type can support both ordinary locations,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
227 and locations relating to a macro expansion.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
228
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
229 As of GCC 6, ordinary locations changed from supporting just a
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
230 point in the user's source code to supporting three points: the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
231 @dfn{caret} location, plus a start and a finish:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
232
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
233 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
234 a = foo && bar;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
235 ~~~~^~~~~~
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
236 | | |
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
237 | | finish
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
238 | caret
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
239 start
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
240 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
241
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
242 Tokens coming out of libcpp have locations of the form @code{caret == start},
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
243 such as for @code{foo} here:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
244
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
245 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
246 a = foo && bar;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
247 ^~~
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
248 | |
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
249 | finish
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
250 caret == start
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
251 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
252
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
253 Compound expressions should be reported using the location of the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
254 expression as a whole, rather than just of one token within it.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
255
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
256 For example, in @code{-Wformat}, rather than underlining just the first
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
257 token of a bad argument:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
258
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
259 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
260 printf("hello %i %s", (long)0, "world");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
261 ~^ ~
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
262 %li
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
263 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
264
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
265 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
266 the whole of the expression should be underlined, so that the user can
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
267 easily identify what is being referred to:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
268
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
269 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
270 printf("hello %i %s", (long)0, "world");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
271 ~^ ~~~~~~~
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
272 %li
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
273 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
274
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
275 @c this was r251239
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
276
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
277 Avoid using the @code{input_location} global, and the diagnostic functions
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
278 that implicitly use it---use @code{error_at} and @code{warning_at} rather
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
279 than @code{error} and @code{warning}, and provide the most appropriate
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
280 @code{location_t} value available at that phase of the compilation. It's
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
281 possible to supply secondary @code{location_t} values via
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
282 @code{rich_location}.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
283
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
284 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
285 @anchor{input_location_example}
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
286 For example, in the example of imprecise wording above, generating the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
287 diagnostic using @code{warning}:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
288
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
289 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
290 // BAD: implicitly uses @code{input_location}
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
291 warning (OPT_Wattributes, "%qE attribute ignored", name);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
292 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
293
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
294 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
295 leads to:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
296
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
297 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
298 // BAD: uses @code{input_location}
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
299 demo.c:1:1: warning: 'noinline' attribute ignored [-Wattributes]
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
300 1 | int foo __attribute__((noinline));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
301 | ^~~
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
302 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
303
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
304 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
305 which thus happened to use the location of the @code{int} token, rather
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
306 than that of the attribute. Using @code{warning_at} with the location of
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
307 the attribute, providing the location of the declaration in question
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
308 as a secondary location, and adding a note:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
309
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
310 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
311 auto_diagnostic_group d;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
312 gcc_rich_location richloc (attrib_loc);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
313 richloc.add_range (decl_loc);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
314 if (warning_at (OPT_Wattributes, &richloc,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
315 "attribute %qE on variable %qE was ignored", name))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
316 inform (attrib_loc, "attribute %qE is only applicable to functions");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
317 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
318
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
319 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
320 would lead to:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
321
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
322 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
323 // OK: use location of attribute, with a secondary location
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
324 demo.c:1:24: warning: attribute 'noinline' on variable 'foo' was
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
325 ignored [-Wattributes]
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
326 1 | int foo __attribute__((noinline));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
327 | ~~~ ~~~~~~~~~~~~~~~^~~~~~~~~
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
328 demo.c:1:24: note: attribute 'noinline' is only applicable to functions
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
329 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
330
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
331 @c TODO labelling of ranges
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
332
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
333 @subsection Coding Conventions
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
334
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
335 See the @uref{https://gcc.gnu.org/codingconventions.html#Diagnostics,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
336 diagnostics section} of the GCC coding conventions.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
337
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
338 In the C++ front end, when comparing two types in a message, use @samp{%H}
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
339 and @samp{%I} rather than @samp{%T}, as this allows the diagnostics
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
340 subsystem to highlight differences between template-based types.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
341 For example, rather than using @samp{%qT}:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
342
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
343 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
344 // BAD: a pair of %qT used in C++ front end for type comparison
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
345 error_at (loc, "could not convert %qE from %qT to %qT", expr,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
346 TREE_TYPE (expr), type);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
347 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
348
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
349 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
350 which could lead to:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
351
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
352 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
353 error: could not convert 'map<int, double>()' from 'map<int,double>'
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
354 to 'map<int,int>'
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
355 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
356
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
357 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
358 using @samp{%H} and @samp{%I} (via @samp{%qH} and @samp{%qI}):
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
359
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
360 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
361 // OK: compare types in C++ front end via %qH and %qI
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
362 error_at (loc, "could not convert %qE from %qH to %qI", expr,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
363 TREE_TYPE (expr), type);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
364 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
365
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
366 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
367 allows the above output to be simplified to:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
368
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
369 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
370 error: could not convert 'map<int, double>()' from 'map<[...],double>'
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
371 to 'map<[...],int>'
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
372 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
373
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
374 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
375 where the @code{double} and @code{int} are colorized to highlight them.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
376
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
377 @c %H and %I were added in r248698.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
378
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
379 @subsection Group logically-related diagnostics
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
380
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
381 Use @code{auto_diagnostic_group} when issuing multiple related
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
382 diagnostics (seen in various examples on this page). This informs the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
383 diagnostic subsystem that all diagnostics issued within the lifetime
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
384 of the @code{auto_diagnostic_group} are related. For example,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
385 @option{-fdiagnostics-format=json} will treat the first diagnostic
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
386 emitted within the group as a top-level diagnostic, and all subsequent
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
387 diagnostics within the group as its children.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
388
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
389 @subsection Quoting
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
390 Text should be quoted by either using the @samp{q} modifier in a directive
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
391 such as @samp{%qE}, or by enclosing the quoted text in a pair of @samp{%<}
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
392 and @samp{%>} directives, and never by using explicit quote characters.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
393 The directives handle the appropriate quote characters for each language
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
394 and apply the correct color or highlighting.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
395
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
396 The following elements should be quoted in GCC diagnostics:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
397
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
398 @itemize @bullet
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
399 @item
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
400 Language keywords.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
401 @item
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
402 Tokens.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
403 @item
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
404 Boolean, numerical, character, and string constants that appear in the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
405 source code.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
406 @item
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
407 Identifiers, including function, macro, type, and variable names.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
408 @end itemize
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
409
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
410 Other elements such as numbers that do not refer to numeric constants that
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
411 appear in the source code should not be quoted. For example, in the message:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
412
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
413 @smallexample
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
414 argument %d of %qE must be a pointer type
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
415 @end smallexample
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
416
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
417 @noindent
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
418 since the argument number does not refer to a numerical constant in the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
419 source code it should not be quoted.
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
420
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
421 @subsection Spelling and Terminology
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
422
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
423 See the @uref{https://gcc.gnu.org/codingconventions.html#Spelling
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
424 Spelling, terminology and markup} section of the GCC coding conventions.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
425
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
426 @subsection Fix-it hints
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
427 @cindex fix-it hints
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
428 @cindex diagnostics guidelines, fix-it hints
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
429
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
430 GCC's diagnostic subsystem can emit @dfn{fix-it hints}: small suggested
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
431 edits to the user's source code.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
432
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
433 They are printed by default underneath the code in question. They
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
434 can also be viewed via @option{-fdiagnostics-generate-patch} and
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
435 @option{-fdiagnostics-parseable-fixits}. With the latter, an IDE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
436 ought to be able to offer to automatically apply the suggested fix.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
437
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
438 Fix-it hints contain code fragments, and thus they should not be marked
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
439 for translation.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
440
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
441 Fix-it hints can be added to a diagnostic by using a @code{rich_location}
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
442 rather than a @code{location_t} - the fix-it hints are added to the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
443 @code{rich_location} using one of the various @code{add_fixit} member
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
444 functions of @code{rich_location}. They are documented with
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
445 @code{rich_location} in @file{libcpp/line-map.h}.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
446 It's easiest to use the @code{gcc_rich_location} subclass of
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
447 @code{rich_location} found in @file{gcc-rich-location.h}, as this
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
448 implicitly supplies the @code{line_table} variable.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
449
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
450 For example:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
451
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
452 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
453 if (const char *suggestion = hint.suggestion ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
454 @{
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
455 gcc_rich_location richloc (location);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
456 richloc.add_fixit_replace (suggestion);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
457 error_at (&richloc,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
458 "%qE does not name a type; did you mean %qs?",
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
459 id, suggestion);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
460 @}
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
461 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
462
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
463 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
464 which can lead to:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
465
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
466 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
467 spellcheck-typenames.C:73:1: error: 'singed' does not name a type; did
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
468 you mean 'signed'?
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
469 73 | singed char ch;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
470 | ^~~~~~
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
471 | signed
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
472 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
473
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
474 Non-trivial edits can be built up by adding multiple fix-it hints to one
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
475 @code{rich_location}. It's best to express the edits in terms of the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
476 locations of individual tokens. Various handy functions for adding
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
477 fix-it hints for idiomatic C and C++ can be seen in
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
478 @file{gcc-rich-location.h}.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
479
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
480 @subsubsection Fix-it hints should work
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
481
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
482 When implementing a fix-it hint, please verify that the suggested edit
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
483 leads to fixed, compilable code. (Unfortunately, this currently must be
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
484 done by hand using @option{-fdiagnostics-generate-patch}. It would be
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
485 good to have an automated way of verifying that fix-it hints actually fix
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
486 the code).
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
487
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
488 For example, a ``gotcha'' here is to forget to add a space when adding a
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
489 missing reserved word. Consider a C++ fix-it hint that adds
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
490 @code{typename} in front of a template declaration. A naive way to
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
491 implement this might be:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
492
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
493 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
494 gcc_rich_location richloc (loc);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
495 // BAD: insertion is missing a trailing space
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
496 richloc.add_fixit_insert_before ("typename");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
497 error_at (&richloc, "need %<typename%> before %<%T::%E%> because "
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
498 "%qT is a dependent scope",
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
499 parser->scope, id, parser->scope);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
500 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
501
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
502 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
503 When applied to the code, this might lead to:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
504
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
505 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
506 T::type x;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
507 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
508
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
509 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
510 being ``corrected'' to:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
511
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
512 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
513 typenameT::type x;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
514 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
515
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
516 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
517 In this case, the correct thing to do is to add a trailing space after
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
518 @code{typename}:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
519
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
520 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
521 gcc_rich_location richloc (loc);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
522 // OK: note that here we have a trailing space
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
523 richloc.add_fixit_insert_before ("typename ");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
524 error_at (&richloc, "need %<typename%> before %<%T::%E%> because "
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
525 "%qT is a dependent scope",
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
526 parser->scope, id, parser->scope);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
527 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
528
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
529 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
530 leading to this corrected code:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
531
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
532 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
533 typename T::type x;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
534 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
535
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
536 @subsubsection Express deletion in terms of deletion, not replacement
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
537
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
538 It's best to express deletion suggestions in terms of deletion fix-it
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
539 hints, rather than replacement fix-it hints. For example, consider this:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
540
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
541 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
542 auto_diagnostic_group d;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
543 gcc_rich_location richloc (location_of (retval));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
544 tree name = DECL_NAME (arg);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
545 richloc.add_fixit_replace (IDENTIFIER_POINTER (name));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
546 warning_at (&richloc, OPT_Wredundant_move,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
547 "redundant move in return statement");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
548 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
549
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
550 @noindent
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
551 which is intended to e.g.@: replace a @code{std::move} with the underlying
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
552 value:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
553
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
554 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
555 return std::move (retval);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
556 ~~~~~~~~~~^~~~~~~~
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
557 retval
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
558 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
559
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
560 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
561 where the change has been expressed as replacement, replacing
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
562 with the name of the declaration.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
563 This works for simple cases, but consider this case:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
564
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
565 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
566 #ifdef SOME_CONFIG_FLAG
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
567 # define CONFIGURY_GLOBAL global_a
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
568 #else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
569 # define CONFIGURY_GLOBAL global_b
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
570 #endif
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
571
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
572 int fn ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
573 @{
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
574 return std::move (CONFIGURY_GLOBAL /* some comment */);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
575 @}
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
576 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
577
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
578 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
579 The above implementation erroneously strips out the macro and the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
580 comment in the fix-it hint:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
581
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
582 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
583 return std::move (CONFIGURY_GLOBAL /* some comment */);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
584 ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
585 global_a
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
586 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
587
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
588 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
589 and thus this resulting code:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
590
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
591 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
592 return global_a;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
593 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
594
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
595 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
596 It's better to do deletions in terms of deletions; deleting the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
597 @code{std::move (} and the trailing close-paren, leading to
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
598 this:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
599
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
600 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
601 return std::move (CONFIGURY_GLOBAL /* some comment */);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
602 ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
603 CONFIGURY_GLOBAL /* some comment */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
604 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
605
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
606 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
607 and thus this result:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
608
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
609 @smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
610 return CONFIGURY_GLOBAL /* some comment */;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
611 @end smallexample
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
612
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
613 @noindent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
614 Unfortunately, the pertinent @code{location_t} values are not always
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
615 available.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
616
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
617 @c the above was https://gcc.gnu.org/ml/gcc-patches/2018-08/msg01474.html
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
618
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
619 @subsubsection Multiple suggestions
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
620
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
621 In the rare cases where you need to suggest more than one mutually
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
622 exclusive solution to a problem, this can be done by emitting
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
623 multiple notes and calling
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
624 @code{rich_location::fixits_cannot_be_auto_applied} on each note's
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
625 @code{rich_location}. If this is called, then the fix-it hints in
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
626 the @code{rich_location} will be printed, but will not be added to
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
627 generated patches.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
628
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
629
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
630 @node Guidelines for Options
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
631 @section Guidelines for Options
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
632 @cindex command-line options, guidelines for
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
633 @cindex options, guidelines for
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
634 @cindex guidelines for options
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
635
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
636 @c TODO