Jason Merrill <ja...@redhat.com> writes:

> On 05/15/2012 07:18 AM, Dodji Seketeli wrote:
>> +paste_tokens (cpp_reader *pfile, source_location lhs_location,
>
> If in the long run we want the location passed in to be the ##
> location, let's drop the "lhs" from the parameter name.

Dropped.

>
>> -      const cpp_token *result = cpp_get_token (pfile);
>> +      const cpp_token *result = cpp_get_token_with_location (pfile, NULL);
>
> I find the difference between these two functions confusing, since you
> aren't passing in a pointer for the location to go into.  I see that
> cpp_get_token_with_location sets pfile->set_invocation_location, which
> is documented to mean
>
>>   /* When expanding a macro at top-level, this is the location of the
>>      macro invocation.  */
>>   source_location invocation_location;
>>
>>   /* True if this call to cpp_get_token should consider setting
>>      invocation_location.  */
>>   bool set_invocation_location;
>
> But presumably get_token_no_padding isn't only called when we're
> starting to expand a top-level macro.  And as far as I can tell the
> value of invocation_location is only used when we aren't tracking
> virtual locations anyway.  So why does the change above fix the
> testcase?

It fixes the test case gcc.dg/cpp/paste12.c because that test case runs
with -ftrack-macro-expansion turned off.  Otherwise, you are right that
the issue exists only when we aren't tracking virtual locations.

FWIW, here is the updated patch I have.


libcpp/

        PR preprocessor/53229
        * directives.c (get_token_no_padding): Allow use of virtual
        locations in diagnostics emitted by the processor when handling
        directives.  Update comments.  This fixes gcc.dg/cpp/paste12.c.
        * macro.c (paste_tokens): Take a virtual location parameter for
        the LHS of the pasting operator.  Use it in diagnostics.  Update
        comments.
        (paste_all_tokens): Tighten the assert.  Propagate the location of
        the expansion point when no virtual locations are available.
        Pass the virtual location to paste_tokens.

gcc/testsuite/

        PR preprocessor/53229
        * gcc.dg/cpp/paste6.c: Force to run without
        -ftrack-macro-expansion.
        * gcc.dg/cpp/paste8.c: Likewise.
        * gcc.dg/cpp/paste8-2.c: New test, like paste8.c but run with
        -ftrack-macro-expansion.
        * gcc.dg/cpp/paste12.c: Force to run without
        -ftrack-macro-expansion.
        * gcc.dg/cpp/paste12-2.c: New test, like paste12.c but run with
        -ftrack-macro-expansion.
        * gcc.dg/cpp/paste13.c: Likewise.
        * gcc.dg/cpp/paste14.c: Likewise.
        * gcc.dg/cpp/paste14-2.c: New test, like paste14.c but run with
        -ftrack-macro-expansion.
        * gcc.dg/cpp/paste18.c: New test.
---
 gcc/testsuite/gcc.dg/cpp/paste12-2.c |   11 +++++++++++
 gcc/testsuite/gcc.dg/cpp/paste12.c   |    5 ++++-
 gcc/testsuite/gcc.dg/cpp/paste13.c   |    5 ++++-
 gcc/testsuite/gcc.dg/cpp/paste14-2.c |   11 +++++++++++
 gcc/testsuite/gcc.dg/cpp/paste14.c   |    5 ++++-
 gcc/testsuite/gcc.dg/cpp/paste18.c   |   16 ++++++++++++++++
 gcc/testsuite/gcc.dg/cpp/paste6.c    |    5 ++++-
 gcc/testsuite/gcc.dg/cpp/paste8-2.c  |   15 +++++++++++++++
 gcc/testsuite/gcc.dg/cpp/paste8.c    |    2 +-
 libcpp/directives.c                  |    7 +++++--
 libcpp/macro.c                       |   25 +++++++++++++++++--------
 11 files changed, 92 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/cpp/paste12-2.c
 create mode 100644 gcc/testsuite/gcc.dg/cpp/paste14-2.c
 create mode 100644 gcc/testsuite/gcc.dg/cpp/paste18.c
 create mode 100644 gcc/testsuite/gcc.dg/cpp/paste8-2.c

diff --git a/gcc/testsuite/gcc.dg/cpp/paste12-2.c 
b/gcc/testsuite/gcc.dg/cpp/paste12-2.c
new file mode 100644
index 0000000..6e2e4f1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/paste12-2.c
@@ -0,0 +1,11 @@
+/* 
+   { dg-options "-ftrack-macro-expansion=2" }
+   { dg-do preprocess }
+ */
+
+/* Test correct diagnostics when pasting in #include.
+   Source: PR preprocessor/6780.  */
+
+#define inc2(a,b) <##a.b>  /* { dg-error "pasting \"<\" and \"stdio\" does 
not" } */
+#define INC(X) inc2(X,h)
+#include INC(stdio)
diff --git a/gcc/testsuite/gcc.dg/cpp/paste12.c 
b/gcc/testsuite/gcc.dg/cpp/paste12.c
index e61ec51..3e0f7b9 100644
--- a/gcc/testsuite/gcc.dg/cpp/paste12.c
+++ b/gcc/testsuite/gcc.dg/cpp/paste12.c
@@ -1,4 +1,7 @@
-/* { dg-do preprocess } */
+/*
+  { dg-options "-ftrack-macro-expansion=0" }
+  { dg-do preprocess }
+*/
 
 /* Test correct diagnostics when pasting in #include.
    Source: PR preprocessor/6780.  */
diff --git a/gcc/testsuite/gcc.dg/cpp/paste13.c 
b/gcc/testsuite/gcc.dg/cpp/paste13.c
index 62c72d4..f0f4fd8 100644
--- a/gcc/testsuite/gcc.dg/cpp/paste13.c
+++ b/gcc/testsuite/gcc.dg/cpp/paste13.c
@@ -1,6 +1,9 @@
 /* Copyright (C) 2000 Free Software Foundation, Inc.  */
 
-/* { dg-do preprocess } */
+/*
+  { dg-options "-ftrack-macro-expansion=0" }
+  { dg-do preprocess }
+*/
 
 /* This used to be recognized as a comment when lexing after pasting
    spellings.  Neil Booth, 9 Oct 2002.  */
diff --git a/gcc/testsuite/gcc.dg/cpp/paste14-2.c 
b/gcc/testsuite/gcc.dg/cpp/paste14-2.c
new file mode 100644
index 0000000..3b23ada
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/paste14-2.c
@@ -0,0 +1,11 @@
+/* PR preprocessor/28709 */
+/* 
+   { dg-options "-ftrack-macro-expansion=2" }
+   { dg-do preprocess }
+*/
+
+#define foo - ## >> /* { dg-error "pasting \"-\" and \">>\"" } */
+foo
+#define bar = ## == /* { dg-error "pasting \"=\" and \"==\"" } */
+bar
+
diff --git a/gcc/testsuite/gcc.dg/cpp/paste14.c 
b/gcc/testsuite/gcc.dg/cpp/paste14.c
index ec243c2..043d5e5 100644
--- a/gcc/testsuite/gcc.dg/cpp/paste14.c
+++ b/gcc/testsuite/gcc.dg/cpp/paste14.c
@@ -1,5 +1,8 @@
 /* PR preprocessor/28709 */
-/* { dg-do preprocess } */
+/* 
+   { dg-options "-ftrack-macro-expansion=0" }
+   { dg-do preprocess }
+*/
 
 #define foo - ## >>
 foo            /* { dg-error "pasting \"-\" and \">>\"" } */
diff --git a/gcc/testsuite/gcc.dg/cpp/paste18.c 
b/gcc/testsuite/gcc.dg/cpp/paste18.c
new file mode 100644
index 0000000..2888144
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/paste18.c
@@ -0,0 +1,16 @@
+/* 
+   { dg-options "-ftrack-macro-expansion=2" }
+   { dg-do compile }
+ */
+
+struct x {
+  int i;
+};
+struct x x;
+
+#define TEST(X) x.##X /* { dg-error "pasting\[^\n\r\]*does not 
give\[^\n\r\]*token" } */
+
+void foo (void)
+{
+  TEST(i) = 0;
+}
diff --git a/gcc/testsuite/gcc.dg/cpp/paste6.c 
b/gcc/testsuite/gcc.dg/cpp/paste6.c
index ac9ae39..a4e70e4 100644
--- a/gcc/testsuite/gcc.dg/cpp/paste6.c
+++ b/gcc/testsuite/gcc.dg/cpp/paste6.c
@@ -2,7 +2,10 @@
    actual arguments.  Original bug exposed by Linux kernel.  Problem
    reported by Jakub Jelinek <ja...@redhat.com>.  */
 
-/* { dg-do compile } */
+/*
+  { dg-options "-ftrack-macro-expansion=0" }
+  { dg-do compile }
+*/
 
 extern int foo(int x);
 
diff --git a/gcc/testsuite/gcc.dg/cpp/paste8-2.c 
b/gcc/testsuite/gcc.dg/cpp/paste8-2.c
new file mode 100644
index 0000000..c037e99
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/paste8-2.c
@@ -0,0 +1,15 @@
+/* { dg-do preprocess } */
+/* { dg-options "-ftrack-macro-expansion=2" } */
+
+int foo(int, ...);
+
+#define a(x, y...) foo(x, ##y)
+a(1)
+a(1, 2, 3)
+#define b(x, y, z...) foo(x, ##y) /* { dg-error "valid preprocessing token" } 
*/
+b(1, 2, 3)                     
+#define c(x, y, z...) foo(x, ##z)
+c(1, 2)
+c(1, 2, 3)
+#define d(x) fo(##x) /* { dg-error "valid preprocessing token" } */
+d(1)                           
diff --git a/gcc/testsuite/gcc.dg/cpp/paste8.c 
b/gcc/testsuite/gcc.dg/cpp/paste8.c
index ab01779..db1416c 100644
--- a/gcc/testsuite/gcc.dg/cpp/paste8.c
+++ b/gcc/testsuite/gcc.dg/cpp/paste8.c
@@ -1,5 +1,5 @@
 /* { dg-do preprocess } */
-/* { dg-options "" } */
+/* { dg-options "-ftrack-macro-expansion=0" } */
 
 int foo(int, ...);
 
diff --git a/libcpp/directives.c b/libcpp/directives.c
index e46280e..e161810 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -1660,13 +1660,16 @@ do_pragma_dependency (cpp_reader *pfile)
   free ((void *) fname);
 }
 
