Re: [PATCH] Fix __has_{cpp_}attribute with -traditional-cpp (PR preprocessor/65238)

2015-03-20 Thread Jason Merrill

On 03/20/2015 01:23 PM, Jakub Jelinek wrote:

Well, but the traditional preprocessor behavior in the end is not in not
expanding macro arguments, normally they actually are expanded, but not
immediately, but because of trying to preprocess the result of preprocessing
again and again.
When traditionally preprocessing #if/#elif etc. directives, the directive
line is preprocessed until no macros are present and only then fed to the
ISO preprocessor to evaluate and handle the directive.
The problem with the builtin function-like macros is that it needs the
argument immediately.


Ah, I see, thanks.  Please add some of this rationale to the patch.  OK 
with that.


Jason




Re: [PATCH] Fix __has_{cpp_}attribute with -traditional-cpp (PR preprocessor/65238)

2015-03-20 Thread Jakub Jelinek
On Fri, Mar 20, 2015 at 01:15:52PM -0400, Jason Merrill wrote:
 On 03/20/2015 12:48 PM, Jakub Jelinek wrote:
 On Fri, Mar 20, 2015 at 12:30:44PM -0400, Jason Merrill wrote:
 On 03/11/2015 03:10 PM, Jakub Jelinek wrote:
 __has_{cpp_,}attribute builtin macros are effectively function-like macros
 taking one argument (and the ISO preprocessor expands macros in the 
 argument
 which is IMHO desirable), but the traditional preprocessor has been 
 crashing
 on them or reporting errors.
 
 Why do we want ISO preprocessor behavior in this specific situation?
 
 You mean that we would handle
 #define U unused
 #if __has_attribute(U)
 int u __attribute__((unused));
 #endif
 differently between ISO and traditional preprocessing?
 
 That would be surprising to users.
 
 Why surprising?  Don't users of the traditional preprocessor expect
 traditional preprocessor behavior?

Well, but the traditional preprocessor behavior in the end is not in not
expanding macro arguments, normally they actually are expanded, but not
immediately, but because of trying to preprocess the result of preprocessing
again and again.
When traditionally preprocessing #if/#elif etc. directives, the directive
line is preprocessed until no macros are present and only then fed to the
ISO preprocessor to evaluate and handle the directive.
The problem with the builtin function-like macros is that it needs the
argument immediately.

Jakub


Re: [PATCH] Fix __has_{cpp_}attribute with -traditional-cpp (PR preprocessor/65238)

2015-03-20 Thread Dodji Seketeli
Jason Merrill ja...@redhat.com writes:

 On 03/20/2015 12:48 PM, Jakub Jelinek wrote:
 On Fri, Mar 20, 2015 at 12:30:44PM -0400, Jason Merrill wrote:
 On 03/11/2015 03:10 PM, Jakub Jelinek wrote:
 __has_{cpp_,}attribute builtin macros are effectively function-like macros
 taking one argument (and the ISO preprocessor expands macros in the 
 argument
 which is IMHO desirable), but the traditional preprocessor has been 
 crashing
 on them or reporting errors.

 Why do we want ISO preprocessor behavior in this specific situation?

 You mean that we would handle
 #define U unused
 #if __has_attribute(U)
 int u __attribute__((unused));
 #endif
 differently between ISO and traditional preprocessing?

 That would be surprising to users.

 Why surprising?  Don't users of the traditional preprocessor expect
 traditional preprocessor behavior?

One of the reasons why I thought it'd be nice to have the traditionnal
mode support the macro-expansion of the arguments here is that there
already are cases where the traditionnal mode supports ISO behaviour.
For instance, the documentation of cpp says:

10.3 Traditional miscellany
===

Here are some things to be aware of when using the traditional
preprocessor.

[...]

   * A true traditional C preprocessor does not recognize '#error' or
 '#pragma', and may not recognize '#elif'.  CPP supports all the
 directives in traditional mode that it supports in ISO mode,
 including extensions, with the exception that the effects of
 '#pragma GCC poison' are undefined.

So I thought this useful particular use case of __has_attribute(U) might
well be another of such case even if it's not a directive.

Just my 2 cents.

-- 
Dodji


Re: [PATCH] Fix __has_{cpp_}attribute with -traditional-cpp (PR preprocessor/65238)

2015-03-20 Thread Jason Merrill

On 03/11/2015 03:10 PM, Jakub Jelinek wrote:

__has_{cpp_,}attribute builtin macros are effectively function-like macros
taking one argument (and the ISO preprocessor expands macros in the argument
which is IMHO desirable), but the traditional preprocessor has been crashing
on them or reporting errors.


Why do we want ISO preprocessor behavior in this specific situation?

Jason



Re: [PATCH] Fix __has_{cpp_}attribute with -traditional-cpp (PR preprocessor/65238)

2015-03-20 Thread Jason Merrill

On 03/20/2015 12:48 PM, Jakub Jelinek wrote:

