mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Deprecated '&' macro arguments.
This commit is contained in:
@@ -26,24 +26,25 @@ def VoidFn = fn void();
|
||||
Stores a variable on the stack, then restores it at the end of the
|
||||
macro scope.
|
||||
|
||||
@param variable `the variable to store and restore`
|
||||
@param #variable `the variable to store and restore`
|
||||
@require values::@is_lvalue(#variable)
|
||||
*>
|
||||
macro void @scope(&variable; @body) @builtin
|
||||
macro void @scope(#variable; @body) @builtin
|
||||
{
|
||||
var temp = *variable;
|
||||
defer *variable = temp;
|
||||
var temp = #variable;
|
||||
defer #variable = temp;
|
||||
@body();
|
||||
}
|
||||
|
||||
<*
|
||||
Swap two variables
|
||||
@require $assignable(*b, $typeof(*a)) && $assignable(*a, $typeof(*b))
|
||||
@require $defined(#a = #b, #b = #a) `The values must be mutually assignable`
|
||||
*>
|
||||
macro void @swap(&a, &b) @builtin
|
||||
macro void @swap(#a, #b) @builtin
|
||||
{
|
||||
var temp = *a;
|
||||
*a = *b;
|
||||
*b = temp;
|
||||
var temp = #a;
|
||||
#a = #b;
|
||||
#b = temp;
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -366,9 +367,12 @@ macro bool @ok(#expr) @builtin
|
||||
return true;
|
||||
}
|
||||
|
||||
macro char[] @as_char_view(&value) @builtin
|
||||
<*
|
||||
@require $defined(&#value, (char*)&#value) "This must be a value that can be viewed as a char array"
|
||||
*>
|
||||
macro char[] @as_char_view(#value) @builtin
|
||||
{
|
||||
return ((char*)value)[:$sizeof(*value)];
|
||||
return ((char*)&#value)[:$sizeof(#value)];
|
||||
}
|
||||
|
||||
macro isz @str_find(String $string, String $needle) @builtin => $$str_find($string, $needle);
|
||||
|
||||
@@ -162,42 +162,55 @@ macro @scatter_aligned(ptrvec, value, bool[<*>] mask, usz $alignment)
|
||||
}
|
||||
|
||||
<*
|
||||
@param [in] x "The variable or dereferenced pointer to load."
|
||||
@param #x "The variable or dereferenced pointer to load."
|
||||
@param $alignment "The alignment to assume for the load"
|
||||
@return "The value of x"
|
||||
@return "The value of the variable"
|
||||
|
||||
@require @constant_is_power_of_2($alignment) : "The alignment must be a power of two"
|
||||
@require $defined(&#x) : "This must be a variable or dereferenced pointer"
|
||||
*>
|
||||
macro @unaligned_load(&x, usz $alignment) @builtin
|
||||
macro @unaligned_load(#x, usz $alignment) @builtin
|
||||
{
|
||||
return $$unaligned_load(x, $alignment);
|
||||
return $$unaligned_load(&#x, $alignment);
|
||||
}
|
||||
|
||||
<*
|
||||
@param [out] x "The variable or dereferenced pointer to store to."
|
||||
@param #x "The variable or dereferenced pointer to store to."
|
||||
@param value "The value to store."
|
||||
@param $alignment "The alignment to assume for the store"
|
||||
@return "The value of x"
|
||||
@return "The value stored"
|
||||
|
||||
@require $assignable(value, $typeof(*x)) : "The value doesn't match the variable"
|
||||
@require $defined(&#x) : "This must be a variable or dereferenced pointer"
|
||||
@require $defined(#x = value) : "The value doesn't match the variable"
|
||||
@require @constant_is_power_of_2($alignment) : "The alignment must be a power of two"
|
||||
*>
|
||||
macro @unaligned_store(&x, value, usz $alignment) @builtin
|
||||
macro @unaligned_store(#x, value, usz $alignment) @builtin
|
||||
{
|
||||
return $$unaligned_store(x, ($typeof(*x))value, $alignment);
|
||||
}
|
||||
|
||||
macro @volatile_load(&x) @builtin
|
||||
{
|
||||
return $$volatile_load(x);
|
||||
return $$unaligned_store(&#x, ($typeof(#x))value, $alignment);
|
||||
}
|
||||
|
||||
<*
|
||||
@require $assignable(y, $typeof(*x)) : "The value doesn't match the variable"
|
||||
@param #x "The variable or dereferenced pointer to load."
|
||||
@return "The value of the variable"
|
||||
|
||||
@require $defined(&#x) : "This must be a variable or dereferenced pointer"
|
||||
*>
|
||||
macro @volatile_store(&x, y) @builtin
|
||||
macro @volatile_load(#x) @builtin
|
||||
{
|
||||
return $$volatile_store(x, ($typeof(*x))y);
|
||||
return $$volatile_load(&#x);
|
||||
}
|
||||
|
||||
<*
|
||||
@param #x "The variable or dereferenced pointer to store to."
|
||||
@param value "The value to store."
|
||||
@return "The value stored"
|
||||
|
||||
@require $defined(&#x) : "This must be a variable or dereferenced pointer"
|
||||
@require $defined(#x = value) : "The value doesn't match the variable"
|
||||
*>
|
||||
macro @volatile_store(#x, value) @builtin
|
||||
{
|
||||
return $$volatile_store(&#x, ($typeof(#x))value);
|
||||
}
|
||||
|
||||
enum AtomicOrdering : int
|
||||
@@ -212,34 +225,36 @@ enum AtomicOrdering : int
|
||||
}
|
||||
|
||||
<*
|
||||
@param [in] x "the variable or dereferenced pointer to load."
|
||||
@param #x "the variable or dereferenced pointer to load."
|
||||
@param $ordering "atomic ordering of the load, defaults to SEQ_CONSISTENT"
|
||||
@param $volatile "whether the load should be volatile, defaults to 'false'"
|
||||
@return "returns the value of x"
|
||||
|
||||
@require $defined(&#x) : "This must be a variable or dereferenced pointer"
|
||||
@require $ordering != AtomicOrdering.RELEASE "Release ordering is not valid for load."
|
||||
@require $ordering != AtomicOrdering.ACQUIRE_RELEASE "Acquire release is not valid for load."
|
||||
@require types::may_load_atomic($typeof(x)) "Only integer, float and pointers may be used."
|
||||
@require @typekind(x) == POINTER "You can only load from a pointer"
|
||||
@require types::may_load_atomic($typeof(#x)) "Only integer, float and pointers may be used."
|
||||
*>
|
||||
macro @atomic_load(&x, AtomicOrdering $ordering = SEQ_CONSISTENT, $volatile = false) @builtin
|
||||
macro @atomic_load(#x, AtomicOrdering $ordering = SEQ_CONSISTENT, $volatile = false) @builtin
|
||||
{
|
||||
return $$atomic_load(x, $volatile, $ordering.ordinal);
|
||||
return $$atomic_load(&#x, $volatile, $ordering.ordinal);
|
||||
}
|
||||
|
||||
<*
|
||||
@param [out] x "the variable or dereferenced pointer to store to."
|
||||
@param #x "the variable or dereferenced pointer to store to."
|
||||
@param value "the value to store."
|
||||
@param $ordering "the atomic ordering of the store, defaults to SEQ_CONSISTENT"
|
||||
@param $volatile "whether the store should be volatile, defaults to 'false'"
|
||||
|
||||
@require $ordering != AtomicOrdering.ACQUIRE "Acquire ordering is not valid for store."
|
||||
@require $ordering != AtomicOrdering.ACQUIRE_RELEASE "Acquire release is not valid for store."
|
||||
@require types::may_load_atomic($typeof(x)) "Only integer, float and pointers may be used."
|
||||
@require types::may_load_atomic($typeof(#x)) "Only integer, float and pointers may be used."
|
||||
@require $defined(&#x) : "This must be a variable or dereferenced pointer"
|
||||
@require $defined(#x = value) : "The value doesn't match the variable"
|
||||
*>
|
||||
macro void @atomic_store(&x, value, AtomicOrdering $ordering = SEQ_CONSISTENT, $volatile = false) @builtin
|
||||
macro void @atomic_store(#x, value, AtomicOrdering $ordering = SEQ_CONSISTENT, $volatile = false) @builtin
|
||||
{
|
||||
$$atomic_store(x, value, $volatile, $ordering.ordinal);
|
||||
$$atomic_store(&#x, value, $volatile, $ordering.ordinal);
|
||||
}
|
||||
|
||||
<*
|
||||
|
||||
@@ -16,6 +16,7 @@ macro bool @is_promotable_to_float(#value) @const => types::is_promotable_to_flo
|
||||
macro bool @is_vector(#value) @const => types::is_vector($typeof(#value));
|
||||
macro bool @is_same_vector_type(#value1, #value2) @const => types::is_same_vector_type($typeof(#value1), $typeof(#value2));
|
||||
macro bool @assign_to(#value1, #value2) @const => $assignable(#value1, $typeof(#value2));
|
||||
macro bool @is_lvalue(#value) => $defined(#value = #value);
|
||||
|
||||
macro promote_int(x)
|
||||
{
|
||||
|
||||
@@ -106,7 +106,7 @@ macro @h(x, y, z) => (x ^ y) ^ z;
|
||||
macro @h2(x, y, z) => x ^ (y ^ z);
|
||||
macro @i(x, y, z) => y ^ (x | ~z);
|
||||
|
||||
macro @step(#f, &a, b, c, d, ptr, n, t, s)
|
||||
macro @step(#f, a, b, c, d, ptr, n, t, s)
|
||||
{
|
||||
*a += #f(b, c, d) + *(uint *)&ptr[n * 4] + t;
|
||||
*a = (*a << s) | ((*a & 0xffffffff) >> (32 - s));
|
||||
@@ -133,76 +133,76 @@ fn char* body(Md5* ctx, void* data, usz size)
|
||||
saved_d = d;
|
||||
|
||||
/* Round 1 */
|
||||
@step(@f, a, b, c, d, ptr, 0, 0xd76aa478, 7) ;
|
||||
@step(@f, d, a, b, c, ptr, 1, 0xe8c7b756, 12) ;
|
||||
@step(@f, c, d, a, b, ptr, 2, 0x242070db, 17) ;
|
||||
@step(@f, b, c, d, a, ptr, 3, 0xc1bdceee, 22) ;
|
||||
@step(@f, a, b, c, d, ptr, 4, 0xf57c0faf, 7) ;
|
||||
@step(@f, d, a, b, c, ptr, 5, 0x4787c62a, 12) ;
|
||||
@step(@f, c, d, a, b, ptr, 6, 0xa8304613, 17) ;
|
||||
@step(@f, b, c, d, a, ptr, 7, 0xfd469501, 22) ;
|
||||
@step(@f, a, b, c, d, ptr, 8, 0x698098d8, 7) ;
|
||||
@step(@f, d, a, b, c, ptr, 9, 0x8b44f7af, 12) ;
|
||||
@step(@f, c, d, a, b, ptr, 10, 0xffff5bb1, 17);
|
||||
@step(@f, b, c, d, a, ptr, 11, 0x895cd7be, 22);
|
||||
@step(@f, a, b, c, d, ptr, 12, 0x6b901122, 7) ;
|
||||
@step(@f, d, a, b, c, ptr, 13, 0xfd987193, 12);
|
||||
@step(@f, c, d, a, b, ptr, 14, 0xa679438e, 17);
|
||||
@step(@f, b, c, d, a, ptr, 15, 0x49b40821, 22);
|
||||
@step(@f, &a, b, c, d, ptr, 0, 0xd76aa478, 7) ;
|
||||
@step(@f, &d, a, b, c, ptr, 1, 0xe8c7b756, 12) ;
|
||||
@step(@f, &c, d, a, b, ptr, 2, 0x242070db, 17) ;
|
||||
@step(@f, &b, c, d, a, ptr, 3, 0xc1bdceee, 22) ;
|
||||
@step(@f, &a, b, c, d, ptr, 4, 0xf57c0faf, 7) ;
|
||||
@step(@f, &d, a, b, c, ptr, 5, 0x4787c62a, 12) ;
|
||||
@step(@f, &c, d, a, b, ptr, 6, 0xa8304613, 17) ;
|
||||
@step(@f, &b, c, d, a, ptr, 7, 0xfd469501, 22) ;
|
||||
@step(@f, &a, b, c, d, ptr, 8, 0x698098d8, 7) ;
|
||||
@step(@f, &d, a, b, c, ptr, 9, 0x8b44f7af, 12) ;
|
||||
@step(@f, &c, d, a, b, ptr, 10, 0xffff5bb1, 17);
|
||||
@step(@f, &b, c, d, a, ptr, 11, 0x895cd7be, 22);
|
||||
@step(@f, &a, b, c, d, ptr, 12, 0x6b901122, 7) ;
|
||||
@step(@f, &d, a, b, c, ptr, 13, 0xfd987193, 12);
|
||||
@step(@f, &c, d, a, b, ptr, 14, 0xa679438e, 17);
|
||||
@step(@f, &b, c, d, a, ptr, 15, 0x49b40821, 22);
|
||||
|
||||
/* Round 2 */
|
||||
@step(@g, a, b, c, d, ptr, 1, 0xf61e2562, 5) ;
|
||||
@step(@g, d, a, b, c, ptr, 6, 0xc040b340, 9) ;
|
||||
@step(@g, c, d, a, b, ptr, 11, 0x265e5a51, 14);
|
||||
@step(@g, b, c, d, a, ptr, 0, 0xe9b6c7aa, 20) ;
|
||||
@step(@g, a, b, c, d, ptr, 5, 0xd62f105d, 5) ;
|
||||
@step(@g, d, a, b, c, ptr, 10, 0x02441453, 9) ;
|
||||
@step(@g, c, d, a, b, ptr, 15, 0xd8a1e681, 14);
|
||||
@step(@g, b, c, d, a, ptr, 4, 0xe7d3fbc8, 20) ;
|
||||
@step(@g, a, b, c, d, ptr, 9, 0x21e1cde6, 5) ;
|
||||
@step(@g, d, a, b, c, ptr, 14, 0xc33707d6, 9) ;
|
||||
@step(@g, c, d, a, b, ptr, 3, 0xf4d50d87, 14) ;
|
||||
@step(@g, b, c, d, a, ptr, 8, 0x455a14ed, 20) ;
|
||||
@step(@g, a, b, c, d, ptr, 13, 0xa9e3e905, 5) ;
|
||||
@step(@g, d, a, b, c, ptr, 2, 0xfcefa3f8, 9) ;
|
||||
@step(@g, c, d, a, b, ptr, 7, 0x676f02d9, 14) ;
|
||||
@step(@g, b, c, d, a, ptr, 12, 0x8d2a4c8a, 20);
|
||||
@step(@g, &a, b, c, d, ptr, 1, 0xf61e2562, 5) ;
|
||||
@step(@g, &d, a, b, c, ptr, 6, 0xc040b340, 9) ;
|
||||
@step(@g, &c, d, a, b, ptr, 11, 0x265e5a51, 14);
|
||||
@step(@g, &b, c, d, a, ptr, 0, 0xe9b6c7aa, 20) ;
|
||||
@step(@g, &a, b, c, d, ptr, 5, 0xd62f105d, 5) ;
|
||||
@step(@g, &d, a, b, c, ptr, 10, 0x02441453, 9) ;
|
||||
@step(@g, &c, d, a, b, ptr, 15, 0xd8a1e681, 14);
|
||||
@step(@g, &b, c, d, a, ptr, 4, 0xe7d3fbc8, 20) ;
|
||||
@step(@g, &a, b, c, d, ptr, 9, 0x21e1cde6, 5) ;
|
||||
@step(@g, &d, a, b, c, ptr, 14, 0xc33707d6, 9) ;
|
||||
@step(@g, &c, d, a, b, ptr, 3, 0xf4d50d87, 14) ;
|
||||
@step(@g, &b, c, d, a, ptr, 8, 0x455a14ed, 20) ;
|
||||
@step(@g, &a, b, c, d, ptr, 13, 0xa9e3e905, 5) ;
|
||||
@step(@g, &d, a, b, c, ptr, 2, 0xfcefa3f8, 9) ;
|
||||
@step(@g, &c, d, a, b, ptr, 7, 0x676f02d9, 14) ;
|
||||
@step(@g, &b, c, d, a, ptr, 12, 0x8d2a4c8a, 20);
|
||||
|
||||
/* Round 3 */
|
||||
@step(@h, a, b, c, d, ptr, 5, 0xfffa3942, 4);
|
||||
@step(@h2, d, a, b, c, ptr, 8, 0x8771f681, 11);
|
||||
@step(@h, c, d, a, b, ptr, 11, 0x6d9d6122, 16);
|
||||
@step(@h2, b, c, d, a, ptr, 14, 0xfde5380c, 23);
|
||||
@step(@h, a, b, c, d, ptr, 1, 0xa4beea44, 4);
|
||||
@step(@h2, d, a, b, c, ptr, 4, 0x4bdecfa9, 11);
|
||||
@step(@h, c, d, a, b, ptr, 7, 0xf6bb4b60, 16);
|
||||
@step(@h2, b, c, d, a, ptr, 10, 0xbebfbc70, 23);
|
||||
@step(@h, a, b, c, d, ptr, 13, 0x289b7ec6, 4) ;
|
||||
@step(@h2, d, a, b, c, ptr, 0, 0xeaa127fa, 11) ;
|
||||
@step(@h, c, d, a, b, ptr, 3, 0xd4ef3085, 16) ;
|
||||
@step(@h2, b, c, d, a, ptr, 6, 0x04881d05, 23) ;
|
||||
@step(@h, a, b, c, d, ptr, 9, 0xd9d4d039, 4) ;
|
||||
@step(@h2, d, a, b, c, ptr, 12, 0xe6db99e5, 11) ;
|
||||
@step(@h, c, d, a, b, ptr, 15, 0x1fa27cf8, 16) ;
|
||||
@step(@h2, b, c, d, a, ptr, 2, 0xc4ac5665, 23) ;
|
||||
@step(@h, &a, b, c, d, ptr, 5, 0xfffa3942, 4);
|
||||
@step(@h2, &d, a, b, c, ptr, 8, 0x8771f681, 11);
|
||||
@step(@h, &c, d, a, b, ptr, 11, 0x6d9d6122, 16);
|
||||
@step(@h2, &b, c, d, a, ptr, 14, 0xfde5380c, 23);
|
||||
@step(@h, &a, b, c, d, ptr, 1, 0xa4beea44, 4);
|
||||
@step(@h2, &d, a, b, c, ptr, 4, 0x4bdecfa9, 11);
|
||||
@step(@h, &c, d, a, b, ptr, 7, 0xf6bb4b60, 16);
|
||||
@step(@h2, &b, c, d, a, ptr, 10, 0xbebfbc70, 23);
|
||||
@step(@h, &a, b, c, d, ptr, 13, 0x289b7ec6, 4) ;
|
||||
@step(@h2, &d, a, b, c, ptr, 0, 0xeaa127fa, 11) ;
|
||||
@step(@h, &c, d, a, b, ptr, 3, 0xd4ef3085, 16) ;
|
||||
@step(@h2, &b, c, d, a, ptr, 6, 0x04881d05, 23) ;
|
||||
@step(@h, &a, b, c, d, ptr, 9, 0xd9d4d039, 4) ;
|
||||
@step(@h2, &d, a, b, c, ptr, 12, 0xe6db99e5, 11) ;
|
||||
@step(@h, &c, d, a, b, ptr, 15, 0x1fa27cf8, 16) ;
|
||||
@step(@h2, &b, c, d, a, ptr, 2, 0xc4ac5665, 23) ;
|
||||
|
||||
/* Round 4 */
|
||||
@step(@i, a, b, c, d, ptr, 0, 0xf4292244, 6) ;
|
||||
@step(@i, d, a, b, c, ptr, 7, 0x432aff97, 10) ;
|
||||
@step(@i, c, d, a, b, ptr, 14, 0xab9423a7, 15) ;
|
||||
@step(@i, b, c, d, a, ptr, 5, 0xfc93a039, 21) ;
|
||||
@step(@i, a, b, c, d, ptr, 12, 0x655b59c3, 6) ;
|
||||
@step(@i, d, a, b, c, ptr, 3, 0x8f0ccc92, 10) ;
|
||||
@step(@i, c, d, a, b, ptr, 10, 0xffeff47d, 15) ;
|
||||
@step(@i, b, c, d, a, ptr, 1, 0x85845dd1, 21) ;
|
||||
@step(@i, a, b, c, d, ptr, 8, 0x6fa87e4f, 6) ;
|
||||
@step(@i, d, a, b, c, ptr, 15, 0xfe2ce6e0, 10) ;
|
||||
@step(@i, c, d, a, b, ptr, 6, 0xa3014314, 15) ;
|
||||
@step(@i, b, c, d, a, ptr, 13, 0x4e0811a1, 21) ;
|
||||
@step(@i, a, b, c, d, ptr, 4, 0xf7537e82, 6) ;
|
||||
@step(@i, d, a, b, c, ptr, 11, 0xbd3af235, 10) ;
|
||||
@step(@i, c, d, a, b, ptr, 2, 0x2ad7d2bb, 15) ;
|
||||
@step(@i, b, c, d, a, ptr, 9, 0xeb86d391, 21) ;
|
||||
@step(@i, &a, b, c, d, ptr, 0, 0xf4292244, 6) ;
|
||||
@step(@i, &d, a, b, c, ptr, 7, 0x432aff97, 10) ;
|
||||
@step(@i, &c, d, a, b, ptr, 14, 0xab9423a7, 15) ;
|
||||
@step(@i, &b, c, d, a, ptr, 5, 0xfc93a039, 21) ;
|
||||
@step(@i, &a, b, c, d, ptr, 12, 0x655b59c3, 6) ;
|
||||
@step(@i, &d, a, b, c, ptr, 3, 0x8f0ccc92, 10) ;
|
||||
@step(@i, &c, d, a, b, ptr, 10, 0xffeff47d, 15) ;
|
||||
@step(@i, &b, c, d, a, ptr, 1, 0x85845dd1, 21) ;
|
||||
@step(@i, &a, b, c, d, ptr, 8, 0x6fa87e4f, 6) ;
|
||||
@step(@i, &d, a, b, c, ptr, 15, 0xfe2ce6e0, 10) ;
|
||||
@step(@i, &c, d, a, b, ptr, 6, 0xa3014314, 15) ;
|
||||
@step(@i, &b, c, d, a, ptr, 13, 0x4e0811a1, 21) ;
|
||||
@step(@i, &a, b, c, d, ptr, 4, 0xf7537e82, 6) ;
|
||||
@step(@i, &d, a, b, c, ptr, 11, 0xbd3af235, 10) ;
|
||||
@step(@i, &c, d, a, b, ptr, 2, 0x2ad7d2bb, 15) ;
|
||||
@step(@i, &b, c, d, a, ptr, 9, 0xeb86d391, 21) ;
|
||||
|
||||
a += saved_a;
|
||||
b += saved_b;
|
||||
|
||||
@@ -104,7 +104,7 @@ macro usz! write_all(stream, char[] buffer)
|
||||
return n;
|
||||
}
|
||||
|
||||
macro usz! @read_using_read_byte(&s, char[] buffer)
|
||||
macro usz! @read_using_read_byte(&s, char[] buffer) @deprecated
|
||||
{
|
||||
return read_using_read_byte(*s, buffer);
|
||||
}
|
||||
@@ -137,7 +137,7 @@ macro void! @write_byte_using_write(&s, char c) @deprecated
|
||||
return write_byte_using_write(*s, c);
|
||||
}
|
||||
|
||||
macro char! @read_byte_using_read(&s)
|
||||
macro char! @read_byte_using_read(&s) @deprecated
|
||||
{
|
||||
return read_byte_using_read(*s);
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ $endif
|
||||
return (usz)n;
|
||||
}
|
||||
|
||||
fn char! Socket.read_byte(&self) @dynamic => io::@read_byte_using_read(self);
|
||||
fn char! Socket.read_byte(&self) @dynamic => io::read_byte_using_read(self);
|
||||
|
||||
fn usz! Socket.write(&self, char[] bytes) @dynamic
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
- Include `@name` when searching for possible matches to `name` in the error message. #1779
|
||||
- Improve `@param` parse errors #1777
|
||||
- Improved `#foo` resolution inside of the compiler.
|
||||
- Deprecated '&' macro arguments.
|
||||
|
||||
### Fixes
|
||||
- Fix case trying to initialize a `char[*]*` from a String.
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
module test;
|
||||
import libc;
|
||||
import std::io;
|
||||
|
||||
<*
|
||||
@require values::@assign_to(*b, *a) && values::@assign_to(*a, *b)
|
||||
@require $defined(#a = #b, #b = #a)
|
||||
*>
|
||||
macro void @swap(&a, &b)
|
||||
macro void @swap(#a, #b)
|
||||
{
|
||||
var temp = *a;
|
||||
*a = *b;
|
||||
*b = temp;
|
||||
var temp = #a;
|
||||
#a = #b;
|
||||
#b = temp;
|
||||
}
|
||||
|
||||
fn void main()
|
||||
@@ -16,5 +16,5 @@ fn void main()
|
||||
int x = 123;
|
||||
int y = 456;
|
||||
@swap(x, y);
|
||||
libc::printf("x: %d y: %d\n", x, y);
|
||||
io::printfn("x: %d y: %d", x, y);
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
static inline bool sema_analyse_func_macro(SemaContext *context, Decl *decl, AttributeDomain domain, bool *erase_decl);
|
||||
static inline bool sema_analyse_func(SemaContext *context, Decl *decl, bool *erase_decl);
|
||||
static inline bool sema_analyse_macro(SemaContext *context, Decl *decl, bool *erase_decl);
|
||||
static inline bool sema_analyse_signature(SemaContext *context, Signature *sig, TypeInfo *method_parent, bool is_export);
|
||||
static inline bool sema_analyse_signature(SemaContext *context, Signature *sig, TypeInfo *method_parent, bool is_export, bool is_deprecated);
|
||||
static inline bool sema_analyse_main_function(SemaContext *context, Decl *decl);
|
||||
static inline bool sema_check_param_uniqueness_and_type(SemaContext *context, Decl **decls, Decl *current,
|
||||
unsigned current_index, unsigned count);
|
||||
@@ -1085,7 +1085,7 @@ ERROR:
|
||||
return decl_poison(decl);
|
||||
}
|
||||
|
||||
static inline bool sema_analyse_signature(SemaContext *context, Signature *sig, TypeInfo *method_parent, bool is_export)
|
||||
static inline bool sema_analyse_signature(SemaContext *context, Signature *sig, TypeInfo *method_parent, bool is_export, bool is_deprecated)
|
||||
{
|
||||
Variadic variadic_type = sig->variadic;
|
||||
Decl **params = sig->params;
|
||||
@@ -1149,7 +1149,7 @@ static inline bool sema_analyse_signature(SemaContext *context, Signature *sig,
|
||||
case VARDECL_PARAM_REF:
|
||||
inferred_type = type_get_ptr(method_parent->type);
|
||||
param->var.not_null = true;
|
||||
if (!is_macro) param->var.kind = VARDECL_PARAM;
|
||||
param->var.kind = VARDECL_PARAM;
|
||||
break;
|
||||
case VARDECL_PARAM:
|
||||
case VARDECL_PARAM_EXPR:
|
||||
@@ -1224,6 +1224,10 @@ static inline bool sema_analyse_signature(SemaContext *context, Signature *sig,
|
||||
switch (var_kind)
|
||||
{
|
||||
case VARDECL_PARAM_REF:
|
||||
if ((i != 0 || !method_parent) && !is_deprecated)
|
||||
{
|
||||
SEMA_DEPRECATED(param, "Reference macro arguments are deprecated.");
|
||||
}
|
||||
if (type_info && !type_is_pointer(param->type))
|
||||
{
|
||||
SEMA_ERROR(type_info, "A pointer type was expected for a ref argument, did you mean %s?",
|
||||
@@ -1239,7 +1243,7 @@ static inline bool sema_analyse_signature(SemaContext *context, Signature *sig,
|
||||
}
|
||||
if (!is_macro_at_name && (!method_parent || i != 0 || var_kind != VARDECL_PARAM_REF))
|
||||
{
|
||||
SEMA_ERROR(param, "Ref and expression parameters are not allowed in function-like macros. Prefix the macro name with '@'.");
|
||||
SEMA_ERROR(param, "Expression parameters are not allowed in function-like macros. Prefix the macro name with '@'.");
|
||||
return decl_poison(param);
|
||||
}
|
||||
FALLTHROUGH;
|
||||
@@ -1333,7 +1337,9 @@ bool sema_analyse_function_signature(SemaContext *context, Decl *func_decl, Type
|
||||
// Get param count and variadic type
|
||||
Decl **params = signature->params;
|
||||
|
||||
if (!sema_analyse_signature(context, signature, parent, func_decl->is_export)) return false;
|
||||
bool deprecated = func_decl->resolved_attributes && func_decl->attrs_resolved && func_decl->attrs_resolved->deprecated;
|
||||
|
||||
if (!sema_analyse_signature(context, signature, parent, func_decl->is_export, deprecated)) return false;
|
||||
|
||||
Variadic variadic_type = signature->variadic;
|
||||
|
||||
@@ -3696,9 +3702,12 @@ static inline bool sema_analyse_macro(SemaContext *context, Decl *decl, bool *er
|
||||
|
||||
if (!sema_analyse_func_macro(context, decl, ATTR_MACRO, erase_decl)) return false;
|
||||
if (*erase_decl) return true;
|
||||
|
||||
bool deprecated = decl->resolved_attributes && decl->attrs_resolved && decl->attrs_resolved->deprecated;
|
||||
|
||||
if (!sema_analyse_signature(context, &decl->func_decl.signature,
|
||||
type_infoptrzero(decl->func_decl.type_parent),
|
||||
false)) return false;
|
||||
false, deprecated)) return false;
|
||||
|
||||
if (!decl->func_decl.signature.is_at_macro && decl->func_decl.body_param && !decl->func_decl.signature.is_safemacro)
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ static inline bool sema_expr_analyse_slice(SemaContext *context, Expr *expr, Che
|
||||
static inline bool sema_expr_analyse_access(SemaContext *context, Expr *expr, bool *missing_ref, CheckType check);
|
||||
static inline bool sema_expr_analyse_compound_literal(SemaContext *context, Expr *expr);
|
||||
static inline bool sema_expr_analyse_builtin(SemaContext *context, Expr *expr, bool throw_error);
|
||||
static inline bool sema_expr_analyse_binary(SemaContext *context, Expr *expr);
|
||||
static inline bool sema_expr_analyse_binary(SemaContext *context, Expr *expr, bool *failed_ref);
|
||||
static inline bool sema_expr_analyse_ct_eval(SemaContext *context, Expr *expr, CheckType check);
|
||||
static inline bool sema_expr_analyse_identifier(SemaContext *context, Type *to, Expr *expr);
|
||||
static inline bool sema_expr_analyse_ct_identifier(SemaContext *context, Expr *expr, CheckType check);
|
||||
@@ -77,7 +77,7 @@ static bool sema_expr_analyse_add_sub_assign(SemaContext *context, Expr *expr, E
|
||||
static bool sema_expr_analyse_slice_assign(SemaContext *context, Expr *expr, Type *left_type, Expr *right, bool is_unwrapped);
|
||||
static bool sema_expr_analyse_ct_identifier_assign(SemaContext *context, Expr *expr, Expr *left, Expr *right);
|
||||
static bool sema_expr_analyse_ct_type_identifier_assign(SemaContext *context, Expr *expr, Expr *left, Expr *right);
|
||||
static bool sema_expr_analyse_assign(SemaContext *context, Expr *expr, Expr *left, Expr *right);
|
||||
static bool sema_expr_analyse_assign(SemaContext *context, Expr *expr, Expr *left, Expr *right, bool *failed_ref);
|
||||
static bool sema_expr_analyse_comp(SemaContext *context, Expr *expr, Expr *left, Expr *right);
|
||||
static bool sema_expr_analyse_op_assign(SemaContext *context, Expr *expr, Expr *left, Expr *right, bool int_only,
|
||||
bool allow_bitstruct, bool is_add_sub);
|
||||
@@ -124,7 +124,7 @@ static bool sema_binary_arithmetic_promotion(SemaContext *context, Expr *left, E
|
||||
Expr *parent, const char *error_message, bool allow_bool_vec);
|
||||
static bool sema_binary_is_unsigned_always_same_comparison(SemaContext *context, Expr *expr, Expr *left, Expr *right,
|
||||
Type *lhs_type, Type *rhs_type);
|
||||
static bool sema_binary_is_expr_lvalue(SemaContext *context, Expr *top_expr, Expr *expr);
|
||||
static bool sema_binary_is_expr_lvalue(SemaContext *context, Expr *top_expr, Expr *expr, bool *failed_ref);
|
||||
static void sema_binary_unify_voidptr(SemaContext *context, Expr *left, Expr *right, Type **left_type_ref, Type **right_type_ref);
|
||||
|
||||
// -- function helper functions
|
||||
@@ -436,40 +436,45 @@ CondResult sema_check_comp_time_bool(SemaContext *context, Expr *expr)
|
||||
}
|
||||
|
||||
|
||||
static bool sema_binary_is_expr_lvalue(SemaContext *context, Expr *top_expr, Expr *expr)
|
||||
static bool sema_binary_is_expr_lvalue(SemaContext *context, Expr *top_expr, Expr *expr, bool *failed_ref)
|
||||
{
|
||||
switch (expr->expr_kind)
|
||||
{
|
||||
case EXPR_SWIZZLE:
|
||||
if (failed_ref) goto FAILED_REF;
|
||||
RETURN_SEMA_ERROR(expr, "You cannot use swizzling to assign to multiple elements, use element-wise assign instead.");
|
||||
case EXPR_LAMBDA:
|
||||
case EXPR_EMBED:
|
||||
if (failed_ref) goto FAILED_REF;
|
||||
RETURN_SEMA_ERROR(expr, "This expression is a value and cannot be assigned to.");
|
||||
case EXPR_CT_IDENT:
|
||||
return true;
|
||||
case EXPR_EXT_TRUNC:
|
||||
case EXPR_INT_TO_BOOL:
|
||||
case EXPR_DISCARD:
|
||||
return false;
|
||||
if (failed_ref) goto FAILED_REF;
|
||||
goto ERR;
|
||||
case EXPR_OTHER_CONTEXT:
|
||||
return sema_binary_is_expr_lvalue(context, top_expr, expr->expr_other_context.inner);
|
||||
return sema_binary_is_expr_lvalue(context, top_expr, expr->expr_other_context.inner, failed_ref);
|
||||
case EXPR_IDENTIFIER:
|
||||
{
|
||||
Decl *decl = expr->identifier_expr.decl;
|
||||
if (decl->decl_kind != DECL_VAR)
|
||||
{
|
||||
if (failed_ref) goto FAILED_REF;
|
||||
RETURN_SEMA_ERROR(top_expr, "You cannot assign a value to %s.", decl_to_a_name(decl));
|
||||
}
|
||||
if (decl->var.kind == VARDECL_CONST)
|
||||
{
|
||||
if (failed_ref) goto FAILED_REF;
|
||||
RETURN_SEMA_ERROR(top_expr, "You cannot assign to a constant.");
|
||||
}
|
||||
decl = decl_raw(decl);
|
||||
switch (decl->var.kind)
|
||||
{
|
||||
case VARDECL_PARAM_REF:
|
||||
SEMA_ERROR(top_expr, "You cannot assign to a ref parameter.");
|
||||
return false;
|
||||
if (failed_ref) goto FAILED_REF;
|
||||
RETURN_SEMA_ERROR(top_expr, "You cannot assign to a ref parameter.");
|
||||
case VARDECL_LOCAL_CT:
|
||||
case VARDECL_LOCAL_CT_TYPE:
|
||||
case VARDECL_LOCAL:
|
||||
@@ -495,13 +500,13 @@ static bool sema_binary_is_expr_lvalue(SemaContext *context, Expr *top_expr, Exp
|
||||
if (expr->unary_expr.operator != UNARYOP_DEREF) goto ERR;
|
||||
if (IS_OPTIONAL(expr))
|
||||
{
|
||||
SEMA_ERROR(top_expr, "You cannot assign to a dereferenced optional.");
|
||||
return false;
|
||||
if (failed_ref) goto FAILED_REF;
|
||||
RETURN_SEMA_ERROR(top_expr, "You cannot assign to a dereferenced optional.");
|
||||
}
|
||||
return true;
|
||||
case EXPR_BITACCESS:
|
||||
case EXPR_ACCESS:
|
||||
if (!sema_binary_is_expr_lvalue(context, top_expr, expr->access_expr.parent)) return false;
|
||||
if (!sema_binary_is_expr_lvalue(context, top_expr, expr->access_expr.parent, failed_ref)) return false;
|
||||
goto CHECK_OPTIONAL;
|
||||
case EXPR_SUBSCRIPT:
|
||||
case EXPR_SLICE:
|
||||
@@ -509,12 +514,13 @@ static bool sema_binary_is_expr_lvalue(SemaContext *context, Expr *top_expr, Exp
|
||||
case EXPR_SUBSCRIPT_ADDR:
|
||||
goto CHECK_OPTIONAL;
|
||||
case EXPR_HASH_IDENT:
|
||||
if (failed_ref) goto FAILED_REF;
|
||||
RETURN_SEMA_ERROR(top_expr, "You cannot assign to an unevaluated expression.");
|
||||
case EXPR_EXPRESSION_LIST:
|
||||
if (!vec_size(expr->expression_list)) return false;
|
||||
return sema_binary_is_expr_lvalue(context, top_expr, VECLAST(expr->expression_list));
|
||||
goto CHECK_OPTIONAL;
|
||||
if (!vec_size(expr->expression_list)) goto ERR;
|
||||
return sema_binary_is_expr_lvalue(context, top_expr, VECLAST(expr->expression_list), failed_ref);
|
||||
case EXPR_CONST:
|
||||
if (failed_ref) goto FAILED_REF;
|
||||
RETURN_SEMA_ERROR(top_expr, "You cannot assign to a constant expression.");
|
||||
case EXPR_POISONED:
|
||||
case EXPR_ADDR_CONVERSION:
|
||||
@@ -594,15 +600,18 @@ static bool sema_binary_is_expr_lvalue(SemaContext *context, Expr *top_expr, Exp
|
||||
}
|
||||
UNREACHABLE
|
||||
ERR:
|
||||
SEMA_ERROR(top_expr, "An assignable expression, like a variable, was expected here.");
|
||||
return false;
|
||||
if (failed_ref) goto FAILED_REF;
|
||||
RETURN_SEMA_ERROR(top_expr, "An assignable expression, like a variable, was expected here.");
|
||||
CHECK_OPTIONAL:
|
||||
if (IS_OPTIONAL(expr))
|
||||
{
|
||||
if (failed_ref) goto FAILED_REF;
|
||||
RETURN_SEMA_ERROR(top_expr, "You cannot assign to an optional value.");
|
||||
}
|
||||
return true;
|
||||
|
||||
FAILED_REF:
|
||||
*failed_ref = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool expr_may_ref(Expr *expr)
|
||||
@@ -744,10 +753,10 @@ static bool expr_may_ref(Expr *expr)
|
||||
UNREACHABLE
|
||||
}
|
||||
|
||||
bool sema_expr_check_assign(SemaContext *context, Expr *expr)
|
||||
bool sema_expr_check_assign(SemaContext *context, Expr *expr, bool *failed_ref)
|
||||
{
|
||||
Expr *inner;
|
||||
if (!sema_binary_is_expr_lvalue(context, expr, expr)) return false;
|
||||
if (!sema_binary_is_expr_lvalue(context, expr, expr, failed_ref)) return false;
|
||||
if (expr->expr_kind == EXPR_SUBSCRIPT)
|
||||
{
|
||||
inner = exprptr(expr->subscript_expr.expr);
|
||||
@@ -766,8 +775,7 @@ CHECK_INNER:
|
||||
Decl *decl = inner->identifier_expr.decl;
|
||||
if (decl->decl_kind != DECL_VAR) return true;
|
||||
if (!decl->var.in_param) return true;
|
||||
SEMA_ERROR(inner, "'in' parameters may not be assigned to.");
|
||||
return false;
|
||||
RETURN_SEMA_ERROR(inner, "'in' parameters may not be assigned to.");
|
||||
}
|
||||
|
||||
static inline bool sema_cast_ident_rvalue(SemaContext *context, Expr *expr)
|
||||
@@ -1309,7 +1317,7 @@ static bool sema_analyse_parameter(SemaContext *context, Expr *arg, Decl *param,
|
||||
break;
|
||||
}
|
||||
if (!sema_analyse_expr_address(context, arg)) return false;
|
||||
if (sema_arg_is_pass_through_ref(arg) && !sema_expr_check_assign(context, arg))
|
||||
if (sema_arg_is_pass_through_ref(arg) && !sema_expr_check_assign(context, arg, NULL))
|
||||
{
|
||||
SEMA_NOTE(definition, "The definition is here.");
|
||||
return false;
|
||||
@@ -3003,7 +3011,7 @@ static inline bool sema_expr_analyse_subscript(SemaContext *context, Expr *expr,
|
||||
if (!sema_analyse_expr_check(context, subscripted, CHECK_VALUE)) return false;
|
||||
|
||||
// If it is an lvalue then check that it is assignable.
|
||||
if (check == CHECK_LVALUE && !sema_expr_check_assign(context, expr)) return false;
|
||||
if (check == CHECK_LVALUE && !sema_expr_check_assign(context, expr, NULL)) return false;
|
||||
|
||||
// 2. Evaluate the index.
|
||||
Expr *index = exprptr(expr->subscript_expr.index.expr);
|
||||
@@ -5677,7 +5685,7 @@ static bool sema_expr_fold_hash(SemaContext *context, Expr *expr)
|
||||
* Analyse a = b
|
||||
* @return true if analysis works
|
||||
*/
|
||||
static bool sema_expr_analyse_assign(SemaContext *context, Expr *expr, Expr *left, Expr *right)
|
||||
static bool sema_expr_analyse_assign(SemaContext *context, Expr *expr, Expr *left, Expr *right, bool *failed_ref)
|
||||
{
|
||||
if (!sema_expr_fold_hash(context, left)) return false;
|
||||
// 1. Evaluate left side
|
||||
@@ -5698,7 +5706,7 @@ static bool sema_expr_analyse_assign(SemaContext *context, Expr *expr, Expr *lef
|
||||
break;
|
||||
}
|
||||
// 2. Check assignability
|
||||
if (!sema_expr_check_assign(context, left)) return false;
|
||||
if (!sema_expr_check_assign(context, left, failed_ref)) return false;
|
||||
|
||||
bool is_unwrapped_var = expr_is_unwrapped_ident(left);
|
||||
|
||||
@@ -5742,7 +5750,7 @@ static bool sema_binary_analyse_ct_common_assign(SemaContext *context, Expr *exp
|
||||
|
||||
expr->binary_expr.operator = binaryop_assign_base_op(expr->binary_expr.operator);
|
||||
|
||||
if (!sema_expr_analyse_binary(context, expr)) return false;
|
||||
if (!sema_expr_analyse_binary(context, expr, NULL)) return false;
|
||||
|
||||
if (!sema_cast_const(expr))
|
||||
{
|
||||
@@ -5771,7 +5779,7 @@ static bool sema_expr_analyse_op_assign(SemaContext *context, Expr *expr, Expr *
|
||||
if (!sema_analyse_expr_lvalue(context, left)) return false;
|
||||
|
||||
// 2. Verify that the left side is assignable.
|
||||
if (!sema_expr_check_assign(context, left)) return false;
|
||||
if (!sema_expr_check_assign(context, left, NULL)) return false;
|
||||
|
||||
Type *left_type_canonical = left->type->canonical;
|
||||
|
||||
@@ -6620,7 +6628,7 @@ static bool sema_expr_analyse_shift_assign(SemaContext *context, Expr *expr, Exp
|
||||
bool optional = IS_OPTIONAL(left) || IS_OPTIONAL(right);
|
||||
|
||||
// 2. Ensure the lhs side is assignable
|
||||
if (!sema_expr_check_assign(context, left)) return false;
|
||||
if (!sema_expr_check_assign(context, left, NULL)) return false;
|
||||
|
||||
// 3. Only integers may be shifted.
|
||||
if (!expr_both_any_integer_or_integer_vector(left, right)) return sema_type_error_on_binop(context, expr);
|
||||
@@ -7397,7 +7405,7 @@ static inline bool sema_expr_analyse_incdec(SemaContext *context, Expr *expr)
|
||||
if (!sema_analyse_expr_lvalue(context, inner)) return false;
|
||||
|
||||
// 2. Assert it's an l-value
|
||||
if (!sema_expr_check_assign(context, inner)) return false;
|
||||
if (!sema_expr_check_assign(context, inner, NULL)) return false;
|
||||
|
||||
// 3. This might be a $foo, if to handle it.
|
||||
if (inner->expr_kind == EXPR_CT_IDENT)
|
||||
@@ -7587,7 +7595,7 @@ static inline bool sema_expr_analyse_ct_and_or(SemaContext *context, Expr *expr,
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool sema_expr_analyse_binary(SemaContext *context, Expr *expr)
|
||||
static inline bool sema_expr_analyse_binary(SemaContext *context, Expr *expr, bool *failed_ref)
|
||||
{
|
||||
if (expr->binary_expr.operator == BINARYOP_ELSE) return sema_expr_analyse_or_error(context, expr);
|
||||
ASSERT_SPAN(expr, expr->resolve_status == RESOLVE_RUNNING);
|
||||
@@ -7609,7 +7617,7 @@ static inline bool sema_expr_analyse_binary(SemaContext *context, Expr *expr)
|
||||
case BINARYOP_CT_AND:
|
||||
return sema_expr_analyse_ct_and_or(context, expr, left, right);
|
||||
case BINARYOP_ASSIGN:
|
||||
return sema_expr_analyse_assign(context, expr, left, right);
|
||||
return sema_expr_analyse_assign(context, expr, left, right, failed_ref);
|
||||
case BINARYOP_MULT:
|
||||
return sema_expr_analyse_mult(context, expr, left, right);
|
||||
case BINARYOP_ADD:
|
||||
@@ -8986,9 +8994,15 @@ static inline bool sema_expr_analyse_ct_defined(SemaContext *context, Expr *expr
|
||||
case EXPR_DEFAULT_ARG:
|
||||
case EXPR_NAMED_ARGUMENT:
|
||||
UNREACHABLE
|
||||
case EXPR_CT_ARG:
|
||||
FALLTHROUGH;
|
||||
case EXPR_BINARY:
|
||||
main_expr->resolve_status = RESOLVE_RUNNING;
|
||||
if (!sema_expr_analyse_binary(context, main_expr, &failed))
|
||||
{
|
||||
if (!failed) goto FAIL;
|
||||
success = false;
|
||||
}
|
||||
break;
|
||||
case EXPR_CT_ARG:
|
||||
case EXPR_BITACCESS:
|
||||
case EXPR_BITASSIGN:
|
||||
case EXPR_COMPOUND_LITERAL:
|
||||
@@ -9546,7 +9560,7 @@ static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr,
|
||||
case EXPR_CT_EVAL:
|
||||
return sema_expr_analyse_ct_eval(context, expr, check);
|
||||
case EXPR_BINARY:
|
||||
return sema_expr_analyse_binary(context, expr);
|
||||
return sema_expr_analyse_binary(context, expr, NULL);
|
||||
case EXPR_TERNARY:
|
||||
return sema_expr_analyse_ternary(context, NULL, expr);
|
||||
case EXPR_UNARY:
|
||||
|
||||
@@ -109,7 +109,8 @@ bool sema_analyse_asm(SemaContext *context, AsmInlineBlock *block, Ast *asm_stmt
|
||||
|
||||
bool sema_bit_assignment_check(SemaContext *context, Expr *right, Decl *member);
|
||||
CondResult sema_check_comp_time_bool(SemaContext *context, Expr *expr);
|
||||
bool sema_expr_check_assign(SemaContext *context, Expr *expr);
|
||||
|
||||
bool sema_expr_check_assign(SemaContext *context, Expr *expr, bool *failed_ref);
|
||||
bool sema_analyse_function_signature(SemaContext *context, Decl *func_decl, TypeInfo *parent, CallABI abi, Signature *signature);
|
||||
Expr *sema_create_struct_from_expressions(Decl *struct_decl, SourceSpan span, Expr **exprs);
|
||||
ConstInitializer *sema_merge_bitstruct_const_initializers(ConstInitializer *lhs, ConstInitializer *rhs, BinaryOp op);
|
||||
|
||||
@@ -9,12 +9,16 @@ fn void main()
|
||||
{
|
||||
Foo* foo;
|
||||
float[<4>] a @align(1) @noinit;
|
||||
float[<4>] b @align(1) @noinit;
|
||||
|
||||
a = *(float[<4>]*)&foo.a;
|
||||
*(float[<4>]*)&foo.a = a;
|
||||
|
||||
a = $$unaligned_load((float[<4>]*)&foo.a, 1);
|
||||
$$unaligned_store((float[<4>]*)&foo.a, a, 1);
|
||||
|
||||
b = @unaligned_load(*(float[<4>]*)&foo.a, 1);
|
||||
@unaligned_store(*(float[<4>]*)&foo.a, b, 1);
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
@@ -23,6 +27,8 @@ define void @test.main() #0 {
|
||||
entry:
|
||||
%foo = alloca ptr, align 8
|
||||
%a = alloca <4 x float>, align 1
|
||||
%b = alloca <4 x float>, align 1
|
||||
%value = alloca <4 x float>, align 16
|
||||
store ptr null, ptr %foo, align 8
|
||||
%0 = load ptr, ptr %foo, align 8
|
||||
%1 = load <4 x float>, ptr %0, align 16
|
||||
@@ -36,5 +42,13 @@ entry:
|
||||
%6 = load ptr, ptr %foo, align 8
|
||||
%7 = load <4 x float>, ptr %a, align 1
|
||||
store <4 x float> %7, ptr %6, align 1
|
||||
%8 = load ptr, ptr %foo, align 8
|
||||
%9 = load <4 x float>, ptr %8, align 1
|
||||
store <4 x float> %9, ptr %b, align 1
|
||||
%10 = load <4 x float>, ptr %b, align 1
|
||||
store <4 x float> %10, ptr %value, align 16
|
||||
%11 = load ptr, ptr %foo, align 8
|
||||
%12 = load <4 x float>, ptr %value, align 16
|
||||
store <4 x float> %12, ptr %11, align 1
|
||||
ret void
|
||||
}
|
||||
}
|
||||
@@ -31,42 +31,30 @@ define void @test.main() #0 !dbg !8 {
|
||||
entry:
|
||||
%a = alloca i32, align 4
|
||||
%x = alloca i32, align 4
|
||||
%x1 = alloca ptr, align 8
|
||||
%y = alloca i32, align 4
|
||||
%x2 = alloca ptr, align 8
|
||||
%x3 = alloca ptr, align 8
|
||||
%value = alloca i32, align 4
|
||||
%x4 = alloca ptr, align 8
|
||||
%value6 = alloca i32, align 4
|
||||
%value2 = alloca i32, align 4
|
||||
%varargslots = alloca [1 x %any], align 16
|
||||
%retparam = alloca i64, align 8
|
||||
store i32 111, ptr %a, align 4, !dbg !15
|
||||
store ptr %a, ptr %x1, align 8
|
||||
%0 = load ptr, ptr %x1, align 8, !dbg !18
|
||||
%1 = load atomic i32, ptr %0 seq_cst, align 4, !dbg !18
|
||||
store i32 %1, ptr %x, align 4, !dbg !18
|
||||
store ptr %a, ptr %x2, align 8
|
||||
%2 = load ptr, ptr %x2, align 8, !dbg !24
|
||||
%3 = load atomic volatile i32, ptr %2 monotonic, align 4, !dbg !24
|
||||
store i32 %3, ptr %y, align 4, !dbg !24
|
||||
store ptr %a, ptr %x3, align 8
|
||||
%4 = load i32, ptr %x, align 4, !dbg !27
|
||||
%add = add i32 123, %4, !dbg !28
|
||||
%0 = load atomic i32, ptr %a seq_cst, align 4, !dbg !18
|
||||
store i32 %0, ptr %x, align 4, !dbg !18
|
||||
%1 = load atomic volatile i32, ptr %a monotonic, align 4, !dbg !24
|
||||
store i32 %1, ptr %y, align 4, !dbg !24
|
||||
%2 = load i32, ptr %x, align 4, !dbg !27
|
||||
%add = add i32 123, %2, !dbg !28
|
||||
store i32 %add, ptr %value, align 4
|
||||
%5 = load ptr, ptr %x3, align 8, !dbg !29
|
||||
%6 = load i32, ptr %value, align 4, !dbg !29
|
||||
store atomic i32 %6, ptr %5 seq_cst, align 4, !dbg !29
|
||||
store ptr %a, ptr %x4, align 8
|
||||
%7 = load i32, ptr %y, align 4, !dbg !32
|
||||
%add5 = add i32 33, %7, !dbg !33
|
||||
store i32 %add5, ptr %value6, align 4
|
||||
%8 = load ptr, ptr %x4, align 8, !dbg !34
|
||||
%9 = load i32, ptr %value6, align 4, !dbg !34
|
||||
store atomic volatile i32 %9, ptr %8 monotonic, align 4, !dbg !34
|
||||
%10 = insertvalue %any undef, ptr %a, 0, !dbg !37
|
||||
%11 = insertvalue %any %10, i64 ptrtoint (ptr @"$ct.int" to i64), 1, !dbg !37
|
||||
store %any %11, ptr %varargslots, align 16, !dbg !37
|
||||
%12 = call i64 @std.io.printfn(ptr %retparam, ptr @.str, i64 2, ptr %varargslots, i64 1), !dbg !38
|
||||
%3 = load i32, ptr %value, align 4, !dbg !29
|
||||
store atomic i32 %3, ptr %a seq_cst, align 4, !dbg !29
|
||||
%4 = load i32, ptr %y, align 4, !dbg !32
|
||||
%add1 = add i32 33, %4, !dbg !33
|
||||
store i32 %add1, ptr %value2, align 4
|
||||
%5 = load i32, ptr %value2, align 4, !dbg !34
|
||||
store atomic volatile i32 %5, ptr %a monotonic, align 4, !dbg !34
|
||||
%6 = insertvalue %any undef, ptr %a, 0, !dbg !37
|
||||
%7 = insertvalue %any %6, i64 ptrtoint (ptr @"$ct.int" to i64), 1, !dbg !37
|
||||
store %any %7, ptr %varargslots, align 16, !dbg !37
|
||||
%8 = call i64 @std.io.printfn(ptr %retparam, ptr @.str, i64 2, ptr %varargslots, i64 1), !dbg !38
|
||||
ret void, !dbg !38
|
||||
}
|
||||
|
||||
@@ -118,17 +106,17 @@ declare i1 @llvm.expect.i1(i1, i1)
|
||||
!22 = !DILocalVariable(name: "y", scope: !8, file: !7, line: 14, type: !13, align: 4)
|
||||
!23 = !DILocation(line: 14, column: 6, scope: !8)
|
||||
!24 = !DILocation(
|
||||
!25 = distinct !DISubprogram(name: "@atomic_load", linkageName: "@atomic_load", scope: !20, file: !20, line: 225, scopeLine: 225, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !6)
|
||||
!25 = distinct !DISubprogram(name: "@atomic_load", linkageName: "@atomic_load", scope: !20, file: !20
|
||||
!26 = !DILocation(line: 14, column: 10, scope: !8)
|
||||
!27 = !DILocation(line: 15, column: 25, scope: !8)
|
||||
!28 = !DILocation(line: 15, column: 19, scope: !8)
|
||||
!29 = !DILocation(
|
||||
!30 = distinct !DISubprogram(name: "@atomic_store", linkageName: "@atomic_store", scope: !20, file: !20, line: 240, scopeLine: 240, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !6)
|
||||
!30 = distinct !DISubprogram(name: "@atomic_store", linkageName: "@atomic_store", scope: !20, file: !20
|
||||
!31 = !DILocation(line: 15, column: 2, scope: !8)
|
||||
!32 = !DILocation(line: 16, column: 24, scope: !8)
|
||||
!33 = !DILocation(line: 16, column: 19, scope: !8)
|
||||
!34 = !DILocation(
|
||||
!35 = distinct !DISubprogram(name: "@atomic_store", linkageName: "@atomic_store", scope: !20, file: !20, line: 240, scopeLine: 240, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !6)
|
||||
!35 = distinct !DISubprogram(name: "@atomic_store", linkageName: "@atomic_store", scope: !20, file: !20
|
||||
!36 = !DILocation(line: 16, column: 2, scope: !8)
|
||||
!37 = !DILocation(line: 17, column: 20, scope: !8)
|
||||
!38 = !DILocation(line: 17, column: 2, scope: !8)
|
||||
|
||||
@@ -664,7 +664,7 @@ no_match: ; preds = %compare
|
||||
!73 = !DILocalVariable(name: "name", arg: 3, scope: !66, file: !7, line: 33, type: !39)
|
||||
!74 = !DILocation(line: 33, column: 63, scope: !66)
|
||||
!75 = !DILocation(line:
|
||||
!76 = distinct !DISubprogram(name: "new", linkageName: "new", scope: !77, file: !77, line: 624, scopeLine: 624, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !6)
|
||||
!76 = distinct !DISubprogram(name: "new", linkageName: "new", scope: !77, file: !77, line:
|
||||
!77 = !DIFile(filename: "mem.c3"
|
||||
!78 = !DILocation(line: 34, column: 10, scope: !66)
|
||||
!79 = distinct !DISubprogram(name: "test", linkageName: "test.test", scope: !7, file: !7, line: 41, type: !80, scopeLine: 41, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !21)
|
||||
@@ -743,9 +743,9 @@ no_match: ; preds = %compare
|
||||
!152 = distinct !DISubprogram(name: "alloc_array_try", linkageName: "alloc_array_try", scope: !153, file: !153, line: 284, scopeLine: 284, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !6)
|
||||
!153 = !DIFile(filename: "mem_allocator.c3"
|
||||
!154 = !DILocation
|
||||
!155 = distinct !DISubprogram(name: "alloc_array", linkageName: "alloc_array", scope: !153, file: !153, line: 267, scopeLine: 267, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !6)
|
||||
!155 = distinct !DISubprogram(name: "alloc_array", linkageName: "alloc_array", scope: !153
|
||||
!156 = !DILocation
|
||||
!157 = distinct !DISubprogram(name: "alloc_array", linkageName: "alloc_array", scope: !77, file: !77, line: 710, scopeLine: 710, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !6)
|
||||
!157 = distinct !DISubprogram(name: "alloc_array", linkageName: "alloc_array", scope: !77
|
||||
!158 = !DILocation
|
||||
!159 = !DILocation
|
||||
!160 = !DILocation
|
||||
|
||||
@@ -7,8 +7,6 @@ fn void foo3(bar) { } // #error: Only typed parameters are allowed for functions
|
||||
|
||||
fn void foo4($Type) { } // #error: Only regular parameters are allowed for functions.
|
||||
|
||||
fn void foo8(int* &foo) {} // #error: Only regular parameters are allowed for functions.
|
||||
|
||||
fn void foo9(int x, int x) {} // #error: Duplicate parameter name 'x'.
|
||||
|
||||
macro @foo($a, $b, $c, ...) {}
|
||||
@@ -1,15 +0,0 @@
|
||||
module test;
|
||||
|
||||
fn void test(int* a) {}
|
||||
macro @abc(&self)
|
||||
{
|
||||
test(self); // #error: Implicitly casting 'int**' to 'int*'
|
||||
}
|
||||
|
||||
fn void! test1()
|
||||
{
|
||||
int* a;
|
||||
int b;
|
||||
@abc(a);
|
||||
@abc(b);
|
||||
}
|
||||
@@ -4,17 +4,17 @@ import std::io;
|
||||
|
||||
fn void main()
|
||||
{
|
||||
@boba(;#hash_val, &foo, int $value, $Type)
|
||||
@boba(;#hash_val, #foo, int $value, $Type)
|
||||
{
|
||||
io::printn("Now invoking hash");
|
||||
#hash_val;
|
||||
#hash_val;
|
||||
*foo += $value;
|
||||
#foo += $value;
|
||||
io::printfn("The type was: %s", $Type.nameof);
|
||||
};
|
||||
}
|
||||
|
||||
macro void @boba(;@body(#hash, &foo, $val, $Type))
|
||||
macro void @boba(;@body(#hash, #foo, $val, $Type))
|
||||
{
|
||||
io::printn("Boba");
|
||||
int a = 0;
|
||||
@@ -34,7 +34,6 @@ entry:
|
||||
%error_var8 = alloca i64, align 8
|
||||
%a = alloca i32, align 4
|
||||
%b = alloca i32, align 4
|
||||
%foo = alloca ptr, align 8
|
||||
%len14 = alloca i64, align 8
|
||||
%error_var15 = alloca i64, align 8
|
||||
%retparam17 = alloca i64, align 8
|
||||
@@ -54,17 +53,13 @@ entry:
|
||||
%not_err = icmp eq i64 %1, 0
|
||||
%2 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
|
||||
br i1 %2, label %after_check, label %assign_optional
|
||||
|
||||
assign_optional: ; preds = %entry
|
||||
store i64 %1, ptr %error_var, align 8
|
||||
br label %guard_block
|
||||
|
||||
after_check: ; preds = %entry
|
||||
br label %noerr_block
|
||||
|
||||
guard_block: ; preds = %assign_optional
|
||||
br label %voiderr
|
||||
|
||||
noerr_block: ; preds = %after_check
|
||||
%3 = load i64, ptr %retparam, align 8
|
||||
store i64 %3, ptr %len, align 8
|
||||
@@ -72,58 +67,44 @@ noerr_block: ; preds = %after_check
|
||||
%not_err3 = icmp eq i64 %4, 0
|
||||
%5 = call i1 @llvm.expect.i1(i1 %not_err3, i1 true)
|
||||
br i1 %5, label %after_check5, label %assign_optional4
|
||||
|
||||
assign_optional4: ; preds = %noerr_block
|
||||
store i64 %4, ptr %error_var2, align 8
|
||||
br label %guard_block6
|
||||
|
||||
after_check5: ; preds = %noerr_block
|
||||
br label %noerr_block7
|
||||
|
||||
guard_block6: ; preds = %assign_optional4
|
||||
br label %voiderr
|
||||
|
||||
noerr_block7: ; preds = %after_check5
|
||||
%6 = call i64 @std.io.File.flush(ptr %0)
|
||||
%not_err9 = icmp eq i64 %6, 0
|
||||
%7 = call i1 @llvm.expect.i1(i1 %not_err9, i1 true)
|
||||
br i1 %7, label %after_check11, label %assign_optional10
|
||||
|
||||
assign_optional10: ; preds = %noerr_block7
|
||||
store i64 %6, ptr %error_var8, align 8
|
||||
br label %guard_block12
|
||||
|
||||
after_check11: ; preds = %noerr_block7
|
||||
br label %noerr_block13
|
||||
|
||||
guard_block12: ; preds = %assign_optional10
|
||||
br label %voiderr
|
||||
|
||||
noerr_block13: ; preds = %after_check11
|
||||
%8 = load i64, ptr %len, align 8
|
||||
%add = add i64 %8, 1
|
||||
br label %voiderr
|
||||
|
||||
voiderr: ; preds = %noerr_block13, %guard_block12, %guard_block6, %guard_block
|
||||
store i32 0, ptr %a, align 4
|
||||
store i32 0, ptr %b, align 4
|
||||
store ptr %b, ptr %foo, align 8
|
||||
%9 = call ptr @std.io.stdout()
|
||||
%10 = call i64 @std.io.File.write(ptr %retparam17, ptr %9, ptr @.str.1, i64 17)
|
||||
%not_err18 = icmp eq i64 %10, 0
|
||||
%11 = call i1 @llvm.expect.i1(i1 %not_err18, i1 true)
|
||||
br i1 %11, label %after_check20, label %assign_optional19
|
||||
|
||||
assign_optional19: ; preds = %voiderr
|
||||
store i64 %10, ptr %error_var15, align 8
|
||||
br label %guard_block21
|
||||
|
||||
after_check20: ; preds = %voiderr
|
||||
br label %noerr_block22
|
||||
|
||||
guard_block21: ; preds = %assign_optional19
|
||||
br label %voiderr36
|
||||
|
||||
noerr_block22: ; preds = %after_check20
|
||||
%12 = load i64, ptr %retparam17, align 8
|
||||
store i64 %12, ptr %len14, align 8
|
||||
@@ -131,38 +112,29 @@ noerr_block22: ; preds = %after_check20
|
||||
%not_err24 = icmp eq i64 %13, 0
|
||||
%14 = call i1 @llvm.expect.i1(i1 %not_err24, i1 true)
|
||||
br i1 %14, label %after_check26, label %assign_optional25
|
||||
|
||||
assign_optional25: ; preds = %noerr_block22
|
||||
store i64 %13, ptr %error_var23, align 8
|
||||
br label %guard_block27
|
||||
|
||||
after_check26: ; preds = %noerr_block22
|
||||
br label %noerr_block28
|
||||
|
||||
guard_block27: ; preds = %assign_optional25
|
||||
br label %voiderr36
|
||||
|
||||
noerr_block28: ; preds = %after_check26
|
||||
%15 = call i64 @std.io.File.flush(ptr %9)
|
||||
%not_err30 = icmp eq i64 %15, 0
|
||||
%16 = call i1 @llvm.expect.i1(i1 %not_err30, i1 true)
|
||||
br i1 %16, label %after_check32, label %assign_optional31
|
||||
|
||||
assign_optional31: ; preds = %noerr_block28
|
||||
store i64 %15, ptr %error_var29, align 8
|
||||
br label %guard_block33
|
||||
|
||||
after_check32: ; preds = %noerr_block28
|
||||
br label %noerr_block34
|
||||
|
||||
guard_block33: ; preds = %assign_optional31
|
||||
br label %voiderr36
|
||||
|
||||
noerr_block34: ; preds = %after_check32
|
||||
%17 = load i64, ptr %len14, align 8
|
||||
%add35 = add i64 %17, 1
|
||||
br label %voiderr36
|
||||
|
||||
voiderr36: ; preds = %noerr_block34, %guard_block33, %guard_block27, %guard_block21
|
||||
%18 = insertvalue %any undef, ptr %a, 0
|
||||
%19 = insertvalue %any %18, i64 ptrtoint (ptr @"$ct.int" to i64), 1
|
||||
@@ -178,18 +150,17 @@ voiderr36: ; preds = %noerr_block34, %gua
|
||||
%25 = load i32, ptr %a, align 4
|
||||
%add45 = add i32 %25, 1
|
||||
store i32 %add45, ptr %a, align 4
|
||||
%26 = load ptr, ptr %foo, align 8
|
||||
%27 = load i32, ptr %26, align 4
|
||||
%add46 = add i32 %27, 3
|
||||
store i32 %add46, ptr %26, align 4
|
||||
%26 = load i32, ptr %b, align 4
|
||||
%add46 = add i32 %26, 3
|
||||
store i32 %add46, ptr %b, align 4
|
||||
store %"char[]" { ptr @.str.5, i64 3 }, ptr %taddr, align 8
|
||||
%28 = insertvalue %any undef, ptr %taddr, 0
|
||||
%29 = insertvalue %any %28, i64 ptrtoint (ptr @"$ct.String" to i64), 1
|
||||
store %any %29, ptr %varargslots47, align 16
|
||||
%30 = call i64 @std.io.printfn(ptr %retparam48, ptr @.str.4, i64 16, ptr %varargslots47, i64 1)
|
||||
%31 = insertvalue %any undef, ptr %b, 0
|
||||
%32 = insertvalue %any %31, i64 ptrtoint (ptr @"$ct.int" to i64), 1
|
||||
store %any %32, ptr %varargslots51, align 16
|
||||
%33 = call i64 @std.io.printfn(ptr %retparam52, ptr @.str.6, i64 2, ptr %varargslots51, i64 1)
|
||||
%27 = insertvalue %any undef, ptr %taddr, 0
|
||||
%28 = insertvalue %any %27, i64 ptrtoint (ptr @"$ct.String" to i64), 1
|
||||
store %any %28, ptr %varargslots47, align 16
|
||||
%29 = call i64 @std.io.printfn(ptr %retparam48, ptr @.str.4, i64 16, ptr %varargslots47, i64 1)
|
||||
%30 = insertvalue %any undef, ptr %b, 0
|
||||
%31 = insertvalue %any %30, i64 ptrtoint (ptr @"$ct.int" to i64), 1
|
||||
store %any %31, ptr %varargslots51, align 16
|
||||
%32 = call i64 @std.io.printfn(ptr %retparam52, ptr @.str.6, i64 2, ptr %varargslots51, i64 1)
|
||||
ret void
|
||||
}
|
||||
|
||||
@@ -2,10 +2,7 @@ macro foo(a, $b, $Type) {}
|
||||
|
||||
macro @foo2(a, $b, $Type) {}
|
||||
|
||||
macro bar(&x) // #error: Ref and expression parameters
|
||||
{}
|
||||
|
||||
macro baz(#y) {} // #error: Ref and expression parameters
|
||||
macro baz(#y) {} // #error: are not allowed in function-like
|
||||
|
||||
macro baz2(a; @body()) {} // #error: Names of macros
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
module test;
|
||||
|
||||
import std::io;
|
||||
|
||||
macro @foo(int* &hello)
|
||||
{
|
||||
hello = hello; // #error: You cannot assign to a ref
|
||||
}
|
||||
|
||||
macro @bar(Foo* &f)
|
||||
{
|
||||
f.a = 1;
|
||||
int* x = &f.a;
|
||||
Foo **ff = &f; // #error: You may not take the address
|
||||
}
|
||||
|
||||
struct Foo
|
||||
{
|
||||
int a;
|
||||
}
|
||||
|
||||
fn void main()
|
||||
{
|
||||
int a;
|
||||
@foo(a);
|
||||
Foo x;
|
||||
@bar(x);
|
||||
}
|
||||
@@ -14,10 +14,10 @@ fn int Foo.mutate(Foo *foo)
|
||||
return 10 * ++foo.x;
|
||||
}
|
||||
|
||||
macro @macro_with_body(foo, &x; @body(x, y))
|
||||
macro @macro_with_body(foo, #x; @body(x, y))
|
||||
{
|
||||
*x = foo.x;
|
||||
@body(foo.mutate(), *x);
|
||||
#x = foo.x;
|
||||
@body(foo.mutate(), #x);
|
||||
}
|
||||
|
||||
macro @repeat(int times; @body(x))
|
||||
|
||||
@@ -14,10 +14,10 @@ fn int Foo.mutate(Foo *foo)
|
||||
return 10 * ++foo.x;
|
||||
}
|
||||
|
||||
macro @macro_with_body(foo, &x; @body(x, y))
|
||||
macro @macro_with_body(foo, #x; @body(x, y))
|
||||
{
|
||||
*x = foo.x;
|
||||
@body(foo.mutate(), x); // #error: 'int*' to 'int'
|
||||
#x = foo.x;
|
||||
@body(foo.mutate(), &#x); // #error: 'int*' to 'int'
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ fn int main() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
macro @foo(&ref) {
|
||||
*ref += 1;
|
||||
macro @foo(#ref) {
|
||||
#ref += 1;
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
@@ -21,20 +21,34 @@ define i32 @main() #0 {
|
||||
entry:
|
||||
%vec = alloca <4 x i32>, align 16
|
||||
store <4 x i32> zeroinitializer, ptr %vec, align 16
|
||||
%0 = load i32, ptr %vec, align 4
|
||||
%add = add i32 %0, 1
|
||||
store i32 %add, ptr %vec, align 4
|
||||
%ptradd = getelementptr inbounds i8, ptr %vec, i64 8
|
||||
%1 = load i32, ptr %ptradd, align 4
|
||||
%add1 = add i32 %1, 1
|
||||
store i32 %add1, ptr %ptradd, align 4
|
||||
%0 = load <4 x i32>, ptr %vec, align 16
|
||||
%elem = extractelement <4 x i32> %0, i64 0
|
||||
%add = add i32 %elem, 1
|
||||
%elemset = insertelement <4 x i32> %0, i32 %add, i64 0
|
||||
store <4 x i32> %elemset, ptr %vec, align 16
|
||||
%1 = load <4 x i32>, ptr %vec, align 16
|
||||
%elem1 = extractelement <4 x i32> %1, i64 2
|
||||
%add2 = add i32 %elem1, 1
|
||||
%elemset3 = insertelement <4 x i32> %1, i32 %add2, i64 2
|
||||
store <4 x i32> %elemset3, ptr %vec, align 16
|
||||
%2 = load <4 x i32>, ptr %vec, align 16
|
||||
%3 = extractelement <4 x i32> %2, i64 0
|
||||
%eq = icmp eq i32 %3, 1
|
||||
call void @llvm.assume(i1 %eq)
|
||||
%4 = load <4 x i32>, ptr %vec, align 16
|
||||
%5 = extractelement <4 x i32> %4, i64 2
|
||||
%eq2 = icmp eq i32 %5, 1
|
||||
call void @llvm.assume(i1 %eq2)
|
||||
%eq4 = icmp eq i32 %5, 1
|
||||
call void @llvm.assume(i1 %eq4)
|
||||
ret i32 1
|
||||
}
|
||||
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write)
|
||||
declare void @llvm.assume(i1 noundef) #1
|
||||
attributes #0 = { nounwind uwtable "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
|
||||
attributes #1 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
|
||||
!llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
|
||||
!0 = !{i32 2, !"Dwarf Version", i32 4}
|
||||
!1 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!2 = !{i32 2, !"wchar_size", i32 4}
|
||||
!3 = !{i32 4, !"PIC Level", i32 2}
|
||||
!4 = !{i32 1, !"uwtable", i32 2}
|
||||
!5 = !{i32 2, !"frame-pointer", i32 2}
|
||||
@@ -4,9 +4,9 @@ import std, test2;
|
||||
|
||||
int[2] x;
|
||||
|
||||
macro @test2(&a = x[1])
|
||||
macro @test2(#a = x[1])
|
||||
{
|
||||
*a = 123;
|
||||
#a = 123;
|
||||
}
|
||||
macro test($Type = int) { io::printn($Type.nameof); }
|
||||
|
||||
@@ -31,9 +31,9 @@ import std;
|
||||
|
||||
int[2] x;
|
||||
|
||||
macro @test2(&a = x[1])
|
||||
macro @test2(#a = x[1])
|
||||
{
|
||||
*a = 12;
|
||||
#a = 12;
|
||||
}
|
||||
macro test($Type = double) { io::printn($Type.nameof); }
|
||||
|
||||
|
||||
@@ -68,4 +68,4 @@ fn usz! TestReader.read(&self, char[] bytes) @dynamic
|
||||
return n;
|
||||
}
|
||||
|
||||
fn char! TestReader.read_byte(&self) @dynamic => io::@read_byte_using_read(self);
|
||||
fn char! TestReader.read_byte(&self) @dynamic => io::read_byte_using_read(self);
|
||||
|
||||
Reference in New Issue
Block a user