Re: [PATCH] Fix __has_{cpp_}attribute with -traditional-cpp (PR preprocessor/65238)
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)
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)
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)
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)
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)
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)
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)
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 -