From ad527d801855d7992e25b1548628566eefcf69e9 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sat, 31 Aug 2019 18:09:47 -0400 Subject: [PATCH] Add source location to TRAIT_EXPR. Since TRAIT_EXPR is exceptional, maybe_wrap_with_location won't wrap it, so we need to put its location in the TRAIT_EXPR node itself. * cp-tree.h (TRAIT_EXPR_LOCATION): New. (struct tree_trait_expr): Add locus field. * parser.c (cp_parser_trait_expr): Pass trait_loc down. * pt.c (tsubst_copy_and_build) [TRAIT_EXPR]: Likewise. * semantics.c (finish_trait_expr): Add location parm. * tree.c (cp_expr_location): Handle TRAIT_EXPR. From-SVN: r275260 --- gcc/cp/ChangeLog | 10 ++++++++++ gcc/cp/cp-tree.h | 6 +++++- gcc/cp/parser.c | 2 +- gcc/cp/pt.c | 3 ++- gcc/cp/semantics.c | 8 +++++--- gcc/cp/tree.c | 2 ++ gcc/testsuite/g++.dg/ext/is_class_error3.C | 2 ++ 7 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/is_class_error3.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 37de3d91870..9725dda2082 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2019-08-30 Jason Merrill + + Add source location to TRAIT_EXPR. + * cp-tree.h (TRAIT_EXPR_LOCATION): New. + (struct tree_trait_expr): Add locus field. + * parser.c (cp_parser_trait_expr): Pass trait_loc down. + * pt.c (tsubst_copy_and_build) [TRAIT_EXPR]: Likewise. + * semantics.c (finish_trait_expr): Add location parm. + * tree.c (cp_expr_location): Handle TRAIT_EXPR. + 2019-08-29 Paolo Carlini * decl.c (check_var_type): Add location_t parameter and use it. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3c69e54c885..12eb39a0a4c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1295,10 +1295,14 @@ enum cp_trait_kind #define TRAIT_EXPR_KIND(NODE) \ (((struct tree_trait_expr *)TRAIT_EXPR_CHECK (NODE))->kind) +#define TRAIT_EXPR_LOCATION(NODE) \ + (((struct tree_trait_expr *)TRAIT_EXPR_CHECK (NODE))->locus) + struct GTY (()) tree_trait_expr { struct tree_common common; tree type1; tree type2; + location_t locus; enum cp_trait_kind kind; }; @@ -7174,7 +7178,7 @@ extern tree baselink_for_fns (tree); extern void finish_static_assert (tree, tree, location_t, bool); extern tree finish_decltype_type (tree, bool, tsubst_flags_t); -extern tree finish_trait_expr (enum cp_trait_kind, tree, tree); +extern tree finish_trait_expr (location_t, enum cp_trait_kind, tree, tree); extern tree build_lambda_expr (void); extern tree build_lambda_object (tree); extern tree begin_lambda_type (tree); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 93cdaddf52d..baa60b8834e 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -10396,7 +10396,7 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword) case CPTK_DIRECT_BASES: return cp_expr (finish_bases (type1, true), trait_loc); default: - return cp_expr (finish_trait_expr (kind, type1, type2), trait_loc); + return finish_trait_expr (trait_loc, kind, type1, type2); } } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 13d3db9a0f7..187f9d857bc 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -19536,7 +19536,8 @@ tsubst_copy_and_build (tree t, else if (type2) type2 = tsubst (type2, args, complain, in_decl); - RETURN (finish_trait_expr (TRAIT_EXPR_KIND (t), type1, type2)); + RETURN (finish_trait_expr (TRAIT_EXPR_LOCATION (t), + TRAIT_EXPR_KIND (t), type1, type2)); } case STMT_EXPR: diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index b61d86f94b9..56f70a0a589 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -9921,7 +9921,7 @@ check_trait_type (tree type) /* Process a trait expression. */ tree -finish_trait_expr (cp_trait_kind kind, tree type1, tree type2) +finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) { if (type1 == error_mark_node || type2 == error_mark_node) @@ -9934,6 +9934,7 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2) TRAIT_EXPR_TYPE1 (trait_expr) = type1; TRAIT_EXPR_TYPE2 (trait_expr) = type2; TRAIT_EXPR_KIND (trait_expr) = kind; + TRAIT_EXPR_LOCATION (trait_expr) = loc; return trait_expr; } @@ -9991,8 +9992,9 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2) gcc_unreachable (); } - return (trait_expr_value (kind, type1, type2) - ? boolean_true_node : boolean_false_node); +tree val = (trait_expr_value (kind, type1, type2) + ? boolean_true_node : boolean_false_node); + return maybe_wrap_with_location (val, loc); } /* Do-nothing variants of functions to handle pragma FLOAT_CONST_DECIMAL64, diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 17a4df380c1..7f71891000d 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -5500,6 +5500,8 @@ cp_expr_location (const_tree t_) return LAMBDA_EXPR_LOCATION (t); case STATIC_ASSERT: return STATIC_ASSERT_SOURCE_LOCATION (t); + case TRAIT_EXPR: + return TRAIT_EXPR_LOCATION (t); default: return EXPR_LOCATION (t); } diff --git a/gcc/testsuite/g++.dg/ext/is_class_error3.C b/gcc/testsuite/g++.dg/ext/is_class_error3.C new file mode 100644 index 00000000000..a3c16a4007f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_class_error3.C @@ -0,0 +1,2 @@ +struct A {}; +void *p = __is_class (A); // { dg-error "11:cannot convert" } -- 2.30.2