218 lines · c
1// RUN: %clang_cc1 -verify -fsyntax-only --embed-dir=%S/Inputs -std=c2x %s -Wno-constant-logical-operand2// RUN: %clang_cc1 -verify -fsyntax-only --embed-dir=%S/Inputs -std=c2x %s -Wno-constant-logical-operand -fexperimental-new-constant-interpreter3 4/* WG14 N3017: full5 * #embed - a scannable, tooling-friendly binary resource inclusion mechanism6 */7 8// C23 6.10p69char b1[] = {10#embed "boop.h" limit(5)11,12#embed "boop.h" __limit__(5)13};14 15// C23 6.10.1p1916#if __has_embed(__FILE__ ext::token(0xB055))17#error "Supports an extension parameter Clang never claimed to support?"18#endif19 20#if !__has_embed(__FILE__ clang::offset(0))21#error "Doesn't support an extension Clang claims to support?"22#endif23 24// C23 6.10.1p2025void parse_into_s(short* ptr, unsigned char* ptr_bytes, unsigned long long size);26int f() {27#if __has_embed ("bits.bin" ds9000::element_type(short))28 /* Implementation extension: create short integers from the */29 /* translation environment resource into */30 /* a sequence of integer constants */31 short meow[] = {32#embed "bits.bin" ds9000::element_type(short)33 };34#elif __has_embed ("bits.bin")35 /* no support for implementation-specific */36 /* ds9000::element_type(short) parameter */37 unsigned char meow_bytes[] = {38 #embed "bits.bin"39 };40 short meow[sizeof(meow_bytes) / sizeof(short)] = {};41 /* parse meow_bytes into short values by-hand! */42 parse_into_s(meow, meow_bytes, sizeof(meow_bytes));43#else44#error "cannot find bits.bin resource"45#endif46 return (int)(meow[0] + meow[(sizeof(meow) / sizeof(*meow)) - 1]);47}48 49// NOTE: we don't have a good way to test infinite resources from within lit.50int g() {51#if __has_embed(<infinite-resource> limit(0)) == 252 // if <infinite-resource> exists, this53 // token sequence is always taken.54 return 0;55#else56 // the �infinite-resource� resource does not exist57 #error "The resource does not exist"58#endif59 // expected-error@-2 {{"The resource does not exist"}}60}61 62#include <stddef.h>63void have_you_any_wool(const unsigned char*, size_t);64int h() {65 static const unsigned char baa_baa[] = {66#embed __FILE__67 };68 have_you_any_wool(baa_baa, sizeof(baa_baa));69 return 0;70}71 72// C23 6.10.3.1p17: not tested here because we do not currently support any73// platforms where CHAR_BIT != 8.74 75// C23 6.10.3.1p1876int i() {77/* Braces may be kept or elided as per normal initialization rules */78 int i = {79#embed "i.dat"80 }; /* valid if i.dat produces 1 value,81 i value is [0, 2(embed element width)) */82 int i2 =83#embed "i.dat"84 ; /* valid if i.dat produces 1 value,85 i2 value is [0, 2(embed element width)) */86 struct s {87 double a, b, c;88 struct { double e, f, g; };89 double h, i, j;90 };91 struct s x = {92 /* initializes each element in order according to initialization93 rules with comma-separated list of integer constant expressions94 inside of braces */95 #embed "s.dat"96 };97 return 0;98}99 100// C23 6.10.3.1p19: not tested here because it's a runtime test rather than one101// which can be handled at compile time (it validates file contents via fread).102 103// C23 6.10.3.2p5104int j() {105 static const char sound_signature[] = {106#embed <jump.wav> limit(2+2)107 };108 static_assert((sizeof(sound_signature) / sizeof(*sound_signature)) == 4,109 "There should only be 4 elements in this array.");110 // verify PCM WAV resource111 static_assert(sound_signature[0] == 'R');112 static_assert(sound_signature[1] == 'I');113 static_assert(sound_signature[2] == 'F');114 static_assert(sound_signature[3] == 'F');115 static_assert(sizeof(sound_signature) == 4);116 return 0;117}118 119// C23 6.10.3p6120int k() {121#define TWO_PLUS_TWO 2+2122 static const char sound_signature[] = {123#embed <jump.wav> limit(TWO_PLUS_TWO)124 };125 static_assert((sizeof(sound_signature) / sizeof(*sound_signature)) == 4,126 "There should only be 4 elements in this array.");127 // verify PCM WAV resource128 static_assert(sound_signature[0] == 'R');129 static_assert(sound_signature[1] == 'I');130 static_assert(sound_signature[2] == 'F');131 static_assert(sound_signature[3] == 'F');132 static_assert(sizeof(sound_signature) == 4);133 return 0;134}135 136// C23 6.10.3.2p7: not tested here because we do not currently support any137// platforms where CHAR_BIT != 8.138 139// C23 6.10.3.2p8: not tested here because it requires access to an infinite140// resource like /dev/urandom.141 142// C23 6.10.3.3p4143char *strcpy(char *, const char *);144#ifndef SHADER_TARGET145 #define SHADER_TARGET "bits.bin"146#endif147extern char* null_term_shader_data;148void fill_in_data () {149 const char internal_data[] = {150#embed SHADER_TARGET \151 suffix(,)152 0153 };154 strcpy(null_term_shader_data, internal_data);155}156 157// C23 6.10.3.4p4158#ifndef SHADER_TARGET159#define SHADER_TARGET "bits.bin"160#endif161extern char* merp;162void init_data () {163 const char whl[] = {164#embed SHADER_TARGET \165 prefix(0xEF, 0xBB, 0xBF, ) /* UTF-8 BOM */ \166 suffix(,)167 0168 };169 // always null terminated,170 // contains BOM if not-empty171 const int is_good = (sizeof(whl) == 1 && whl[0] == '\0')172 || (whl[0] == '\xEF' && whl[1] == '\xBB'173 && whl[2] == '\xBF' && whl[sizeof(whl) - 1] == '\0');174 static_assert(is_good);175 strcpy(merp, whl);176}177 178// C23 6.10.3.5p3179int l() {180 return181#embed <bits.bin> limit(0) prefix(1) if_empty(0)182 ;183 // becomes:184 // return 0;185 186 // Validating the assumption from the example in the standard.187 static_assert(188#embed <bits.bin> limit(0) prefix(1) if_empty(0)189 == 0);190}191 192// C23 6.10.3.5p4193void fill_in_data_again() {194 const char internal_data[] = {195#embed SHADER_TARGET \196 suffix(, 0) \197 if_empty(0)198 };199 strcpy(null_term_shader_data, internal_data);200}201 202// C23 6.10.3.5p5203int m() {204 return205#embed __FILE__ limit(0) if_empty(45540)206 ;207 208 // Validating the assumption from the example in the standard.209 static_assert(210#embed __FILE__ limit(0) if_empty(45540)211 == 45540);212}213 214// 6.10.9.1p1215static_assert(__STDC_EMBED_NOT_FOUND__ == 0);216static_assert(__STDC_EMBED_FOUND__ == 1);217static_assert(__STDC_EMBED_EMPTY__ == 2);218