-/* Get a token but skip padding.  */
+/* Get a token but skip padding.
+
+   Handles macro expansion and allows the use of virtual locations in
+   diagnostics emitted by the preprocessor.  */
 static const cpp_token *
 get_token_no_padding (cpp_reader *pfile)
 {
   for (;;)
     {
-      const cpp_token *result = cpp_get_token (pfile);
+      const cpp_token *result = cpp_get_token_with_location (pfile, NULL);
       if (result->type != CPP_PADDING)
        return result;
     }
diff --git a/libcpp/macro.c b/libcpp/macro.c
index c4e2a23..04810b3 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -100,7 +100,8 @@ static void expand_arg (cpp_reader *, macro_arg *);
 static const cpp_token *new_string_token (cpp_reader *, uchar *, unsigned int);
 static const cpp_token *stringify_arg (cpp_reader *, macro_arg *);
 static void paste_all_tokens (cpp_reader *, const cpp_token *);
-static bool paste_tokens (cpp_reader *, const cpp_token **, const cpp_token *);
+static bool paste_tokens (cpp_reader *, source_location,
+                         const cpp_token **, const cpp_token *);
 static void alloc_expanded_arg_mem (cpp_reader *, macro_arg *, size_t);
 static void ensure_expanded_arg_room (cpp_reader *, macro_arg *, size_t, 
size_t *);
 static void delete_macro_args (_cpp_buff*, unsigned num_args);
@@ -544,9 +545,11 @@ stringify_arg (cpp_reader *pfile, macro_arg *arg)
 
 /* Try to paste two tokens.  On success, return nonzero.  In any
    case, PLHS is updated to point to the pasted token, which is
-   guaranteed to not have the PASTE_LEFT flag set.  */
+   guaranteed to not have the PASTE_LEFT flag set.  LOCATION is
+   the virtual location used for error reporting.  */
 static bool
-paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs)
+paste_tokens (cpp_reader *pfile, source_location location,
+             const cpp_token **plhs, const cpp_token *rhs)
 {
   unsigned char *buf, *end, *lhsend;
   cpp_token *lhs;
@@ -590,7 +593,7 @@ paste_tokens (cpp_reader *pfile, const cpp_token **plhs, 
const cpp_token *rhs)
 
       /* Mandatory error for all apart from assembler.  */
       if (CPP_OPTION (pfile, lang) != CLK_ASM)
-       cpp_error (pfile, CPP_DL_ERROR,
+       cpp_error_with_line (pfile, CPP_DL_ERROR, location, 0,
         "pasting \"%s\" and \"%s\" does not give a valid preprocessing token",
                   buf, cpp_token_as_text (pfile, rhs));
       return false;
@@ -615,9 +618,10 @@ paste_all_tokens (cpp_reader *pfile, const cpp_token *lhs)
   cpp_context *context = pfile->context;
   source_location virt_loc = 0;
 
-  /* We must have been called on a token that appears at the left
-     hand side of a ## operator.  */
-  if (!(lhs->flags & PASTE_LEFT))
+  /* We are expanding a macro and we must have been called on a token
+     that appears at the left hand side of a ## operator.  */
+  if (macro_of_context (pfile->context) == NULL
+      || (!(lhs->flags & PASTE_LEFT)))
     abort ();
 
   if (context->tokens_kind == TOKENS_KIND_EXTENDED)
@@ -628,6 +632,11 @@ paste_all_tokens (cpp_reader *pfile, const cpp_token *lhs)
        resulting pasted token to have the location of the current
        *LHS, though.  */
     virt_loc = context->c.mc->cur_virt_loc[-1];
+  else
+    /* We are not tracking macro expansion.  So the best virtual
+       location we can get here is the expansion point of the macro we
+       are currently expanding.  */
+    virt_loc = pfile->invocation_location;
 
   do
     {
@@ -661,7 +670,7 @@ paste_all_tokens (cpp_reader *pfile, const cpp_token *lhs)
          if (rhs->flags & PASTE_LEFT)
            abort ();
        }
-      if (!paste_tokens (pfile, &lhs, rhs))
+      if (!paste_tokens (pfile, virt_loc, &lhs, rhs))
        break;
     }
   while (rhs->flags & PASTE_LEFT);
-- 
1.7.6.5


-- 
                Dodji

Reply via email to