On Fri, Mar 20, 2015 at 12:30:44PM -0400, Jason Merrill wrote:

On 03/11/2015 03:10 PM, Jakub Jelinek wrote:

__has_{cpp_,}attribute builtin macros are effectively function-like macros
taking one argument (and the ISO preprocessor expands macros in the argument
which is IMHO desirable), but the traditional preprocessor has been crashing
on them or reporting errors.


Why do we want ISO preprocessor behavior in this specific situation?


You mean that we would handle
#define U unused
#if __has_attribute(U)
int u __attribute__((unused));
#endif
differently between ISO and traditional preprocessing?



That would be surprising to users.


Why surprising?  Don't users of the traditional preprocessor expect 
traditional preprocessor behavior?


Jason



Re: [PATCH] Fix __has_{cpp_}attribute with -traditional-cpp (PR preprocessor/65238)

2015-03-20 Thread Jakub Jelinek
On Fri, Mar 20, 2015 at 12:30:44PM -0400, Jason Merrill wrote:
 On 03/11/2015 03:10 PM, Jakub Jelinek wrote:
 __has_{cpp_,}attribute builtin macros are effectively function-like macros
 taking one argument (and the ISO preprocessor expands macros in the argument
 which is IMHO desirable), but the traditional preprocessor has been crashing
 on them or reporting errors.
 
 Why do we want ISO preprocessor behavior in this specific situation?

You mean that we would handle
#define U unused
#if __has_attribute(U)
int u __attribute__((unused));
#endif
differently between ISO and traditional preprocessing?
That would be surprising to users.  IMHO either we want to expand
the arguments in both cases (what the patch does), or in none
(that would be then consistent with clang++, guess would mean adding
pfile-state.prevent_expansion++; / pfile-state.prevent_expansion--;
pair around something in the ISO case, and would slightly but not too much
simplify the traditional __has_attribute handling; still we'd need to build
the buffer with the argument and feed it to the langhook, which parses it
with ISO preprocessor with disabled expansion).

Jakub


Re: [PATCH] Fix __has_{cpp_}attribute with -traditional-cpp (PR preprocessor/65238)

2015-03-19 Thread Dodji Seketeli
Hello Jakub,

