Hi Martin,

Asher Gordon <asd...@posteo.net> writes:

> Martin Sebor <mse...@gmail.com> writes:
>
>> Unfortunately, attributes don't have locations (yet).
>
> Hmm, well maybe I could implement that. I'm not very familiar with the
> GCC source (this is my first patch), but I'll see if I can figure it
> out. It would probably be useful for other warnings/errors too.

Well, I've been trying to implement source locations for
IDENTIFIER_NODEs. But I ran into some very strange problems. If I add a
'location_t' for 'struct tree_identifier' like this:
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 8c5a2e3c404..b3c46d3c0d3 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -1423,6 +1423,7 @@ struct GTY(()) tree_poly_int_cst {
 struct GTY(()) tree_identifier {
   struct tree_common common;
   struct ht_identifier id;
+  location_t locus;
 };
 
 struct GTY(()) tree_list {
everything works fine. However, if I then try to use the 'location_t' I
just added, like this:
diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c
index b1cef2345f4..d2d86c5f78a 100644
--- a/gcc/c-family/c-lex.c
+++ b/gcc/c-family/c-lex.c
@@ -465,6 +465,7 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
 
     case CPP_NAME:
       *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node.node));
+      IDENTIFIER_SOURCE_LOCATION (*value) = *loc;
       break;
 
     case CPP_NUMBER:
diff --git a/gcc/tree.h b/gcc/tree.h
index a74872f5f3e..1e5a4fba0ed 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1069,6 +1069,16 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
 #define IDENTIFIER_HASH_VALUE(NODE) \
   (IDENTIFIER_NODE_CHECK (NODE)->identifier.id.hash_value)
 
+/* The source location in which the identifier appears.  */
+#define IDENTIFIER_SOURCE_LOCATION(NODE) \
+  (IDENTIFIER_NODE_CHECK (NODE)->identifier.locus)
+#define IDENTIFIER_SOURCE_FILE(NODE)\
+  LOCATION_FILE (IDENTIFIER_SOURCE_LOCATION (NODE))
+#define IDENTIFIER_SOURCE_LINE(NODE)\
+  LOCATION_LINE (IDENTIFIER_SOURCE_LOCATION (NODE))
+#define IDENTIFIER_SOURCE_COLUMN(NODE)\
+  LOCATION_COLUMN (IDENTIFIER_SOURCE_LOCATION (NODE))
+
 /* Translate a hash table identifier pointer to a tree_identifier
    pointer, and vice versa.  */
 
then lots of ICEs occur. Or, if I don't use IDENTIFIER_SOURCE_LOCATION,
but add 'locus' before 'id' instead of after it, like this:
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 8c5a2e3c404..b3c46d3c0d3 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -1423,6 +1423,7 @@ struct GTY(()) tree_poly_int_cst {
 struct GTY(()) tree_identifier {
   struct tree_common common;
+  location_t locus;
   struct ht_identifier id;
 };
 
 struct GTY(()) tree_list {
then, again, lots of ICEs occur.

My best guess for why the ICEs occur, is that perhaps there is a
'struct' with a similar structure to 'struct tree_identifier', and
pointers to these 'struct's are being casted to each other. Something
like this, sort of:
/* This is analogous to the unknown structure, to and from which
   'struct tree_identifier' is being casted. */
struct foo {
  int i;
  float f;
};

/* This is analogous to the modified 'struct tree_identifier' with the
   'location_t' added at the end. */
struct end {
  int i;
  float f;
  const char *s; /* Analogous to 'locus' in 'struct tree_identifier' */
};

/* This is analogous to the modified 'struct tree_identifier' with the
   'location_t' added in the middle. */
struct middle {
  int i;
  const char *s; /* Analogous to 'locus' in 'struct tree_identifier' */
  float f;
};

int
main (void)
{
  struct foo foo, *foo_p = &foo;
  struct end *end_p;
  struct middle *middle_p;

  /* This works, as long as 's' is not used. */
  end_p = (struct end *) foo_p;
  /* But as soon as 's' is used, it invokes UB. This is analogous to
     the IDENTIFIER_SOURCE_LOCATION in c_lex_with_flags. */
  end_p->s = "hello";

  /* This works, as long as neither 'f' (analogous to 'id') nor 's' is
     used. */
  middle_p = (struct middle *) foo_p;
  /* But, doubtless, 'f' ('id') will be used somewhere... */
  middle_p->f = 42.0;

  return 0; /* if we're lucky... */
}
Do you think something like that is possible? And if so, where might it
occur? Or maybe the wrong member of 'union tree_node' is being used
somewhere? But that seems unlikely, since I configured with
--enable-checking...

Thanks,
Asher

-- 
One picture is worth 128K words.
                               --------
I prefer to send and receive mail encrypted. Please send me your
public key, and if you do not have my public key, please let me
know. Thanks.

GPG fingerprint: 38F3 975C D173 4037 B397  8095 D4C9 C4FC 5460 8E68

Attachment: signature.asc
Description: PGP signature

Reply via email to