1*0bfacb9bSmrg@c Copyright (C) 2018-2020 Free Software Foundation, Inc. 2760c2415Smrg@c Free Software Foundation, Inc. 3760c2415Smrg@c This is part of the GCC manual. 4760c2415Smrg@c For copying conditions, see the file gcc.texi. 5760c2415Smrg 6760c2415Smrg@node User Experience Guidelines 7760c2415Smrg@chapter User Experience Guidelines 8760c2415Smrg@cindex user experience guidelines 9760c2415Smrg@cindex guidelines, user experience 10760c2415Smrg 11760c2415SmrgTo borrow a slogan from 12*0bfacb9bSmrg@uref{https://elm-lang.org/news/compilers-as-assistants, Elm}, 13760c2415Smrg 14760c2415Smrg@quotation 15760c2415Smrg@strong{Compilers should be assistants, not adversaries.} A compiler should 16760c2415Smrgnot just detect bugs, it should then help you understand why there is a bug. 17760c2415SmrgIt should not berate you in a robot voice, it should give you specific hints 18760c2415Smrgthat help you write better code. Ultimately, a compiler should make 19760c2415Smrgprogramming faster and more fun! 20760c2415Smrg@author Evan Czaplicki 21760c2415Smrg@end quotation 22760c2415Smrg 23760c2415SmrgThis chapter provides guidelines on how to implement diagnostics and 24760c2415Smrgcommand-line options in ways that we hope achieve the above ideal. 25760c2415Smrg 26760c2415Smrg@menu 27760c2415Smrg* Guidelines for Diagnostics:: How to implement diagnostics. 28760c2415Smrg* Guidelines for Options:: Guidelines for command-line options. 29760c2415Smrg@end menu 30760c2415Smrg 31760c2415Smrg 32760c2415Smrg@node Guidelines for Diagnostics 33760c2415Smrg@section Guidelines for Diagnostics 34760c2415Smrg@cindex guidelines for diagnostics 35760c2415Smrg@cindex diagnostics, guidelines for 36760c2415Smrg 37760c2415Smrg@subsection Talk in terms of the user's code 38760c2415Smrg 39760c2415SmrgDiagnostics should be worded in terms of the user's source code, and the 40760c2415Smrgsource language, rather than GCC's own implementation details. 41760c2415Smrg 42760c2415Smrg@subsection Diagnostics are actionable 43760c2415Smrg@cindex diagnostics, actionable 44760c2415Smrg 45760c2415SmrgA good diagnostic is @dfn{actionable}: it should assist the user in 46760c2415Smrgtaking action. 47760c2415Smrg 48760c2415SmrgConsider what an end user will want to do when encountering a diagnostic. 49760c2415Smrg 50760c2415SmrgGiven an error, an end user will think: ``How do I fix this?'' 51760c2415Smrg 52760c2415SmrgGiven a warning, an end user will think: 53760c2415Smrg 54760c2415Smrg@itemize @bullet 55760c2415Smrg@item 56760c2415Smrg``Is this a real problem?'' 57760c2415Smrg@item 58760c2415Smrg``Do I care?'' 59760c2415Smrg@item 60760c2415Smrgif they decide it's genuine: ``How do I fix this?'' 61760c2415Smrg@end itemize 62760c2415Smrg 63760c2415SmrgA good diagnostic provides pertinent information to allow the user to 64760c2415Smrgeasily answer the above questions. 65760c2415Smrg 66760c2415Smrg@subsection The user's attention is important 67760c2415Smrg 68760c2415SmrgA perfect compiler would issue a warning on every aspect of the user's 69760c2415Smrgsource code that ought to be fixed, and issue no other warnings. 70760c2415SmrgNaturally, this ideal is impossible to achieve. 71760c2415Smrg 72760c2415Smrg@cindex signal-to-noise ratio (metaphorical usage for diagnostics) 73760c2415Smrg@cindex diagnostics, false positive 74760c2415Smrg@cindex diagnostics, true positive 75760c2415Smrg@cindex false positive 76760c2415Smrg@cindex true positive 77760c2415Smrg 78760c2415SmrgWarnings should have a good @dfn{signal-to-noise ratio}: we should have few 79760c2415Smrg@dfn{false positives} (falsely issuing a warning when no warning is 80760c2415Smrgwarranted) and few @dfn{false negatives} (failing to issue a warning when 81760c2415Smrgone @emph{is} justified). 82760c2415Smrg 83760c2415SmrgNote that a false positive can mean, in practice, a warning that the 84760c2415Smrguser doesn't agree with. Ideally a diagnostic should contain enough 85760c2415Smrginformation to allow the user to make an informed choice about whether 86760c2415Smrgthey should care (and how to fix it), but a balance must be drawn against 87760c2415Smrgoverloading the user with irrelevant data. 88760c2415Smrg 89760c2415Smrg@subsection Precision of Wording 90760c2415Smrg 91760c2415SmrgProvide the user with details that allow them to identify what the 92760c2415Smrgproblem is. For example, the vaguely-worded message: 93760c2415Smrg 94760c2415Smrg@smallexample 95760c2415Smrgdemo.c:1:1: warning: 'noinline' attribute ignored [-Wattributes] 96760c2415Smrg 1 | int foo __attribute__((noinline)); 97760c2415Smrg | ^~~ 98760c2415Smrg@end smallexample 99760c2415Smrg 100760c2415Smrg@noindent 101760c2415Smrgdoesn't tell the user why the attribute was ignored, or what kind of 102760c2415Smrgentity the compiler thought the attribute was being applied to (the 103760c2415Smrgsource location for the diagnostic is also poor; 104760c2415Smrg@pxref{input_location_example,,discussion of @code{input_location}}). 105760c2415SmrgA better message would be: 106760c2415Smrg 107760c2415Smrg@smallexample 108760c2415Smrgdemo.c:1:24: warning: attribute 'noinline' on variable 'foo' was 109760c2415Smrg ignored [-Wattributes] 110760c2415Smrg 1 | int foo __attribute__((noinline)); 111760c2415Smrg | ~~~ ~~~~~~~~~~~~~~~^~~~~~~~~ 112760c2415Smrgdemo.c:1:24: note: attribute 'noinline' is only applicable to functions 113760c2415Smrg@end smallexample 114760c2415Smrg 115760c2415Smrg@noindent 116760c2415Smrgwhich spells out the missing information (and fixes the location 117760c2415Smrginformation, as discussed below). 118760c2415Smrg 119760c2415SmrgThe above example uses a note to avoid a combinatorial explosion of possible 120760c2415Smrgmessages. 121760c2415Smrg 122760c2415Smrg@subsection Try the diagnostic on real-world code 123760c2415Smrg 124760c2415SmrgIt's worth testing a new warning on many instances of real-world code, 125760c2415Smrgwritten by different people, and seeing what it complains about, and 126760c2415Smrgwhat it doesn't complain about. 127760c2415Smrg 128760c2415SmrgThis may suggest heuristics that silence common false positives. 129760c2415Smrg 130760c2415SmrgIt may also suggest ways to improve the precision of the message. 131760c2415Smrg 132760c2415Smrg@subsection Make mismatches clear 133760c2415Smrg 134760c2415SmrgMany diagnostics relate to a mismatch between two different places in the 135760c2415Smrguser's source code. Examples include: 136760c2415Smrg@itemize @bullet 137760c2415Smrg @item 138760c2415Smrg a type mismatch, where the type at a usage site does not match the type 139760c2415Smrg at a declaration 140760c2415Smrg 141760c2415Smrg @item 142760c2415Smrg the argument count at a call site does not match the parameter count 143760c2415Smrg at the declaration 144760c2415Smrg 145760c2415Smrg @item 146760c2415Smrg something is erroneously duplicated (e.g.@: an error, due to breaking a 147760c2415Smrg uniqueness requirement, or a warning, if it's suggestive of a bug) 148760c2415Smrg 149760c2415Smrg @item 150760c2415Smrg an ``opened'' syntactic construct (such as an open-parenthesis) is not 151760c2415Smrg closed 152760c2415Smrg 153760c2415Smrg @c TODO: more examples? 154760c2415Smrg@end itemize 155760c2415Smrg 156760c2415SmrgIn each case, the diagnostic should indicate @strong{both} pertinent 157760c2415Smrglocations (so that the user can easily see the problem and how to fix it). 158760c2415Smrg 159760c2415SmrgThe standard way to do this is with a note (via @code{inform}). For 160760c2415Smrgexample: 161760c2415Smrg 162760c2415Smrg@smallexample 163760c2415Smrg auto_diagnostic_group d; 164760c2415Smrg if (warning_at (loc, OPT_Wduplicated_cond, 165760c2415Smrg "duplicated %<if%> condition")) 166760c2415Smrg inform (EXPR_LOCATION (t), "previously used here"); 167760c2415Smrg@end smallexample 168760c2415Smrg 169760c2415Smrg@noindent 170760c2415Smrgwhich leads to: 171760c2415Smrg 172760c2415Smrg@smallexample 173760c2415Smrgdemo.c: In function 'test': 174760c2415Smrgdemo.c:5:17: warning: duplicated 'if' condition [-Wduplicated-cond] 175760c2415Smrg 5 | else if (flag > 3) 176760c2415Smrg | ~~~~~^~~ 177760c2415Smrgdemo.c:3:12: note: previously used here 178760c2415Smrg 3 | if (flag > 3) 179760c2415Smrg | ~~~~~^~~ 180760c2415Smrg@end smallexample 181760c2415Smrg 182760c2415Smrg@noindent 183760c2415SmrgThe @code{inform} call should be guarded by the return value from the 184760c2415Smrg@code{warning_at} call so that the note isn't emitted when the warning 185760c2415Smrgis suppressed. 186760c2415Smrg 187760c2415SmrgFor cases involving punctuation where the locations might be near 188760c2415Smrgeach other, they can be conditionally consolidated via 189760c2415Smrg@code{gcc_rich_location::add_location_if_nearby}: 190760c2415Smrg 191760c2415Smrg@smallexample 192760c2415Smrg auto_diagnostic_group d; 193760c2415Smrg gcc_rich_location richloc (primary_loc); 194760c2415Smrg bool added secondary = richloc.add_location_if_nearby (secondary_loc); 195760c2415Smrg error_at (&richloc, "main message"); 196760c2415Smrg if (!added secondary) 197760c2415Smrg inform (secondary_loc, "message for secondary"); 198760c2415Smrg@end smallexample 199760c2415Smrg 200760c2415Smrg@noindent 201760c2415SmrgThis will emit either one diagnostic with two locations: 202760c2415Smrg@smallexample 203760c2415Smrg demo.c:42:10: error: main message 204760c2415Smrg (foo) 205760c2415Smrg ~ ^ 206760c2415Smrg@end smallexample 207760c2415Smrg 208760c2415Smrg@noindent 209760c2415Smrgor two diagnostics: 210760c2415Smrg 211760c2415Smrg@smallexample 212760c2415Smrg demo.c:42:4: error: main message 213760c2415Smrg foo) 214760c2415Smrg ^ 215760c2415Smrg demo.c:40:2: note: message for secondary 216760c2415Smrg ( 217760c2415Smrg ^ 218760c2415Smrg@end smallexample 219760c2415Smrg 220760c2415Smrg@subsection Location Information 221760c2415Smrg@cindex diagnostics, locations 222760c2415Smrg@cindex location information 223760c2415Smrg@cindex source code, location information 224760c2415Smrg@cindex caret 225760c2415Smrg 226760c2415SmrgGCC's @code{location_t} type can support both ordinary locations, 227760c2415Smrgand locations relating to a macro expansion. 228760c2415Smrg 229760c2415SmrgAs of GCC 6, ordinary locations changed from supporting just a 230760c2415Smrgpoint in the user's source code to supporting three points: the 231760c2415Smrg@dfn{caret} location, plus a start and a finish: 232760c2415Smrg 233760c2415Smrg@smallexample 234760c2415Smrg a = foo && bar; 235760c2415Smrg ~~~~^~~~~~ 236760c2415Smrg | | | 237760c2415Smrg | | finish 238760c2415Smrg | caret 239760c2415Smrg start 240760c2415Smrg@end smallexample 241760c2415Smrg 242760c2415SmrgTokens coming out of libcpp have locations of the form @code{caret == start}, 243760c2415Smrgsuch as for @code{foo} here: 244760c2415Smrg 245760c2415Smrg@smallexample 246760c2415Smrg a = foo && bar; 247760c2415Smrg ^~~ 248760c2415Smrg | | 249760c2415Smrg | finish 250760c2415Smrg caret == start 251760c2415Smrg@end smallexample 252760c2415Smrg 253760c2415SmrgCompound expressions should be reported using the location of the 254760c2415Smrgexpression as a whole, rather than just of one token within it. 255760c2415Smrg 256760c2415SmrgFor example, in @code{-Wformat}, rather than underlining just the first 257760c2415Smrgtoken of a bad argument: 258760c2415Smrg 259760c2415Smrg@smallexample 260760c2415Smrg printf("hello %i %s", (long)0, "world"); 261760c2415Smrg ~^ ~ 262760c2415Smrg %li 263760c2415Smrg@end smallexample 264760c2415Smrg 265760c2415Smrg@noindent 266760c2415Smrgthe whole of the expression should be underlined, so that the user can 267760c2415Smrgeasily identify what is being referred to: 268760c2415Smrg 269760c2415Smrg@smallexample 270760c2415Smrg printf("hello %i %s", (long)0, "world"); 271760c2415Smrg ~^ ~~~~~~~ 272760c2415Smrg %li 273760c2415Smrg@end smallexample 274760c2415Smrg 275760c2415Smrg@c this was r251239 276760c2415Smrg 277760c2415SmrgAvoid using the @code{input_location} global, and the diagnostic functions 278760c2415Smrgthat implicitly use it---use @code{error_at} and @code{warning_at} rather 279760c2415Smrgthan @code{error} and @code{warning}, and provide the most appropriate 280760c2415Smrg@code{location_t} value available at that phase of the compilation. It's 281760c2415Smrgpossible to supply secondary @code{location_t} values via 282760c2415Smrg@code{rich_location}. 283760c2415Smrg 284760c2415Smrg@noindent 285760c2415Smrg@anchor{input_location_example} 286760c2415SmrgFor example, in the example of imprecise wording above, generating the 287760c2415Smrgdiagnostic using @code{warning}: 288760c2415Smrg 289760c2415Smrg@smallexample 290760c2415Smrg // BAD: implicitly uses @code{input_location} 291760c2415Smrg warning (OPT_Wattributes, "%qE attribute ignored", name); 292760c2415Smrg@end smallexample 293760c2415Smrg 294760c2415Smrg@noindent 295760c2415Smrgleads to: 296760c2415Smrg 297760c2415Smrg@smallexample 298760c2415Smrg// BAD: uses @code{input_location} 299760c2415Smrgdemo.c:1:1: warning: 'noinline' attribute ignored [-Wattributes] 300760c2415Smrg 1 | int foo __attribute__((noinline)); 301760c2415Smrg | ^~~ 302760c2415Smrg@end smallexample 303760c2415Smrg 304760c2415Smrg@noindent 305760c2415Smrgwhich thus happened to use the location of the @code{int} token, rather 306760c2415Smrgthan that of the attribute. Using @code{warning_at} with the location of 307760c2415Smrgthe attribute, providing the location of the declaration in question 308760c2415Smrgas a secondary location, and adding a note: 309760c2415Smrg 310760c2415Smrg@smallexample 311760c2415Smrg auto_diagnostic_group d; 312760c2415Smrg gcc_rich_location richloc (attrib_loc); 313760c2415Smrg richloc.add_range (decl_loc); 314760c2415Smrg if (warning_at (OPT_Wattributes, &richloc, 315760c2415Smrg "attribute %qE on variable %qE was ignored", name)) 316760c2415Smrg inform (attrib_loc, "attribute %qE is only applicable to functions"); 317760c2415Smrg@end smallexample 318760c2415Smrg 319760c2415Smrg@noindent 320760c2415Smrgwould lead to: 321760c2415Smrg 322760c2415Smrg@smallexample 323760c2415Smrg// OK: use location of attribute, with a secondary location 324760c2415Smrgdemo.c:1:24: warning: attribute 'noinline' on variable 'foo' was 325760c2415Smrg ignored [-Wattributes] 326760c2415Smrg 1 | int foo __attribute__((noinline)); 327760c2415Smrg | ~~~ ~~~~~~~~~~~~~~~^~~~~~~~~ 328760c2415Smrgdemo.c:1:24: note: attribute 'noinline' is only applicable to functions 329760c2415Smrg@end smallexample 330760c2415Smrg 331760c2415Smrg@c TODO labelling of ranges 332760c2415Smrg 333760c2415Smrg@subsection Coding Conventions 334760c2415Smrg 335760c2415SmrgSee the @uref{https://gcc.gnu.org/codingconventions.html#Diagnostics, 336760c2415Smrgdiagnostics section} of the GCC coding conventions. 337760c2415Smrg 338760c2415SmrgIn the C++ front end, when comparing two types in a message, use @samp{%H} 339760c2415Smrgand @samp{%I} rather than @samp{%T}, as this allows the diagnostics 340760c2415Smrgsubsystem to highlight differences between template-based types. 341760c2415SmrgFor example, rather than using @samp{%qT}: 342760c2415Smrg 343760c2415Smrg@smallexample 344760c2415Smrg // BAD: a pair of %qT used in C++ front end for type comparison 345760c2415Smrg error_at (loc, "could not convert %qE from %qT to %qT", expr, 346760c2415Smrg TREE_TYPE (expr), type); 347760c2415Smrg@end smallexample 348760c2415Smrg 349760c2415Smrg@noindent 350760c2415Smrgwhich could lead to: 351760c2415Smrg 352760c2415Smrg@smallexample 353760c2415Smrgerror: could not convert 'map<int, double>()' from 'map<int,double>' 354760c2415Smrg to 'map<int,int>' 355760c2415Smrg@end smallexample 356760c2415Smrg 357760c2415Smrg@noindent 358760c2415Smrgusing @samp{%H} and @samp{%I} (via @samp{%qH} and @samp{%qI}): 359760c2415Smrg 360760c2415Smrg@smallexample 361760c2415Smrg // OK: compare types in C++ front end via %qH and %qI 362760c2415Smrg error_at (loc, "could not convert %qE from %qH to %qI", expr, 363760c2415Smrg TREE_TYPE (expr), type); 364760c2415Smrg@end smallexample 365760c2415Smrg 366760c2415Smrg@noindent 367760c2415Smrgallows the above output to be simplified to: 368760c2415Smrg 369760c2415Smrg@smallexample 370760c2415Smrgerror: could not convert 'map<int, double>()' from 'map<[...],double>' 371760c2415Smrg to 'map<[...],int>' 372760c2415Smrg@end smallexample 373760c2415Smrg 374760c2415Smrg@noindent 375760c2415Smrgwhere the @code{double} and @code{int} are colorized to highlight them. 376760c2415Smrg 377760c2415Smrg@c %H and %I were added in r248698. 378760c2415Smrg 379760c2415Smrg@subsection Group logically-related diagnostics 380760c2415Smrg 381760c2415SmrgUse @code{auto_diagnostic_group} when issuing multiple related 382760c2415Smrgdiagnostics (seen in various examples on this page). This informs the 383760c2415Smrgdiagnostic subsystem that all diagnostics issued within the lifetime 384760c2415Smrgof the @code{auto_diagnostic_group} are related. For example, 385760c2415Smrg@option{-fdiagnostics-format=json} will treat the first diagnostic 386760c2415Smrgemitted within the group as a top-level diagnostic, and all subsequent 387760c2415Smrgdiagnostics within the group as its children. 388760c2415Smrg 389760c2415Smrg@subsection Quoting 390760c2415SmrgText should be quoted by either using the @samp{q} modifier in a directive 391760c2415Smrgsuch as @samp{%qE}, or by enclosing the quoted text in a pair of @samp{%<} 392760c2415Smrgand @samp{%>} directives, and never by using explicit quote characters. 393760c2415SmrgThe directives handle the appropriate quote characters for each language 394760c2415Smrgand apply the correct color or highlighting. 395760c2415Smrg 396760c2415SmrgThe following elements should be quoted in GCC diagnostics: 397760c2415Smrg 398760c2415Smrg@itemize @bullet 399760c2415Smrg@item 400760c2415SmrgLanguage keywords. 401760c2415Smrg@item 402760c2415SmrgTokens. 403760c2415Smrg@item 404760c2415SmrgBoolean, numerical, character, and string constants that appear in the 405760c2415Smrgsource code. 406760c2415Smrg@item 407760c2415SmrgIdentifiers, including function, macro, type, and variable names. 408760c2415Smrg@end itemize 409760c2415Smrg 410760c2415SmrgOther elements such as numbers that do not refer to numeric constants that 411760c2415Smrgappear in the source code should not be quoted. For example, in the message: 412760c2415Smrg 413760c2415Smrg@smallexample 414760c2415Smrgargument %d of %qE must be a pointer type 415760c2415Smrg@end smallexample 416760c2415Smrg 417760c2415Smrg@noindent 418760c2415Smrgsince the argument number does not refer to a numerical constant in the 419760c2415Smrgsource code it should not be quoted. 420760c2415Smrg 421760c2415Smrg@subsection Spelling and Terminology 422760c2415Smrg 423760c2415SmrgSee the @uref{https://gcc.gnu.org/codingconventions.html#Spelling 424760c2415SmrgSpelling, terminology and markup} section of the GCC coding conventions. 425760c2415Smrg 426760c2415Smrg@subsection Fix-it hints 427760c2415Smrg@cindex fix-it hints 428760c2415Smrg@cindex diagnostics guidelines, fix-it hints 429760c2415Smrg 430760c2415SmrgGCC's diagnostic subsystem can emit @dfn{fix-it hints}: small suggested 431760c2415Smrgedits to the user's source code. 432760c2415Smrg 433760c2415SmrgThey are printed by default underneath the code in question. They 434760c2415Smrgcan also be viewed via @option{-fdiagnostics-generate-patch} and 435760c2415Smrg@option{-fdiagnostics-parseable-fixits}. With the latter, an IDE 436760c2415Smrgought to be able to offer to automatically apply the suggested fix. 437760c2415Smrg 438760c2415SmrgFix-it hints contain code fragments, and thus they should not be marked 439760c2415Smrgfor translation. 440760c2415Smrg 441760c2415SmrgFix-it hints can be added to a diagnostic by using a @code{rich_location} 442760c2415Smrgrather than a @code{location_t} - the fix-it hints are added to the 443760c2415Smrg@code{rich_location} using one of the various @code{add_fixit} member 444760c2415Smrgfunctions of @code{rich_location}. They are documented with 445760c2415Smrg@code{rich_location} in @file{libcpp/line-map.h}. 446760c2415SmrgIt's easiest to use the @code{gcc_rich_location} subclass of 447760c2415Smrg@code{rich_location} found in @file{gcc-rich-location.h}, as this 448760c2415Smrgimplicitly supplies the @code{line_table} variable. 449760c2415Smrg 450760c2415SmrgFor example: 451760c2415Smrg 452760c2415Smrg@smallexample 453760c2415Smrg if (const char *suggestion = hint.suggestion ()) 454760c2415Smrg @{ 455760c2415Smrg gcc_rich_location richloc (location); 456760c2415Smrg richloc.add_fixit_replace (suggestion); 457760c2415Smrg error_at (&richloc, 458760c2415Smrg "%qE does not name a type; did you mean %qs?", 459760c2415Smrg id, suggestion); 460760c2415Smrg @} 461760c2415Smrg@end smallexample 462760c2415Smrg 463760c2415Smrg@noindent 464760c2415Smrgwhich can lead to: 465760c2415Smrg 466760c2415Smrg@smallexample 467760c2415Smrgspellcheck-typenames.C:73:1: error: 'singed' does not name a type; did 468760c2415Smrg you mean 'signed'? 469760c2415Smrg 73 | singed char ch; 470760c2415Smrg | ^~~~~~ 471760c2415Smrg | signed 472760c2415Smrg@end smallexample 473760c2415Smrg 474760c2415SmrgNon-trivial edits can be built up by adding multiple fix-it hints to one 475760c2415Smrg@code{rich_location}. It's best to express the edits in terms of the 476760c2415Smrglocations of individual tokens. Various handy functions for adding 477760c2415Smrgfix-it hints for idiomatic C and C++ can be seen in 478760c2415Smrg@file{gcc-rich-location.h}. 479760c2415Smrg 480760c2415Smrg@subsubsection Fix-it hints should work 481760c2415Smrg 482760c2415SmrgWhen implementing a fix-it hint, please verify that the suggested edit 483760c2415Smrgleads to fixed, compilable code. (Unfortunately, this currently must be 484760c2415Smrgdone by hand using @option{-fdiagnostics-generate-patch}. It would be 485760c2415Smrggood to have an automated way of verifying that fix-it hints actually fix 486760c2415Smrgthe code). 487760c2415Smrg 488760c2415SmrgFor example, a ``gotcha'' here is to forget to add a space when adding a 489760c2415Smrgmissing reserved word. Consider a C++ fix-it hint that adds 490760c2415Smrg@code{typename} in front of a template declaration. A naive way to 491760c2415Smrgimplement this might be: 492760c2415Smrg 493760c2415Smrg@smallexample 494760c2415Smrggcc_rich_location richloc (loc); 495760c2415Smrg// BAD: insertion is missing a trailing space 496760c2415Smrgrichloc.add_fixit_insert_before ("typename"); 497760c2415Smrgerror_at (&richloc, "need %<typename%> before %<%T::%E%> because " 498760c2415Smrg "%qT is a dependent scope", 499760c2415Smrg parser->scope, id, parser->scope); 500760c2415Smrg@end smallexample 501760c2415Smrg 502760c2415Smrg@noindent 503760c2415SmrgWhen applied to the code, this might lead to: 504760c2415Smrg 505760c2415Smrg@smallexample 506760c2415SmrgT::type x; 507760c2415Smrg@end smallexample 508760c2415Smrg 509760c2415Smrg@noindent 510760c2415Smrgbeing ``corrected'' to: 511760c2415Smrg 512760c2415Smrg@smallexample 513760c2415SmrgtypenameT::type x; 514760c2415Smrg@end smallexample 515760c2415Smrg 516760c2415Smrg@noindent 517760c2415SmrgIn this case, the correct thing to do is to add a trailing space after 518760c2415Smrg@code{typename}: 519760c2415Smrg 520760c2415Smrg@smallexample 521760c2415Smrggcc_rich_location richloc (loc); 522760c2415Smrg// OK: note that here we have a trailing space 523760c2415Smrgrichloc.add_fixit_insert_before ("typename "); 524760c2415Smrgerror_at (&richloc, "need %<typename%> before %<%T::%E%> because " 525760c2415Smrg "%qT is a dependent scope", 526760c2415Smrg parser->scope, id, parser->scope); 527760c2415Smrg@end smallexample 528760c2415Smrg 529760c2415Smrg@noindent 530760c2415Smrgleading to this corrected code: 531760c2415Smrg 532760c2415Smrg@smallexample 533760c2415Smrgtypename T::type x; 534760c2415Smrg@end smallexample 535760c2415Smrg 536760c2415Smrg@subsubsection Express deletion in terms of deletion, not replacement 537760c2415Smrg 538760c2415SmrgIt's best to express deletion suggestions in terms of deletion fix-it 539760c2415Smrghints, rather than replacement fix-it hints. For example, consider this: 540760c2415Smrg 541760c2415Smrg@smallexample 542760c2415Smrg auto_diagnostic_group d; 543760c2415Smrg gcc_rich_location richloc (location_of (retval)); 544760c2415Smrg tree name = DECL_NAME (arg); 545760c2415Smrg richloc.add_fixit_replace (IDENTIFIER_POINTER (name)); 546760c2415Smrg warning_at (&richloc, OPT_Wredundant_move, 547760c2415Smrg "redundant move in return statement"); 548760c2415Smrg@end smallexample 549760c2415Smrg 550760c2415Smrg@noindent 551760c2415Smrgwhich is intended to e.g.@: replace a @code{std::move} with the underlying 552760c2415Smrgvalue: 553760c2415Smrg 554760c2415Smrg@smallexample 555760c2415Smrg return std::move (retval); 556760c2415Smrg ~~~~~~~~~~^~~~~~~~ 557760c2415Smrg retval 558760c2415Smrg@end smallexample 559760c2415Smrg 560760c2415Smrg@noindent 561760c2415Smrgwhere the change has been expressed as replacement, replacing 562760c2415Smrgwith the name of the declaration. 563760c2415SmrgThis works for simple cases, but consider this case: 564760c2415Smrg 565760c2415Smrg@smallexample 566760c2415Smrg#ifdef SOME_CONFIG_FLAG 567760c2415Smrg# define CONFIGURY_GLOBAL global_a 568760c2415Smrg#else 569760c2415Smrg# define CONFIGURY_GLOBAL global_b 570760c2415Smrg#endif 571760c2415Smrg 572760c2415Smrgint fn () 573760c2415Smrg@{ 574760c2415Smrg return std::move (CONFIGURY_GLOBAL /* some comment */); 575760c2415Smrg@} 576760c2415Smrg@end smallexample 577760c2415Smrg 578760c2415Smrg@noindent 579760c2415SmrgThe above implementation erroneously strips out the macro and the 580760c2415Smrgcomment in the fix-it hint: 581760c2415Smrg 582760c2415Smrg@smallexample 583760c2415Smrg return std::move (CONFIGURY_GLOBAL /* some comment */); 584760c2415Smrg ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 585760c2415Smrg global_a 586760c2415Smrg@end smallexample 587760c2415Smrg 588760c2415Smrg@noindent 589760c2415Smrgand thus this resulting code: 590760c2415Smrg 591760c2415Smrg@smallexample 592760c2415Smrg return global_a; 593760c2415Smrg@end smallexample 594760c2415Smrg 595760c2415Smrg@noindent 596760c2415SmrgIt's better to do deletions in terms of deletions; deleting the 597760c2415Smrg@code{std::move (} and the trailing close-paren, leading to 598760c2415Smrgthis: 599760c2415Smrg 600760c2415Smrg@smallexample 601760c2415Smrg return std::move (CONFIGURY_GLOBAL /* some comment */); 602760c2415Smrg ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 603760c2415Smrg CONFIGURY_GLOBAL /* some comment */ 604760c2415Smrg@end smallexample 605760c2415Smrg 606760c2415Smrg@noindent 607760c2415Smrgand thus this result: 608760c2415Smrg 609760c2415Smrg@smallexample 610760c2415Smrg return CONFIGURY_GLOBAL /* some comment */; 611760c2415Smrg@end smallexample 612760c2415Smrg 613760c2415Smrg@noindent 614760c2415SmrgUnfortunately, the pertinent @code{location_t} values are not always 615760c2415Smrgavailable. 616760c2415Smrg 617760c2415Smrg@c the above was https://gcc.gnu.org/ml/gcc-patches/2018-08/msg01474.html 618760c2415Smrg 619760c2415Smrg@subsubsection Multiple suggestions 620760c2415Smrg 621760c2415SmrgIn the rare cases where you need to suggest more than one mutually 622760c2415Smrgexclusive solution to a problem, this can be done by emitting 623760c2415Smrgmultiple notes and calling 624760c2415Smrg@code{rich_location::fixits_cannot_be_auto_applied} on each note's 625760c2415Smrg@code{rich_location}. If this is called, then the fix-it hints in 626760c2415Smrgthe @code{rich_location} will be printed, but will not be added to 627760c2415Smrggenerated patches. 628760c2415Smrg 629760c2415Smrg 630760c2415Smrg@node Guidelines for Options 631760c2415Smrg@section Guidelines for Options 632760c2415Smrg@cindex command-line options, guidelines for 633760c2415Smrg@cindex options, guidelines for 634760c2415Smrg@cindex guidelines for options 635760c2415Smrg 636760c2415Smrg@c TODO 637