Jakub Jelinek ja...@redhat.com writes:

 __has_{cpp_,}attribute builtin macros are effectively function-like macros
 taking one argument (and the ISO preprocessor expands macros in the argument
 which is IMHO desirable), but the traditional preprocessor has been crashing
 on them or reporting errors.
 As the hook uses cpp_get_token and thus the ISO preprocessor, we need to set
 up things such that the argument and ()s around it are already preprocessed
 and ready to be reparsed by the ISO preprocessor (this is similar to how
 e.g. #if/#elif and various other directives are handled).

 Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

 2015-03-11  Jakub Jelinek  ja...@redhat.com

   PR preprocessor/65238
   * internal.h (_cpp_scan_out_logical_line): Add third argument.
   * directives.c (prepare_directive_trad): Pass false to it.
   * traditional.c (_cpp_read_logical_line_trad,
   _cpp_create_trad_definition): Likewise.
   (struct fun_macro): Add paramc field.
   (fun_like_macro): New function.
   (maybe_start_funlike): Handle NODE_BUILTIN macros.  Initialize
   macro-paramc field.
   (save_argument): Use macro-paramc instead of
   macro-node-value.macro-paramc.
   (push_replacement_text): Formatting fix.
   (recursive_macro): Use fun_like_macro helper.
   (_cpp_scan_out_logical_line): Likewise.  Add BUILTIN_MACRO_ARG
   argument.  Initialize fmacro.paramc field.  Handle builtin
   function-like macros.

   * c-c++-common/cpp/pr65238-1.c: New test.
   * gcc.dg/cpp/pr65238-2.c: New test.
   * gcc.dg/cpp/trad/pr65238-3.c: New test.
   * gcc.dg/cpp/trad/pr65238-4.c: New test.

I do not have the rights to ACK this but FWIW it looks OK to me.  Sorry
for the delay in reviewing this.

Thanks!

Cheers,

-- 
Dodji


[PATCH] Fix __has_{cpp_}attribute with -traditional-cpp (PR preprocessor/65238)

2015-03-11 Thread Jakub Jelinek
Hi!

__has_{cpp_,}attribute builtin macros are effectively function-like macros
taking one argument (and the ISO preprocessor expands macros in the argument
which is IMHO desirable), but the traditional preprocessor has been crashing
on them or reporting errors.
As the hook uses cpp_get_token and thus the ISO preprocessor, we need to set
up things such that the argument and ()s around it are already preprocessed
and ready to be reparsed by the ISO preprocessor (this is similar to how
e.g. #if/#elif and various other directives are handled).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2015-03-11  Jakub Jelinek  ja...@redhat.com

PR preprocessor/65238
* internal.h (_cpp_scan_out_logical_line): Add third argument.
* directives.c (prepare_directive_trad): Pass false to it.
* traditional.c (_cpp_read_logical_line_trad,
_cpp_create_trad_definition): Likewise.
(struct fun_macro): Add paramc field.
(fun_like_macro): New function.
(maybe_start_funlike): Handle NODE_BUILTIN macros.  Initialize
macro-paramc field.
(save_argument): Use macro-paramc instead of
macro-node-value.macro-paramc.
(push_replacement_text): Formatting fix.
(recursive_macro): Use fun_like_macro helper.
(_cpp_scan_out_logical_line): Likewise.  Add BUILTIN_MACRO_ARG
argument.  Initialize fmacro.paramc field.  Handle builtin
function-like macros.

* c-c++-common/cpp/pr65238-1.c: New test.
* gcc.dg/cpp/pr65238-2.c: New test.
* gcc.dg/cpp/trad/pr65238-3.c: New test.
* gcc.dg/cpp/trad/pr65238-4.c: New test.

--- libcpp/internal.h.jj2015-02-03 10:33:59.0 +0100
+++ libcpp/internal.h   2015-03-11 14:11:13.410854083 +0100
@@ -708,7 +708,7 @@ extern void _cpp_preprocess_dir_only (cp
  const struct _cpp_dir_only_callbacks *);
 
 /* In traditional.c.  */
-extern bool _cpp_scan_out_logical_line (cpp_reader *, cpp_macro *);
+extern bool _cpp_scan_out_logical_line (cpp_reader *, cpp_macro *, bool);
 extern bool _cpp_read_logical_line_trad (cpp_reader *);
 extern void _cpp_overlay_buffer (cpp_reader *pfile, const unsigned char *,
 size_t);
--- libcpp/directives.c.jj  2015-01-23 19:18:20.0 +0100
+++ libcpp/directives.c 2015-03-11 14:11:34.742511193 +0100
@@ -346,7 +346,7 @@ prepare_directive_trad (cpp_reader *pfil
 
   if (no_expand)
pfile-state.prevent_expansion++;
-  _cpp_scan_out_logical_line (pfile, NULL);
+  _cpp_scan_out_logical_line (pfile, NULL, false);
   if (no_expand)
pfile-state.prevent_expansion--;
 
--- libcpp/traditional.c.jj 2015-03-10 16:37:11.418949471 +0100
+++ libcpp/traditional.c2015-03-11 16:19:05.598475497 +0100
@@ -62,6 +62,9 @@ struct fun_macro
   /* The line the macro name appeared on.  */
   source_location line;
 
+  /* Number of parameters.  */
+  unsigned int paramc;
+
   /* Zero-based index of argument being currently lexed.  */
   unsigned int argc;
 };
@@ -304,24 +307,41 @@ _cpp_read_logical_line_trad (cpp_reader
   if (pfile-buffer-need_line  !_cpp_get_fresh_line (pfile))
return false;
 }
-  while (!_cpp_scan_out_logical_line (pfile, NULL) || pfile-state.skipping);
+  while (!_cpp_scan_out_logical_line (pfile, NULL, false)
+|| pfile-state.skipping);
 
   return pfile-buffer != NULL;
 }
 
+/* Return true if NODE is a fun_like macro.  */
+static inline bool
+fun_like_macro (cpp_hashnode *node)
+{
+  if (node-flags  NODE_BUILTIN)
+return node-value.builtin == BT_HAS_ATTRIBUTE;
+  else
+return node-value.macro-fun_like;
+}
+
 /* Set up state for finding the opening '(' of a function-like
macro.  */
 static void
-maybe_start_funlike (cpp_reader *pfile, cpp_hashnode *node, const uchar 
*start, struct fun_macro *macro)
+maybe_start_funlike (cpp_reader *pfile, cpp_hashnode *node, const uchar *start,
+struct fun_macro *macro)
 {
-  unsigned int n = node-value.macro-paramc + 1;
+  unsigned int n;
+  if (node-flags  NODE_BUILTIN)
+n = 1;
+  else
+n = node-value.macro-paramc;
 
   if (macro-buff)
 _cpp_release_buff (pfile, macro-buff);
-  macro-buff = _cpp_get_buff (pfile, n * sizeof (size_t));
+  macro-buff = _cpp_get_buff (pfile, (n + 1) * sizeof (size_t));
   macro-args = (size_t *) BUFF_FRONT (macro-buff);
   macro-node = node;
   macro-offset = start - pfile-out.base;
+  macro-paramc = n;
   macro-argc = 0;
 }
 
@@ -330,7 +350,7 @@ static void
 save_argument (struct fun_macro *macro, size_t offset)
 {
   macro-argc++;
-  if (macro-argc = macro-node-value.macro-paramc)
+  if (macro-argc = macro-paramc)
 macro-args[macro-argc] = offset;
 }
 
@@ -340,9 +360,13 @@ save_argument (struct fun_macro *macro,
 
If MACRO is non-NULL, then we are scanning the replacement list of
MACRO, and we call save_replacement_text() every time we meet an
-