diff options
author | Jakub Jelinek <jakub@redhat.com> | 2024-09-12 18:17:05 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2024-09-12 18:17:05 +0200 |
commit | ce0aecc7df1ff0be24c278dff5575ec28042ee58 (patch) | |
tree | 0fbd4ae6771550607816a7ba4fb6fd391e4f3c98 /gcc | |
parent | c5009eb887910271ea35a857aa68941c7227b9c7 (diff) | |
download | gcc-ce0aecc7df1ff0be24c278dff5575ec28042ee58.zip gcc-ce0aecc7df1ff0be24c278dff5575ec28042ee58.tar.gz gcc-ce0aecc7df1ff0be24c278dff5575ec28042ee58.tar.bz2 |
libcpp, v2: Add support for gnu::base64 #embed parameter
This patch which adds another #embed extension, gnu::base64.
As mentioned in the documentation, this extension is primarily
intended for use by the preprocessor, so that for the larger (say 32+ or
64+ bytes long embeds it doesn't have to emit tens of thousands or
millions of comma separated string literals which would be very expensive
to parse again, but can emit
#embed "." __gnu__::__base64__( \
"Tm9uIGVyYW0gbsOpc2NpdXMsIEJydXRlLCBjdW0sIHF1w6Ygc3VtbWlzIGluZ8OpbmlpcyBleHF1" \
"aXNpdMOhcXVlIGRvY3Ryw61uYSBwaGlsw7Nzb3BoaSBHcsOmY28gc2VybcOzbmUgdHJhY3RhdsOt" \
"c3NlbnQsIGVhIExhdMOtbmlzIGzDrXR0ZXJpcyBtYW5kYXLDqW11cywgZm9yZSB1dCBoaWMgbm9z" \
"dGVyIGxhYm9yIGluIHbDoXJpYXMgcmVwcmVoZW5zacOzbmVzIGluY8O6cnJlcmV0LiBuYW0gcXVp" \
"YsO6c2RhbSwgZXQgaWlzIHF1aWRlbSBub24gw6FkbW9kdW0gaW5kw7NjdGlzLCB0b3R1bSBob2Mg" \
"ZMOtc3BsaWNldCBwaGlsb3NvcGjDoXJpLiBxdWlkYW0gYXV0ZW0gbm9uIHRhbSBpZCByZXByZWjD" \
"qW5kdW50LCBzaSByZW3DrXNzaXVzIGFnw6F0dXIsIHNlZCB0YW50dW0gc3TDumRpdW0gdGFtcXVl" \
"IG11bHRhbSDDs3BlcmFtIHBvbsOpbmRhbSBpbiBlbyBub24gYXJiaXRyw6FudHVyLiBlcnVudCDD" \
"qXRpYW0sIGV0IGlpIHF1aWRlbSBlcnVkw610aSBHcsOmY2lzIGzDrXR0ZXJpcywgY29udGVtbsOp" \
"bnRlcyBMYXTDrW5hcywgcXVpIHNlIGRpY2FudCBpbiBHcsOmY2lzIGxlZ8OpbmRpcyDDs3BlcmFt" \
"IG1hbGxlIGNvbnPDum1lcmUuIHBvc3Ryw6ltbyDDoWxpcXVvcyBmdXTDunJvcyBzw7pzcGljb3Is" \
"IHF1aSBtZSBhZCDDoWxpYXMgbMOtdHRlcmFzIHZvY2VudCwgZ2VudXMgaG9jIHNjcmliw6luZGks" \
"IGV0c2kgc2l0IGVsw6lnYW5zLCBwZXJzw7Nuw6YgdGFtZW4gZXQgZGlnbml0w6F0aXMgZXNzZSBu" \
"ZWdlbnQu")
with the meaning don't actually load some file, instead base64 decode
(RFC4648 with A-Za-z0-9+/ chars and = padding, no newlines in between)
the string and use that as data. This is chosen because it should be
-pedantic-errors clean, fairly cheap to decode and then in optimizing
compiler could be handled as similar binary blob to normal #embed,
while the data isn't left somewhere on the disk, so distcc/ccache etc.
can move the preprocessed source without issues.
It makes no sense to support limit and gnu::offset parameters together
with it IMHO, why would somebody waste providing full data and then
threw some away? prefix/suffix/if_empty are normally supported though,
but not intended to be used by the preprocessor.
This patch adds just the extension side, not the actual emitting of this
during -E or -E -fdirectives-only for now, that will be included in the
upcoming patch.
Compared to the earlier posted version of this extension, this patch
allows the string concatenation in the parameter argument (but still
doesn't allow escapes in the string, why would anyone use them when
only A-Za-z0-9+/= are valid). The patch also adds support for parsing
this even in -fpreprocessed compilation.
2024-09-12 Jakub Jelinek <jakub@redhat.com>
libcpp/
* internal.h (struct cpp_embed_params): Add base64 member.
(_cpp_free_embed_params_tokens): Declare.
* directives.cc (DIRECTIVE_TABLE): Add IN_I flag to T_EMBED.
(save_token_for_embed, _cpp_free_embed_params_tokens): New functions.
(EMBED_PARAMS): Add gnu::base64 entry.
(_cpp_parse_embed_params): Parse gnu::base64 parameter. If
-fpreprocessed without -fdirectives-only, require #embed to have
gnu::base64 parameter. Diagnose conflict between gnu::base64 and
limit or gnu::offset parameters.
(do_embed): Use _cpp_free_embed_params_tokens.
* files.cc (finish_embed, base64_dec_fn): New functions.
(base64_dec): New array.
(B64D0, B64D1, B64D2, B64D3): Define.
(finish_base64_embed): New function.
(_cpp_stack_embed): Use finish_embed. Handle params->base64
using finish_base64_embed.
* macro.cc (builtin_has_embed): Call _cpp_free_embed_params_tokens.
gcc/
* doc/cpp.texi (Binary Resource Inclusion): Document gnu::base64
parameter.
gcc/testsuite/
* c-c++-common/cpp/embed-17.c: New test.
* c-c++-common/cpp/embed-18.c: New test.
* c-c++-common/cpp/embed-19.c: New test.
* c-c++-common/cpp/embed-27.c: New test.
* gcc.dg/cpp/embed-6.c: New test.
* gcc.dg/cpp/embed-7.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/doc/cpp.texi | 14 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/cpp/embed-17.c | 116 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/cpp/embed-18.c | 54 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/cpp/embed-19.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/cpp/embed-27.c | 64 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/embed-6.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/embed-7.c | 6 |
7 files changed, 264 insertions, 1 deletions
diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi index 612d97e..db3a075 100644 --- a/gcc/doc/cpp.texi +++ b/gcc/doc/cpp.texi @@ -3967,7 +3967,8 @@ with currently supported standard parameters @code{limit}, @code{prefix}, @code{suffix} and @code{if_empty}, or implementation defined parameters specified by a unique vendor prefix followed by @code{::} followed by name of the parameter. GCC uses the @code{gnu} prefix for vendor -parameters and currently supports the @code{gnu::offset} parameter. +parameters and currently supports the @code{gnu::offset} and +@code{gnu::base64} parameters. The @code{limit} parameter argument is a constant expression which specifies the maximum number of bytes included by the directive, @@ -3981,6 +3982,17 @@ The @code{gnu::offset} parameter argument is a constant expression which specifies how many bytes to skip from the start of the resource. @code{limit} is then counted from that position. +The @code{gnu::base64} parameter argument is a possibly concatenated +character string literal with base64 encoded data. See +@uref{https://datatracker.ietf.org/doc/html/rfc4648#section-4}. There +should be no newlines in the string literal and because this parameter +is meant namely for use by the preprocessor itself, there is no support +for any escape sequences in the string literal argument. If @code{gnu::base64} +parameter is specified, the @code{limit} and @code{gnu::offset} parameters +should not be specified and the filename should be always @code{"."}. +Instead of reading a file the directive will decode the base64 encoded +data and use that as the data to include. + The @code{#embed} directive is not supported in the Traditional Mode (@pxref{Traditional Mode}). diff --git a/gcc/testsuite/c-c++-common/cpp/embed-17.c b/gcc/testsuite/c-c++-common/cpp/embed-17.c new file mode 100644 index 0000000..788222c --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/embed-17.c @@ -0,0 +1,116 @@ +/* { dg-do run } */ +/* { dg-options "--embed-dir=${srcdir}/c-c++-common/cpp/embed-dir" } */ +/* { dg-additional-options "-std=gnu99" { target c } } */ + +#if __has_embed ("." gnu::base64 ("")) != __STDC_EMBED_EMPTY__ +#error "__has_embed fail" +#endif + +#if __has_embed ("." gnu::base64 ("SA==")) != __STDC_EMBED_FOUND__ +#error "__has_embed fail" +#endif + +#if __has_embed ("." prefix(-) suffix (-) if_empty (-) __gnu__::__base64__ ("SA==")) != __STDC_EMBED_FOUND__ +#error "__has_embed fail" +#endif + +#if __has_embed ("." gnu::__base64__ ("SGU=")) != __STDC_EMBED_FOUND__ +#error "__has_embed fail" +#endif + +#if __has_embed ("." gnu::__base64__ ("SGVs")) != __STDC_EMBED_FOUND__ +#error "__has_embed fail" +#endif + +#if __has_embed ("." __gnu__::base64 ("SGVsbG8=")) != __STDC_EMBED_FOUND__ +#error "__has_embed fail" +#endif + +/* M. Tulli Ciceronis De Finibus Bonorum et Malorum. Liber Primus. */ +/* echo "Tm9u....bnQu" | fmt -s -w 76 | base64 -d to decode. */ +#define BONORUM_ET_MALORUM \ +"Tm9uIGVyYW0gbsOpc2NpdXMsIEJydXRlLCBjdW0sIHF1w6Ygc3VtbWlzIGluZ8OpbmlpcyBleHF1aXNpdMOhcXVlIGRvY3Ryw61uYSBwaGlsw7Nzb3BoaSBHcsOmY28gc2VybcOzbmUgdHJhY3RhdsOtc3NlbnQsIGVhIExhdMOtbmlzIGzDrXR0ZXJpcyBtYW5kYXLDqW11cywgZm9yZSB1dCBoaWMgbm9zdGVyIGxhYm9yIGluIHbDoXJpYXMgcmVwcmVoZW5zacOzbmVzIGluY8O6cnJlcmV0LiBuYW0gcXVpYsO6c2RhbSwgZXQgaWlzIHF1aWRlbSBub24gw6FkbW9kdW0gaW5kw7NjdGlzLCB0b3R1bSBob2MgZMOtc3BsaWNldCBwaGlsb3NvcGjDoXJpLiBxdWlkYW0gYXV0ZW0gbm9uIHRhbSBpZCByZXByZWjDqW5kdW50LCBzaSByZW3DrXNzaXVzIGFnw6F0dXIsIHNlZCB0YW50dW0gc3TDumRpdW0gdGFtcXVlIG11bHRhbSDDs3BlcmFtIHBvbsOpbmRhbSBpbiBlbyBub24gYXJiaXRyw6FudHVyLiBlcnVudCDDqXRpYW0sIGV0IGlpIHF1aWRlbSBlcnVkw610aSBHcsOmY2lzIGzDrXR0ZXJpcywgY29udGVtbsOpbnRlcyBMYXTDrW5hcywgcXVpIHNlIGRpY2FudCBpbiBHcsOmY2lzIGxlZ8OpbmRpcyDDs3BlcmFtIG1hbGxlIGNvbnPDum1lcmUuIHBvc3Ryw6ltbyDDoWxpcXVvcyBmdXTDunJvcyBzw7pzcGljb3IsIHF1aSBtZSBhZCDDoWxpYXMgbMOtdHRlcmFzIHZvY2VudCwgZ2VudXMgaG9jIHNjcmliw6luZGksIGV0c2kgc2l0IGVsw6lnYW5zLCBwZXJzw7Nuw6YgdGFtZW4gZXQgZGlnbml0w6F0aXMgZXNzZSBuZWdlbnQu" +#if __has_embed ("." gnu::base64 (BONORUM_ET_MALORUM)) != __STDC_EMBED_FOUND__ +#error "__has_embed fail" +#endif + +#if __has_embed ("foo" gnu::base64 ("SGU=")) != __STDC_EMBED_NOT_FOUND__ +#error "__has_embed fail" +#endif + +#if __has_embed (<foo> gnu::base64 ("SGU=")) != __STDC_EMBED_NOT_FOUND__ +#error "__has_embed fail" +#endif + +#if __has_embed (<.> gnu::base64 ("SGU=")) != __STDC_EMBED_NOT_FOUND__ +#error "__has_embed fail" +#endif + +#if __has_embed ("." gnu::base64 ("SGU=") limit(5)) != __STDC_EMBED_NOT_FOUND__ +#error "__has_embed fail" +#endif + +#if __has_embed ("." gnu::base64 ("SGU=") gnu::offset(2)) != __STDC_EMBED_NOT_FOUND__ +#error "__has_embed fail" +#endif + +#embed "." gnu::base64 ("") if_empty (int a = 42;) prefix(+ +) suffix (+ +) +#embed "." __gnu__::__base64__ ("SA==") prefix (int b = ) suffix (;) if_empty (+ +) +const unsigned char c[] = { + #embed "." gnu::base64("SGU=") +}; +const unsigned char d[] = { + #embed "." gnu::base64 ("SGVs") +}; +const unsigned char e[] = { + #embed "." gnu::base64 ("SGVsbG8=") +}; +const unsigned char f[] = { +#ifdef __cplusplus + #embed "." gnu::base64 (BONORUM_ET_MALORUM) prefix (' ', ) +#else + #embed "." gnu::base64 (BONORUM_ET_MALORUM) prefix ([1] = ) suffix(, [0] = ' ') +#endif +}; +#if __has_embed ("." gnu::base64("TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwg" \ +"c2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWdu" \ +"YSBhbGlxdWEuCg==")) == __STDC_EMBED_FOUND__ +const unsigned char g[] = { +#embed "." gnu::base64("" \ +"T" "G9" "yZW" \ +"0gaX" \ +"BzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwg" \ +"c2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWdu" \ +"YSBhbGlxdWEuCg==") +}; +#endif + +#ifdef __cplusplus +#define C "C" +#else +#define C +#endif +extern C void abort (void); +extern C int memcmp (const void *, const void *, __SIZE_TYPE__); + +int +main () +{ + if (a != 42 || b != 'H') + abort (); + if (sizeof (c) != 2 || c[0] != 'H' || c[1] != 'e') + abort (); + if (sizeof (d) != 3 || d[0] != 'H' || d[1] != 'e' || d[2] != 'l') + abort (); + if (sizeof (e) != 5 || memcmp (e, "Hello", 5)) + abort (); + if (sizeof (f) != 1 + 747 || memcmp (f, " Non eram néscius, Brute", + sizeof (" Non eram néscius, Brute") - 1)) + abort (); + const char ge[] + = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."; + if (sizeof (g) != sizeof (ge) + || memcmp (g, ge, sizeof (ge) - 1) + || g[sizeof (ge) - 1] != '\n') + abort (); +} diff --git a/gcc/testsuite/c-c++-common/cpp/embed-18.c b/gcc/testsuite/c-c++-common/cpp/embed-18.c new file mode 100644 index 0000000..e9cefbe --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/embed-18.c @@ -0,0 +1,54 @@ +/* { dg-do preprocess } */ +/* { dg-options "" } */ + +#embed "." gnu::base64("") __gnu__::__base64__("") /* { dg-error "duplicate embed parameter 'gnu::base64'" } */ +#embed __FILE__ gnu::base64 prefix() suffix() /* { dg-error "expected '\\\('" } */ +#embed __FILE__ gnu::base64(1) prefix() suffix() /* { dg-error "expected character string literal" } */ +#embed __FILE__ gnu::base64() prefix() suffix() /* { dg-error "expected character string literal" } */ +#embed __FILE__ gnu::base64(L"SA==") /* { dg-error "expected character string literal" } */ +#embed __FILE__ gnu::base64(L"S" "A==") /* { dg-error "expected character string literal" } */ +/* { dg-error "expected parameter name" "" { target *-*-* } .-1 } */ +#embed __FILE__ gnu::base64("S" L"A==") /* { dg-error "expected '\\\)'" } */ +/* { dg-error "expected parameter name" "" { target *-*-* } .-1 } */ +#embed __FILE__ gnu::base64(L"S" L"A==") /* { dg-error "expected character string literal" } */ +/* { dg-error "expected parameter name" "" { target *-*-* } .-1 } */ +#embed "." prefix() suffix() gnu::base64("" /* { dg-error "expected '\\\)'" } */ +#embed "." gnu::base64("a") /* { dg-error "'gnu::base64' argument not valid base64 encoded string" } */ +#embed "." gnu::base64("----") /* { dg-error "'gnu::base64' argument not valid base64 encoded string" } */ +#embed "." gnu::base64("a===") /* { dg-error "'gnu::base64' argument not valid base64 encoded string" } */ +#embed "." gnu::base64("TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwg\nc2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWdu\nYSBhbGlxdWEuCg==") /* { dg-error "'gnu::base64' argument not valid base64 encoded string" } */ +#embed "." gnu::base64("\x53\x41\x3d\x3d") /* { dg-error "'gnu::base64' argument not valid base64 encoded string" } */ +#embed "." gnu::base64("\123\101\075\075") /* { dg-error "'gnu::base64' argument not valid base64 encoded string" } */ +#embed "." gnu::base64("\u0053\u0041\u003d\u003d") /* { dg-error "'gnu::base64' argument not valid base64 encoded string" } */ +#embed "." gnu::base64("\u{53}\u{41}\u{3d}\u{00003d}") /* { dg-error "'gnu::base64' argument not valid base64 encoded string" } */ +#embed "." gnu::base64("\U00000053\U00000041\U0000003d\U0000003d") /* { dg-error "'gnu::base64' argument not valid base64 encoded string" } */ +#embed "." gnu::base64("\N{LATIN CAPITAL LETTER S}\N{LATIN CAPITAL LETTER A}\N{LATIN CAPITAL LETTER A}\N{LATIN CAPITAL LETTER A}") /* { dg-error "'gnu::base64' argument not valid base64 encoded string" } */ +#embed "embed-18.c" gnu::base64("SA==") /* { dg-error "'gnu::base64' parameter can be only used with \\\".\\\"" } */ +#embed <embed-18.c> gnu::base64("SA==") /* { dg-error "'gnu::base64' parameter can be only used with \\\".\\\"" } */ +#embed <.> gnu::base64("SA==") /* { dg-error "'gnu::base64' parameter can be only used with \\\".\\\"" } */ +#embed "." gnu::base64("SA==") limit(3) /* { dg-error "'gnu::base64' parameter conflicts with 'limit' or 'gnu::offset' parameters" } */ +#embed "." gnu::base64("SA==") gnu::offset(1) /* { dg-error "'gnu::base64' parameter conflicts with 'limit' or 'gnu::offset' parameters" } */ +#if 1 + __has_embed ("." gnu::base64("") __gnu__::__base64__("")) /* { dg-error "duplicate embed parameter 'gnu::base64'" } */ +#endif +#if 1 + __has_embed (__FILE__ __gnu__::__base64__ prefix() suffix()) /* { dg-error "expected '\\\('" } */ +#endif +#if 1 + __has_embed (__FILE__ __gnu__::__base64__(1) prefix() suffix()) /* { dg-error "expected character string literal" } */ +#endif +#if 1 + __has_embed (__FILE__ gnu::base64() prefix() suffix()) /* { dg-error "expected character string literal" } */ +#endif +#if 1 + __has_embed (__FILE__ gnu::base64(L"SA==")) /* { dg-error "expected character string literal" } */ +#endif +#if 1 + __has_embed (__FILE__ gnu::base64(L"S" "A==")) /* { dg-error "expected character string literal" } */ +#endif /* { dg-error "missing '\\\(' in expression" "" { target *-*-* } .-1 } */ +#if 1 + __has_embed (__FILE__ gnu::base64("S" L"A==")) /* { dg-error "expected '\\\)'" } */ +#endif /* { dg-error "missing '\\\(' in expression" "" { target *-*-* } .-1 } */ +#if 1 + __has_embed (__FILE__ gnu::base64(L"S" L"A==")) /* { dg-error "expected character string literal" } */ +#endif /* { dg-error "missing '\\\(' in expression" "" { target *-*-* } .-1 } */ +#if 1 + __has_embed ("." gnu::base64("a")) /* { dg-error "'gnu::base64' argument not valid base64 encoded string" } */ +#endif +#if 1 + __has_embed ("." gnu::base64("----")) /* { dg-error "'gnu::base64' argument not valid base64 encoded string" } */ +#endif +#if 1 + __has_embed ("." gnu::base64("a===")) /* { dg-error "'gnu::base64' argument not valid base64 encoded string" } */ +#endif +#if 1 + __has_embed ("." gnu::base64("TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwg\nc2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWdu\nYSBhbGlxdWEuCg==")) /* { dg-error "'gnu::base64' argument not valid base64 encoded string" } */ +#endif diff --git a/gcc/testsuite/c-c++-common/cpp/embed-19.c b/gcc/testsuite/c-c++-common/cpp/embed-19.c new file mode 100644 index 0000000..a0ce6b2 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/embed-19.c @@ -0,0 +1,5 @@ +/* { dg-do run } */ +/* { dg-options "--embed-dir=${srcdir}/c-c++-common/cpp/embed-dir -save-temps -fdirectives-only" } */ +/* { dg-additional-options "-std=gnu99" { target c } } */ + +#include "embed-1.c" diff --git a/gcc/testsuite/c-c++-common/cpp/embed-27.c b/gcc/testsuite/c-c++-common/cpp/embed-27.c new file mode 100644 index 0000000..2180f58 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/embed-27.c @@ -0,0 +1,64 @@ +/* { dg-do preprocess { target { c || c++11 } } } */ +/* { dg-options "" } */ +/* { dg-additional-options "-std=gnu11" { target c } } */ + +#embed __FILE__ gnu::base64(u"SA==") /* { dg-error "expected character string literal" } */ +#embed __FILE__ gnu::base64(u"S" "A==") /* { dg-error "expected character string literal" } */ +/* { dg-error "expected parameter name" "" { target *-*-* } .-1 } */ +#embed __FILE__ gnu::base64("S" u"A==") /* { dg-error "expected '\\\)'" } */ +/* { dg-error "expected parameter name" "" { target *-*-* } .-1 } */ +#embed __FILE__ gnu::base64(u"S" u"A==") /* { dg-error "expected character string literal" } */ +/* { dg-error "expected parameter name" "" { target *-*-* } .-1 } */ +#embed __FILE__ gnu::base64(U"SA==") /* { dg-error "expected character string literal" } */ +#embed __FILE__ gnu::base64(U"S" "A==") /* { dg-error "expected character string literal" } */ +/* { dg-error "expected parameter name" "" { target *-*-* } .-1 } */ +#embed __FILE__ gnu::base64("S" U"A==") /* { dg-error "expected '\\\)'" } */ +/* { dg-error "expected parameter name" "" { target *-*-* } .-1 } */ +#embed __FILE__ gnu::base64(U"S" U"A==") /* { dg-error "expected character string literal" } */ +/* { dg-error "expected parameter name" "" { target *-*-* } .-1 } */ +#embed __FILE__ gnu::base64(u8"SA==") /* { dg-error "expected character string literal" } */ +#embed __FILE__ gnu::base64(u8"S" "A==") /* { dg-error "expected character string literal" } */ +/* { dg-error "expected parameter name" "" { target *-*-* } .-1 } */ +#embed __FILE__ gnu::base64("S" u8"A==") /* { dg-error "expected '\\\)'" } */ +/* { dg-error "expected parameter name" "" { target *-*-* } .-1 } */ +#embed __FILE__ gnu::base64(u8"S" u8"A==") /* { dg-error "expected character string literal" } */ +/* { dg-error "expected parameter name" "" { target *-*-* } .-1 } */ +#embed "." gnu::base64(R"abc(SA==)abc") /* { dg-error "'gnu::base64' argument not valid base64" } */ +#embed __FILE__ gnu::base64(LR"abc(SA==)abc") /* { dg-error "expected character string literal" } */ +#embed __FILE__ gnu::base64(uR"abc(SA==)abc") /* { dg-error "expected character string literal" } */ +#embed __FILE__ gnu::base64(UR"abc(SA==)abc") /* { dg-error "expected character string literal" } */ +#embed __FILE__ gnu::base64(u8R"abc(SA==)abc") /* { dg-error "expected character string literal" } */ +#if 1 + __has_embed (__FILE__ gnu::base64(u"SA==")) /* { dg-error "expected character string literal" } */ +#endif +#if 1 + __has_embed (__FILE__ gnu::base64(u"S" "A==")) /* { dg-error "expected character string literal" } */ +#endif /* { dg-error "missing '\\\(' in expression" "" { target *-*-* } .-1 } */ +#if 1 + __has_embed (__FILE__ gnu::base64("S" u"A==")) /* { dg-error "expected '\\\)'" } */ +#endif /* { dg-error "missing '\\\(' in expression" "" { target *-*-* } .-1 } */ +#if 1 + __has_embed (__FILE__ gnu::base64(u"S" u"A==")) /* { dg-error "expected character string literal" } */ +#endif /* { dg-error "missing '\\\(' in expression" "" { target *-*-* } .-1 } */ +#if 1 + __has_embed (__FILE__ gnu::base64(U"SA==")) /* { dg-error "expected character string literal" } */ +#endif +#if 1 + __has_embed (__FILE__ gnu::base64(U"S" "A==")) /* { dg-error "expected character string literal" } */ +#endif /* { dg-error "missing '\\\(' in expression" "" { target *-*-* } .-1 } */ +#if 1 + __has_embed (__FILE__ gnu::base64("S" U"A==")) /* { dg-error "expected '\\\)'" } */ +#endif /* { dg-error "missing '\\\(' in expression" "" { target *-*-* } .-1 } */ +#if 1 + __has_embed (__FILE__ gnu::base64(U"S" U"A==")) /* { dg-error "expected character string literal" } */ +#endif /* { dg-error "missing '\\\(' in expression" "" { target *-*-* } .-1 } */ +#if 1 + __has_embed (__FILE__ gnu::base64(u8"SA==")) /* { dg-error "expected character string literal" } */ +#endif +#if 1 + __has_embed (__FILE__ gnu::base64(u8"S" "A==")) /* { dg-error "expected character string literal" } */ +#endif /* { dg-error "missing '\\\(' in expression" "" { target *-*-* } .-1 } */ +#if 1 + __has_embed (__FILE__ gnu::base64("S" u8"A==")) /* { dg-error "expected '\\\)'" } */ +#endif /* { dg-error "missing '\\\(' in expression" "" { target *-*-* } .-1 } */ +#if 1 + __has_embed (__FILE__ gnu::base64(u8"S" u8"A==")) /* { dg-error "expected character string literal" } */ +#endif /* { dg-error "missing '\\\(' in expression" "" { target *-*-* } .-1 } */ +#if 1 + __has_embed ("." gnu::base64(R"abc(SA==)abc")) /* { dg-error "'gnu::base64' argument not valid base64" } */ +#endif +#if 1 + __has_embed (__FILE__ gnu::base64(LR"abc(SA==)abc")) /* { dg-error "expected character string literal" } */ +#endif +#if 1 + __has_embed (__FILE__ gnu::base64(uR"abc(SA==)abc")) /* { dg-error "expected character string literal" } */ +#endif +#if 1 + __has_embed (__FILE__ gnu::base64(UR"abc(SA==)abc")) /* { dg-error "expected character string literal" } */ +#endif +#if 1 + __has_embed (__FILE__ gnu::base64(u8R"abc(SA==)abc")) /* { dg-error "expected character string literal" } */ +#endif diff --git a/gcc/testsuite/gcc.dg/cpp/embed-6.c b/gcc/testsuite/gcc.dg/cpp/embed-6.c new file mode 100644 index 0000000..a0ca31b --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/embed-6.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-fpreprocessed" } */ + +const unsigned char c[] = { +#embed "embed-6.c" limit (64) /* { dg-error "'gnu::base64' parameter required in preprocessed source" } */ +}; diff --git a/gcc/testsuite/gcc.dg/cpp/embed-7.c b/gcc/testsuite/gcc.dg/cpp/embed-7.c new file mode 100644 index 0000000..373e3dd --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/embed-7.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-fpreprocessed -fdirectives-only" } */ + +const unsigned char c[] = { +#embed "embed-7.c" limit (64) /* { dg-error "'gnu::base64' parameter required in preprocessed source" } */ +}; |