Add source location to TRAIT_EXPR.
authorJason Merrill <jason@redhat.com>
Sat, 31 Aug 2019 22:09:47 +0000 (18:09 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 31 Aug 2019 22:09:47 +0000 (18:09 -0400)
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
gcc/cp/cp-tree.h
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/cp/tree.c
gcc/testsuite/g++.dg/ext/is_class_error3.C [new file with mode: 0644]

index 37de3d918709b2577d00d8b374b6f02c1fe471a7..9725dda2082af88962f0a7da9971649a7a0836ab 100644 (file)
@@ -1,3 +1,13 @@
+2019-08-30  Jason Merrill  <jason@redhat.com>
+
+       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  <paolo.carlini@oracle.com>
 
        * decl.c (check_var_type): Add location_t parameter and use it.
index 3c69e54c8858a2bdeb84ef9e0ca549a60072f0c1..12eb39a0a4c76a542a688fcf6031e285c5222713 100644 (file)
@@ -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);
index 93cdaddf52d51e86ca194e120fe77e258207ddc0..baa60b8834ecc119bcea9e84f8062f09c47d19d3 100644 (file)
@@ -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);
     }
 }
 
index 13d3db9a0f7bad9bd00f45b289a88bc240839271..187f9d857bc09254cb547e9848f326035bbb7020 100644 (file)
@@ -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:
index b61d86f94b94434bb7ecabd57f8f403ee6a6f4a9..56f70a0a58929b52cff9940cf346d4baac977aee 100644 (file)
@@ -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,
index 17a4df380c1178821133e87a8f023a77b7538341..7f71891000d8281079152739f4a07fc0f9cf6ae4 100644 (file)
@@ -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 (file)
index 0000000..a3c16a4
--- /dev/null
@@ -0,0 +1,2 @@
+struct A {};
+void *p = __is_class (A);      // { dg-error "11:cannot convert" }