On Mon, 2018-08-27 at 09:14 +0200, Jakub Jelinek wrote: > Hi! > > This patch improves location of the cxx_readonly_error diagnostics by > letting caller's pass the preferred location for it rather than > always using > input_location. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Looks good to me (with my "diagnostic messages" hat on) Dave > 2018-08-27 Jakub Jelinek <ja...@redhat.com> > > PR c++/86993 > * cp-tree.h (cxx_readonly_error): Add location_t argument. > * typeck2.c (cxx_readonly_error): Add LOC argument, pass it to > ERROR_FOR_ASSIGNMENT macro and readonly_error. Add LOC > argument > to ERROR_FOR_ASSIGNMENT macro, use error_at instead of error > and > pass LOC to it. Formatting fixes. > * typeck.c (cp_build_unary_op): Pass location to > cxx_readonly_error. > (cp_build_modify_expr): Pass loc to cxx_readonly_error. > * semantics.c (finish_asm_stmt): Pass input_location to > cxx_readonly_error. > > * g++.dg/diagnostic/pr86993.C: New test. > > --- gcc/cp/cp-tree.h.jj 2018-08-24 08:55:23.000000000 +0200 > +++ gcc/cp/cp-tree.h 2018-08-24 09:10:42.400933523 +0200 > @@ -7388,7 +7388,8 @@ cxx_incomplete_type_error (const_tree va > extern void cxx_incomplete_type_inform (const_tree); > extern tree error_not_base_type (tree, tree); > extern tree binfo_or_else (tree, tree); > -extern void cxx_readonly_error (tree, enum > lvalue_use); > +extern void cxx_readonly_error (location_t, > tree, > + enum lvalue_use); > extern void complete_type_check_abstract (tree); > extern int abstract_virtuals_error (tree, tree); > extern int abstract_virtuals_error (abstract_class_us > e, tree); > --- gcc/cp/typeck2.c.jj 2018-08-24 08:55:23.000000000 +0200 > +++ gcc/cp/typeck2.c 2018-08-24 09:17:11.495798270 +0200 > @@ -67,28 +67,28 @@ binfo_or_else (tree base, tree type) > value may not be changed thereafter. */ > > void > -cxx_readonly_error (tree arg, enum lvalue_use errstring) > +cxx_readonly_error (location_t loc, tree arg, enum lvalue_use > errstring) > { > > /* This macro is used to emit diagnostics to ensure that all format > strings are complete sentences, visible to gettext and checked at > compile time. */ > > -#define ERROR_FOR_ASSIGNMENT(AS, ASM, IN, DE, > ARG) \ > +#define ERROR_FOR_ASSIGNMENT(LOC, AS, ASM, IN, DE, ARG) > \ > do > { \ > switch > (errstring) \ > { > \ > case lv_assign: > \ > - error(AS, > ARG); \ > + error_at (LOC, AS, ARG); > \ > break; > \ > case lv_asm: > \ > - error(ASM, > ARG); \ > + error_at (LOC, ASM, ARG); > \ > break; > \ > case lv_increment: > \ > - error (IN, > ARG); \ > + error_at (LOC, IN, ARG); > \ > break; > \ > - case > lv_decrement: \ > - error (DE, > ARG); \ > + case > lv_decrement: \ > + error_at (LOC, DE, ARG); > \ > break; > \ > default: > \ > gcc_unreachable > (); \ > @@ -101,32 +101,25 @@ cxx_readonly_error (tree arg, enum lvalu > && DECL_LANG_SPECIFIC (arg) > && DECL_IN_AGGR_P (arg) > && !TREE_STATIC (arg)) > - ERROR_FOR_ASSIGNMENT (G_("assignment of " > - "constant field %qD"), > - G_("constant field %qD " > - "used as %<asm%> output"), > - G_("increment of " > - "constant field %qD"), > - G_("decrement of " > - "constant field %qD"), > + ERROR_FOR_ASSIGNMENT (loc, > + G_("assignment of constant field %qD"), > + G_("constant field %qD used as %<asm%> > output"), > + G_("increment of constant field %qD"), > + G_("decrement of constant field %qD"), > arg); > else if (INDIRECT_REF_P (arg) > && TYPE_REF_P (TREE_TYPE (TREE_OPERAND (arg, 0))) > && (VAR_P (TREE_OPERAND (arg, 0)) > || TREE_CODE (TREE_OPERAND (arg, 0)) == PARM_DECL)) > - ERROR_FOR_ASSIGNMENT (G_("assignment of " > - "read-only reference %qD"), > - G_("read-only reference %qD " > - "used as %<asm%> output"), > - G_("increment of " > - "read-only reference %qD"), > - G_("decrement of " > - "read-only reference %qD"), > - TREE_OPERAND (arg, 0)); > + ERROR_FOR_ASSIGNMENT (loc, > + G_("assignment of read-only reference > %qD"), > + G_("read-only reference %qD used as > %<asm%> output"), > + G_("increment of read-only reference > %qD"), > + G_("decrement of read-only reference > %qD"), > + TREE_OPERAND (arg, 0)); > else > - readonly_error (input_location, arg, errstring); > + readonly_error (loc, arg, errstring); > } > - > > /* Structure that holds information about declarations whose type > was > incomplete and we could not check whether it was abstract or > not. */ > --- gcc/cp/typeck.c.jj 2018-08-24 08:55:23.000000000 +0200 > +++ gcc/cp/typeck.c 2018-08-24 09:22:47.579231878 +0200 > @@ -6228,9 +6228,10 @@ cp_build_unary_op (enum tree_code code, > || TREE_READONLY (arg)) > { > if (complain & tf_error) > - cxx_readonly_error (arg, ((code == PREINCREMENT_EXPR > - || code == POSTINCREMENT_EXPR) > - ? lv_increment : > lv_decrement)); > + cxx_readonly_error (location, arg, > + ((code == PREINCREMENT_EXPR > + || code == POSTINCREMENT_EXPR) > + ? lv_increment : lv_decrement)); > else > return error_mark_node; > } > @@ -8159,7 +8160,7 @@ cp_build_modify_expr (location_t loc, tr > && C_TYPE_FIELDS_READONLY (lhstype)))) > { > if (complain & tf_error) > - cxx_readonly_error (lhs, lv_assign); > + cxx_readonly_error (loc, lhs, lv_assign); > return error_mark_node; > } > > --- gcc/cp/semantics.c.jj 2018-08-08 10:27:23.000000000 +0200 > +++ gcc/cp/semantics.c 2018-08-24 09:23:56.122504523 +0200 > @@ -1532,7 +1532,7 @@ finish_asm_stmt (int volatile_p, tree st > effectively const. */ > || (CLASS_TYPE_P (TREE_TYPE (operand)) > && C_TYPE_FIELDS_READONLY (TREE_TYPE > (operand))))) > - cxx_readonly_error (operand, lv_asm); > + cxx_readonly_error (input_location, operand, lv_asm); > > tree *op = &operand; > while (TREE_CODE (*op) == COMPOUND_EXPR) > --- gcc/testsuite/g++.dg/diagnostic/pr86993.C.jj 2018-08-24 > 09:34:35.065756093 +0200 > +++ gcc/testsuite/g++.dg/diagnostic/pr86993.C 2018-08-24 > 09:35:22.489262138 +0200 > @@ -0,0 +1,13 @@ > +// PR c++/86993 > +// { dg-options "-fdiagnostics-show-caret" } > + > +int > +main () > +{ > + const int i = 5; // { dg-error "assignment of read-only > variable 'i'" "" { target *-*-* } .+1 } > + i = 5 + 6; > +/* { dg-begin-multiline-output "" } > + i = 5 + 6; > + ~~^~~~~~~ > + { dg-end-multiline-output "" } */ > +} > > Jakub