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
|
Stores a variable on the stack, then restores it at the end of the
|
||||||
macro scope.
|
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;
|
var temp = #variable;
|
||||||
defer *variable = temp;
|
defer #variable = temp;
|
||||||
@body();
|
@body();
|
||||||
}
|
}
|
||||||
|
|
||||||
<*
|
<*
|
||||||
Swap two variables
|
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;
|
var temp = #a;
|
||||||
*a = *b;
|
#a = #b;
|
||||||
*b = temp;
|
#b = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
<*
|
<*
|
||||||
@@ -366,9 +367,12 @@ macro bool @ok(#expr) @builtin
|
|||||||
return true;
|
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);
|
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"
|
@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 @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 value "The value to store."
|
||||||
@param $alignment "The alignment to assume for the 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"
|
@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);
|
return $$unaligned_store(&#x, ($typeof(#x))value, $alignment);
|
||||||
}
|
|
||||||
|
|
||||||
macro @volatile_load(&x) @builtin
|
|
||||||
{
|
|
||||||
return $$volatile_load(x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<*
|
<*
|
||||||
@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
|
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 $ordering "atomic ordering of the load, defaults to SEQ_CONSISTENT"
|
||||||
@param $volatile "whether the load should be volatile, defaults to 'false'"
|
@param $volatile "whether the load should be volatile, defaults to 'false'"
|
||||||
@return "returns the value of x"
|
@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.RELEASE "Release ordering is not valid for load."
|
||||||
@require $ordering != AtomicOrdering.ACQUIRE_RELEASE "Acquire release 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 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"
|
|
||||||
*>
|
*>
|
||||||
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 value "the value to store."
|
||||||
@param $ordering "the atomic ordering of the store, defaults to SEQ_CONSISTENT"
|
@param $ordering "the atomic ordering of the store, defaults to SEQ_CONSISTENT"
|
||||||
@param $volatile "whether the store should be volatile, defaults to 'false'"
|
@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 "Acquire ordering is not valid for store."
|
||||||
@require $ordering != AtomicOrdering.ACQUIRE_RELEASE "Acquire release 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_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 @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 @assign_to(#value1, #value2) @const => $assignable(#value1, $typeof(#value2));
|
||||||
|
macro bool @is_lvalue(#value) => $defined(#value = #value);
|
||||||
|
|
||||||
macro promote_int(x)
|
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 @h2(x, y, z) => x ^ (y ^ z);
|
||||||
macro @i(x, y, z) => y ^ (x | ~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 += #f(b, c, d) + *(uint *)&ptr[n * 4] + t;
|
||||||
*a = (*a << s) | ((*a & 0xffffffff) >> (32 - s));
|
*a = (*a << s) | ((*a & 0xffffffff) >> (32 - s));
|
||||||
@@ -133,76 +133,76 @@ fn char* body(Md5* ctx, void* data, usz size)
|
|||||||
saved_d = d;
|
saved_d = d;
|
||||||
|
|
||||||
/* Round 1 */
|
/* Round 1 */
|
||||||
@step(@f, a, b, c, d, ptr, 0, 0xd76aa478, 7) ;
|
@step(@f, &a, b, c, d, ptr, 0, 0xd76aa478, 7) ;
|
||||||
@step(@f, d, a, b, c, ptr, 1, 0xe8c7b756, 12) ;
|
@step(@f, &d, a, b, c, ptr, 1, 0xe8c7b756, 12) ;
|
||||||
@step(@f, c, d, a, b, ptr, 2, 0x242070db, 17) ;
|
@step(@f, &c, d, a, b, ptr, 2, 0x242070db, 17) ;
|
||||||
@step(@f, b, c, d, a, ptr, 3, 0xc1bdceee, 22) ;
|
@step(@f, &b, c, d, a, ptr, 3, 0xc1bdceee, 22) ;
|
||||||
@step(@f, a, b, c, d, ptr, 4, 0xf57c0faf, 7) ;
|
@step(@f, &a, b, c, d, ptr, 4, 0xf57c0faf, 7) ;
|
||||||
@step(@f, d, a, b, c, ptr, 5, 0x4787c62a, 12) ;
|
@step(@f, &d, a, b, c, ptr, 5, 0x4787c62a, 12) ;
|
||||||
@step(@f, c, d, a, b, ptr, 6, 0xa8304613, 17) ;
|
@step(@f, &c, d, a, b, ptr, 6, 0xa8304613, 17) ;
|
||||||
@step(@f, b, c, d, a, ptr, 7, 0xfd469501, 22) ;
|
@step(@f, &b, c, d, a, ptr, 7, 0xfd469501, 22) ;
|
||||||
@step(@f, a, b, c, d, ptr, 8, 0x698098d8, 7) ;
|
@step(@f, &a, b, c, d, ptr, 8, 0x698098d8, 7) ;
|
||||||
@step(@f, d, a, b, c, ptr, 9, 0x8b44f7af, 12) ;
|
@step(@f, &d, a, b, c, ptr, 9, 0x8b44f7af, 12) ;
|
||||||
@step(@f, c, d, a, b, ptr, 10, 0xffff5bb1, 17);
|
@step(@f, &c, d, a, b, ptr, 10, 0xffff5bb1, 17);
|
||||||
@step(@f, b, c, d, a, ptr, 11, 0x895cd7be, 22);
|
@step(@f, &b, c, d, a, ptr, 11, 0x895cd7be, 22);
|
||||||
@step(@f, a, b, c, d, ptr, 12, 0x6b901122, 7) ;
|
@step(@f, &a, b, c, d, ptr, 12, 0x6b901122, 7) ;
|
||||||
@step(@f, d, a, b, c, ptr, 13, 0xfd987193, 12);
|
@step(@f, &d, a, b, c, ptr, 13, 0xfd987193, 12);
|
||||||
@step(@f, c, d, a, b, ptr, 14, 0xa679438e, 17);
|
@step(@f, &c, d, a, b, ptr, 14, 0xa679438e, 17);
|
||||||
@step(@f, b, c, d, a, ptr, 15, 0x49b40821, 22);
|
@step(@f, &b, c, d, a, ptr, 15, 0x49b40821, 22);
|
||||||
|
|
||||||
/* Round 2 */
|
/* Round 2 */
|
||||||
@step(@g, a, b, c, d, ptr, 1, 0xf61e2562, 5) ;
|
@step(@g, &a, b, c, d, ptr, 1, 0xf61e2562, 5) ;
|
||||||
@step(@g, d, a, b, c, ptr, 6, 0xc040b340, 9) ;
|
@step(@g, &d, a, b, c, ptr, 6, 0xc040b340, 9) ;
|
||||||
@step(@g, c, d, a, b, ptr, 11, 0x265e5a51, 14);
|
@step(@g, &c, d, a, b, ptr, 11, 0x265e5a51, 14);
|
||||||
@step(@g, b, c, d, a, ptr, 0, 0xe9b6c7aa, 20) ;
|
@step(@g, &b, c, d, a, ptr, 0, 0xe9b6c7aa, 20) ;
|
||||||
@step(@g, a, b, c, d, ptr, 5, 0xd62f105d, 5) ;
|
@step(@g, &a, b, c, d, ptr, 5, 0xd62f105d, 5) ;
|
||||||
@step(@g, d, a, b, c, ptr, 10, 0x02441453, 9) ;
|
@step(@g, &d, a, b, c, ptr, 10, 0x02441453, 9) ;
|
||||||
@step(@g, c, d, a, b, ptr, 15, 0xd8a1e681, 14);
|
@step(@g, &c, d, a, b, ptr, 15, 0xd8a1e681, 14);
|
||||||
@step(@g, b, c, d, a, ptr, 4, 0xe7d3fbc8, 20) ;
|
@step(@g, &b, c, d, a, ptr, 4, 0xe7d3fbc8, 20) ;
|
||||||
@step(@g, a, b, c, d, ptr, 9, 0x21e1cde6, 5) ;
|
@step(@g, &a, b, c, d, ptr, 9, 0x21e1cde6, 5) ;
|
||||||
@step(@g, d, a, b, c, ptr, 14, 0xc33707d6, 9) ;
|
@step(@g, &d, a, b, c, ptr, 14, 0xc33707d6, 9) ;
|
||||||
@step(@g, c, d, a, b, ptr, 3, 0xf4d50d87, 14) ;
|
@step(@g, &c, d, a, b, ptr, 3, 0xf4d50d87, 14) ;
|
||||||
@step(@g, b, c, d, a, ptr, 8, 0x455a14ed, 20) ;
|
@step(@g, &b, c, d, a, ptr, 8, 0x455a14ed, 20) ;
|
||||||
@step(@g, a, b, c, d, ptr, 13, 0xa9e3e905, 5) ;
|
@step(@g, &a, b, c, d, ptr, 13, 0xa9e3e905, 5) ;
|
||||||
@step(@g, d, a, b, c, ptr, 2, 0xfcefa3f8, 9) ;
|
@step(@g, &d, a, b, c, ptr, 2, 0xfcefa3f8, 9) ;
|
||||||
@step(@g, c, d, a, b, ptr, 7, 0x676f02d9, 14) ;
|
@step(@g, &c, d, a, b, ptr, 7, 0x676f02d9, 14) ;
|
||||||
@step(@g, b, c, d, a, ptr, 12, 0x8d2a4c8a, 20);
|
@step(@g, &b, c, d, a, ptr, 12, 0x8d2a4c8a, 20);
|
||||||
|
|
||||||
/* Round 3 */
|
/* Round 3 */
|
||||||
@step(@h, a, b, c, d, ptr, 5, 0xfffa3942, 4);
|
@step(@h, &a, b, c, d, ptr, 5, 0xfffa3942, 4);
|
||||||
@step(@h2, d, a, b, c, ptr, 8, 0x8771f681, 11);
|
@step(@h2, &d, a, b, c, ptr, 8, 0x8771f681, 11);
|
||||||
@step(@h, c, d, a, b, ptr, 11, 0x6d9d6122, 16);
|
@step(@h, &c, d, a, b, ptr, 11, 0x6d9d6122, 16);
|
||||||
@step(@h2, b, c, d, a, ptr, 14, 0xfde5380c, 23);
|
@step(@h2, &b, c, d, a, ptr, 14, 0xfde5380c, 23);
|
||||||
@step(@h, a, b, c, d, ptr, 1, 0xa4beea44, 4);
|
@step(@h, &a, b, c, d, ptr, 1, 0xa4beea44, 4);
|
||||||
@step(@h2, d, a, b, c, ptr, 4, 0x4bdecfa9, 11);
|
@step(@h2, &d, a, b, c, ptr, 4, 0x4bdecfa9, 11);
|
||||||
@step(@h, c, d, a, b, ptr, 7, 0xf6bb4b60, 16);
|
@step(@h, &c, d, a, b, ptr, 7, 0xf6bb4b60, 16);
|
||||||
@step(@h2, b, c, d, a, ptr, 10, 0xbebfbc70, 23);
|
@step(@h2, &b, c, d, a, ptr, 10, 0xbebfbc70, 23);
|
||||||
@step(@h, a, b, c, d, ptr, 13, 0x289b7ec6, 4) ;
|
@step(@h, &a, b, c, d, ptr, 13, 0x289b7ec6, 4) ;
|
||||||
@step(@h2, d, a, b, c, ptr, 0, 0xeaa127fa, 11) ;
|
@step(@h2, &d, a, b, c, ptr, 0, 0xeaa127fa, 11) ;
|
||||||
@step(@h, c, d, a, b, ptr, 3, 0xd4ef3085, 16) ;
|
@step(@h, &c, d, a, b, ptr, 3, 0xd4ef3085, 16) ;
|
||||||
@step(@h2, b, c, d, a, ptr, 6, 0x04881d05, 23) ;
|
@step(@h2, &b, c, d, a, ptr, 6, 0x04881d05, 23) ;
|
||||||
@step(@h, a, b, c, d, ptr, 9, 0xd9d4d039, 4) ;
|
@step(@h, &a, b, c, d, ptr, 9, 0xd9d4d039, 4) ;
|
||||||
@step(@h2, d, a, b, c, ptr, 12, 0xe6db99e5, 11) ;
|
@step(@h2, &d, a, b, c, ptr, 12, 0xe6db99e5, 11) ;
|
||||||
@step(@h, c, d, a, b, ptr, 15, 0x1fa27cf8, 16) ;
|
@step(@h, &c, d, a, b, ptr, 15, 0x1fa27cf8, 16) ;
|
||||||
@step(@h2, b, c, d, a, ptr, 2, 0xc4ac5665, 23) ;
|
@step(@h2, &b, c, d, a, ptr, 2, 0xc4ac5665, 23) ;
|
||||||
|
|
||||||
/* Round 4 */
|
/* Round 4 */
|
||||||
@step(@i, a, b, c, d, ptr, 0, 0xf4292244, 6) ;
|
@step(@i, &a, b, c, d, ptr, 0, 0xf4292244, 6) ;
|
||||||
@step(@i, d, a, b, c, ptr, 7, 0x432aff97, 10) ;
|
@step(@i, &d, a, b, c, ptr, 7, 0x432aff97, 10) ;
|
||||||
@step(@i, c, d, a, b, ptr, 14, 0xab9423a7, 15) ;
|
@step(@i, &c, d, a, b, ptr, 14, 0xab9423a7, 15) ;
|
||||||
@step(@i, b, c, d, a, ptr, 5, 0xfc93a039, 21) ;
|
@step(@i, &b, c, d, a, ptr, 5, 0xfc93a039, 21) ;
|
||||||
@step(@i, a, b, c, d, ptr, 12, 0x655b59c3, 6) ;
|
@step(@i, &a, b, c, d, ptr, 12, 0x655b59c3, 6) ;
|
||||||
@step(@i, d, a, b, c, ptr, 3, 0x8f0ccc92, 10) ;
|
@step(@i, &d, a, b, c, ptr, 3, 0x8f0ccc92, 10) ;
|
||||||
@step(@i, c, d, a, b, ptr, 10, 0xffeff47d, 15) ;
|
@step(@i, &c, d, a, b, ptr, 10, 0xffeff47d, 15) ;
|
||||||
@step(@i, b, c, d, a, ptr, 1, 0x85845dd1, 21) ;
|
@step(@i, &b, c, d, a, ptr, 1, 0x85845dd1, 21) ;
|
||||||
@step(@i, a, b, c, d, ptr, 8, 0x6fa87e4f, 6) ;
|
@step(@i, &a, b, c, d, ptr, 8, 0x6fa87e4f, 6) ;
|
||||||
@step(@i, d, a, b, c, ptr, 15, 0xfe2ce6e0, 10) ;
|
@step(@i, &d, a, b, c, ptr, 15, 0xfe2ce6e0, 10) ;
|
||||||
@step(@i, c, d, a, b, ptr, 6, 0xa3014314, 15) ;
|
@step(@i, &c, d, a, b, ptr, 6, 0xa3014314, 15) ;
|
||||||
@step(@i, b, c, d, a, ptr, 13, 0x4e0811a1, 21) ;
|
@step(@i, &b, c, d, a, ptr, 13, 0x4e0811a1, 21) ;
|
||||||
@step(@i, a, b, c, d, ptr, 4, 0xf7537e82, 6) ;
|
@step(@i, &a, b, c, d, ptr, 4, 0xf7537e82, 6) ;
|
||||||
@step(@i, d, a, b, c, ptr, 11, 0xbd3af235, 10) ;
|
@step(@i, &d, a, b, c, ptr, 11, 0xbd3af235, 10) ;
|
||||||
@step(@i, c, d, a, b, ptr, 2, 0x2ad7d2bb, 15) ;
|
@step(@i, &c, d, a, b, ptr, 2, 0x2ad7d2bb, 15) ;
|
||||||
@step(@i, b, c, d, a, ptr, 9, 0xeb86d391, 21) ;
|
@step(@i, &b, c, d, a, ptr, 9, 0xeb86d391, 21) ;
|
||||||
|
|
||||||
a += saved_a;
|
a += saved_a;
|
||||||
b += saved_b;
|
b += saved_b;
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ macro usz! write_all(stream, char[] buffer)
|
|||||||
return n;
|
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);
|
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);
|
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);
|
return read_byte_using_read(*s);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ $endif
|
|||||||
return (usz)n;
|
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
|
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
|
- Include `@name` when searching for possible matches to `name` in the error message. #1779
|
||||||
- Improve `@param` parse errors #1777
|
- Improve `@param` parse errors #1777
|
||||||
- Improved `#foo` resolution inside of the compiler.
|
- Improved `#foo` resolution inside of the compiler.
|
||||||
|
- Deprecated '&' macro arguments.
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
- Fix case trying to initialize a `char[*]*` from a String.
|
- Fix case trying to initialize a `char[*]*` from a String.
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
module test;
|
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;
|
var temp = #a;
|
||||||
*a = *b;
|
#a = #b;
|
||||||
*b = temp;
|
#b = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void main()
|
fn void main()
|
||||||
@@ -16,5 +16,5 @@ fn void main()
|
|||||||
int x = 123;
|
int x = 123;
|
||||||
int y = 456;
|
int y = 456;
|
||||||
@swap(x, y);
|
@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_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_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_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_analyse_main_function(SemaContext *context, Decl *decl);
|
||||||
static inline bool sema_check_param_uniqueness_and_type(SemaContext *context, Decl **decls, Decl *current,
|
static inline bool sema_check_param_uniqueness_and_type(SemaContext *context, Decl **decls, Decl *current,
|
||||||
unsigned current_index, unsigned count);
|
unsigned current_index, unsigned count);
|
||||||
@@ -1085,7 +1085,7 @@ ERROR:
|
|||||||
return decl_poison(decl);
|
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;
|
Variadic variadic_type = sig->variadic;
|
||||||
Decl **params = sig->params;
|
Decl **params = sig->params;
|
||||||
@@ -1149,7 +1149,7 @@ static inline bool sema_analyse_signature(SemaContext *context, Signature *sig,
|
|||||||
case VARDECL_PARAM_REF:
|
case VARDECL_PARAM_REF:
|
||||||
inferred_type = type_get_ptr(method_parent->type);
|
inferred_type = type_get_ptr(method_parent->type);
|
||||||
param->var.not_null = true;
|
param->var.not_null = true;
|
||||||
if (!is_macro) param->var.kind = VARDECL_PARAM;
|
param->var.kind = VARDECL_PARAM;
|
||||||
break;
|
break;
|
||||||
case VARDECL_PARAM:
|
case VARDECL_PARAM:
|
||||||
case VARDECL_PARAM_EXPR:
|
case VARDECL_PARAM_EXPR:
|
||||||
@@ -1224,6 +1224,10 @@ static inline bool sema_analyse_signature(SemaContext *context, Signature *sig,
|
|||||||
switch (var_kind)
|
switch (var_kind)
|
||||||
{
|
{
|
||||||
case VARDECL_PARAM_REF:
|
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))
|
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?",
|
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))
|
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);
|
return decl_poison(param);
|
||||||
}
|
}
|
||||||
FALLTHROUGH;
|
FALLTHROUGH;
|
||||||
@@ -1333,7 +1337,9 @@ bool sema_analyse_function_signature(SemaContext *context, Decl *func_decl, Type
|
|||||||
// Get param count and variadic type
|
// Get param count and variadic type
|
||||||
Decl **params = signature->params;
|
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;
|
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 (!sema_analyse_func_macro(context, decl, ATTR_MACRO, erase_decl)) return false;
|
||||||
if (*erase_decl) return true;
|
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,
|
if (!sema_analyse_signature(context, &decl->func_decl.signature,
|
||||||
type_infoptrzero(decl->func_decl.type_parent),
|
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)
|
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_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_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_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_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_identifier(SemaContext *context, Type *to, Expr *expr);
|
||||||
static inline bool sema_expr_analyse_ct_identifier(SemaContext *context, Expr *expr, CheckType check);
|
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_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_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_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_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,
|
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);
|
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);
|
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,
|
static bool sema_binary_is_unsigned_always_same_comparison(SemaContext *context, Expr *expr, Expr *left, Expr *right,
|
||||||
Type *lhs_type, Type *rhs_type);
|
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);
|
static void sema_binary_unify_voidptr(SemaContext *context, Expr *left, Expr *right, Type **left_type_ref, Type **right_type_ref);
|
||||||
|
|
||||||
// -- function helper functions
|
// -- 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)
|
switch (expr->expr_kind)
|
||||||
{
|
{
|
||||||
case EXPR_SWIZZLE:
|
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.");
|
RETURN_SEMA_ERROR(expr, "You cannot use swizzling to assign to multiple elements, use element-wise assign instead.");
|
||||||
case EXPR_LAMBDA:
|
case EXPR_LAMBDA:
|
||||||
case EXPR_EMBED:
|
case EXPR_EMBED:
|
||||||
|
if (failed_ref) goto FAILED_REF;
|
||||||
RETURN_SEMA_ERROR(expr, "This expression is a value and cannot be assigned to.");
|
RETURN_SEMA_ERROR(expr, "This expression is a value and cannot be assigned to.");
|
||||||
case EXPR_CT_IDENT:
|
case EXPR_CT_IDENT:
|
||||||
return true;
|
return true;
|
||||||
case EXPR_EXT_TRUNC:
|
case EXPR_EXT_TRUNC:
|
||||||
case EXPR_INT_TO_BOOL:
|
case EXPR_INT_TO_BOOL:
|
||||||
case EXPR_DISCARD:
|
case EXPR_DISCARD:
|
||||||
return false;
|
if (failed_ref) goto FAILED_REF;
|
||||||
|
goto ERR;
|
||||||
case EXPR_OTHER_CONTEXT:
|
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:
|
case EXPR_IDENTIFIER:
|
||||||
{
|
{
|
||||||
Decl *decl = expr->identifier_expr.decl;
|
Decl *decl = expr->identifier_expr.decl;
|
||||||
if (decl->decl_kind != DECL_VAR)
|
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));
|
RETURN_SEMA_ERROR(top_expr, "You cannot assign a value to %s.", decl_to_a_name(decl));
|
||||||
}
|
}
|
||||||
if (decl->var.kind == VARDECL_CONST)
|
if (decl->var.kind == VARDECL_CONST)
|
||||||
{
|
{
|
||||||
|
if (failed_ref) goto FAILED_REF;
|
||||||
RETURN_SEMA_ERROR(top_expr, "You cannot assign to a constant.");
|
RETURN_SEMA_ERROR(top_expr, "You cannot assign to a constant.");
|
||||||
}
|
}
|
||||||
decl = decl_raw(decl);
|
decl = decl_raw(decl);
|
||||||
switch (decl->var.kind)
|
switch (decl->var.kind)
|
||||||
{
|
{
|
||||||
case VARDECL_PARAM_REF:
|
case VARDECL_PARAM_REF:
|
||||||
SEMA_ERROR(top_expr, "You cannot assign to a ref parameter.");
|
if (failed_ref) goto FAILED_REF;
|
||||||
return false;
|
RETURN_SEMA_ERROR(top_expr, "You cannot assign to a ref parameter.");
|
||||||
case VARDECL_LOCAL_CT:
|
case VARDECL_LOCAL_CT:
|
||||||
case VARDECL_LOCAL_CT_TYPE:
|
case VARDECL_LOCAL_CT_TYPE:
|
||||||
case VARDECL_LOCAL:
|
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 (expr->unary_expr.operator != UNARYOP_DEREF) goto ERR;
|
||||||
if (IS_OPTIONAL(expr))
|
if (IS_OPTIONAL(expr))
|
||||||
{
|
{
|
||||||
SEMA_ERROR(top_expr, "You cannot assign to a dereferenced optional.");
|
if (failed_ref) goto FAILED_REF;
|
||||||
return false;
|
RETURN_SEMA_ERROR(top_expr, "You cannot assign to a dereferenced optional.");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case EXPR_BITACCESS:
|
case EXPR_BITACCESS:
|
||||||
case EXPR_ACCESS:
|
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;
|
goto CHECK_OPTIONAL;
|
||||||
case EXPR_SUBSCRIPT:
|
case EXPR_SUBSCRIPT:
|
||||||
case EXPR_SLICE:
|
case EXPR_SLICE:
|
||||||
@@ -509,12 +514,13 @@ static bool sema_binary_is_expr_lvalue(SemaContext *context, Expr *top_expr, Exp
|
|||||||
case EXPR_SUBSCRIPT_ADDR:
|
case EXPR_SUBSCRIPT_ADDR:
|
||||||
goto CHECK_OPTIONAL;
|
goto CHECK_OPTIONAL;
|
||||||
case EXPR_HASH_IDENT:
|
case EXPR_HASH_IDENT:
|
||||||
|
if (failed_ref) goto FAILED_REF;
|
||||||
RETURN_SEMA_ERROR(top_expr, "You cannot assign to an unevaluated expression.");
|
RETURN_SEMA_ERROR(top_expr, "You cannot assign to an unevaluated expression.");
|
||||||
case EXPR_EXPRESSION_LIST:
|
case EXPR_EXPRESSION_LIST:
|
||||||
if (!vec_size(expr->expression_list)) return false;
|
if (!vec_size(expr->expression_list)) goto ERR;
|
||||||
return sema_binary_is_expr_lvalue(context, top_expr, VECLAST(expr->expression_list));
|
return sema_binary_is_expr_lvalue(context, top_expr, VECLAST(expr->expression_list), failed_ref);
|
||||||
goto CHECK_OPTIONAL;
|
|
||||||
case EXPR_CONST:
|
case EXPR_CONST:
|
||||||
|
if (failed_ref) goto FAILED_REF;
|
||||||
RETURN_SEMA_ERROR(top_expr, "You cannot assign to a constant expression.");
|
RETURN_SEMA_ERROR(top_expr, "You cannot assign to a constant expression.");
|
||||||
case EXPR_POISONED:
|
case EXPR_POISONED:
|
||||||
case EXPR_ADDR_CONVERSION:
|
case EXPR_ADDR_CONVERSION:
|
||||||
@@ -594,15 +600,18 @@ static bool sema_binary_is_expr_lvalue(SemaContext *context, Expr *top_expr, Exp
|
|||||||
}
|
}
|
||||||
UNREACHABLE
|
UNREACHABLE
|
||||||
ERR:
|
ERR:
|
||||||
SEMA_ERROR(top_expr, "An assignable expression, like a variable, was expected here.");
|
if (failed_ref) goto FAILED_REF;
|
||||||
return false;
|
RETURN_SEMA_ERROR(top_expr, "An assignable expression, like a variable, was expected here.");
|
||||||
CHECK_OPTIONAL:
|
CHECK_OPTIONAL:
|
||||||
if (IS_OPTIONAL(expr))
|
if (IS_OPTIONAL(expr))
|
||||||
{
|
{
|
||||||
|
if (failed_ref) goto FAILED_REF;
|
||||||
RETURN_SEMA_ERROR(top_expr, "You cannot assign to an optional value.");
|
RETURN_SEMA_ERROR(top_expr, "You cannot assign to an optional value.");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
FAILED_REF:
|
||||||
|
*failed_ref = true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool expr_may_ref(Expr *expr)
|
static bool expr_may_ref(Expr *expr)
|
||||||
@@ -744,10 +753,10 @@ static bool expr_may_ref(Expr *expr)
|
|||||||
UNREACHABLE
|
UNREACHABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sema_expr_check_assign(SemaContext *context, Expr *expr)
|
bool sema_expr_check_assign(SemaContext *context, Expr *expr, bool *failed_ref)
|
||||||
{
|
{
|
||||||
Expr *inner;
|
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)
|
if (expr->expr_kind == EXPR_SUBSCRIPT)
|
||||||
{
|
{
|
||||||
inner = exprptr(expr->subscript_expr.expr);
|
inner = exprptr(expr->subscript_expr.expr);
|
||||||
@@ -766,8 +775,7 @@ CHECK_INNER:
|
|||||||
Decl *decl = inner->identifier_expr.decl;
|
Decl *decl = inner->identifier_expr.decl;
|
||||||
if (decl->decl_kind != DECL_VAR) return true;
|
if (decl->decl_kind != DECL_VAR) return true;
|
||||||
if (!decl->var.in_param) return true;
|
if (!decl->var.in_param) return true;
|
||||||
SEMA_ERROR(inner, "'in' parameters may not be assigned to.");
|
RETURN_SEMA_ERROR(inner, "'in' parameters may not be assigned to.");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool sema_cast_ident_rvalue(SemaContext *context, Expr *expr)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
if (!sema_analyse_expr_address(context, arg)) return false;
|
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.");
|
SEMA_NOTE(definition, "The definition is here.");
|
||||||
return false;
|
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 (!sema_analyse_expr_check(context, subscripted, CHECK_VALUE)) return false;
|
||||||
|
|
||||||
// If it is an lvalue then check that it is assignable.
|
// 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.
|
// 2. Evaluate the index.
|
||||||
Expr *index = exprptr(expr->subscript_expr.index.expr);
|
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
|
* Analyse a = b
|
||||||
* @return true if analysis works
|
* @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;
|
if (!sema_expr_fold_hash(context, left)) return false;
|
||||||
// 1. Evaluate left side
|
// 1. Evaluate left side
|
||||||
@@ -5698,7 +5706,7 @@ static bool sema_expr_analyse_assign(SemaContext *context, Expr *expr, Expr *lef
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// 2. Check assignability
|
// 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);
|
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);
|
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))
|
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;
|
if (!sema_analyse_expr_lvalue(context, left)) return false;
|
||||||
|
|
||||||
// 2. Verify that the left side is assignable.
|
// 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;
|
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);
|
bool optional = IS_OPTIONAL(left) || IS_OPTIONAL(right);
|
||||||
|
|
||||||
// 2. Ensure the lhs side is assignable
|
// 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.
|
// 3. Only integers may be shifted.
|
||||||
if (!expr_both_any_integer_or_integer_vector(left, right)) return sema_type_error_on_binop(context, expr);
|
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;
|
if (!sema_analyse_expr_lvalue(context, inner)) return false;
|
||||||
|
|
||||||
// 2. Assert it's an l-value
|
// 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.
|
// 3. This might be a $foo, if to handle it.
|
||||||
if (inner->expr_kind == EXPR_CT_IDENT)
|
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;
|
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);
|
if (expr->binary_expr.operator == BINARYOP_ELSE) return sema_expr_analyse_or_error(context, expr);
|
||||||
ASSERT_SPAN(expr, expr->resolve_status == RESOLVE_RUNNING);
|
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:
|
case BINARYOP_CT_AND:
|
||||||
return sema_expr_analyse_ct_and_or(context, expr, left, right);
|
return sema_expr_analyse_ct_and_or(context, expr, left, right);
|
||||||
case BINARYOP_ASSIGN:
|
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:
|
case BINARYOP_MULT:
|
||||||
return sema_expr_analyse_mult(context, expr, left, right);
|
return sema_expr_analyse_mult(context, expr, left, right);
|
||||||
case BINARYOP_ADD:
|
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_DEFAULT_ARG:
|
||||||
case EXPR_NAMED_ARGUMENT:
|
case EXPR_NAMED_ARGUMENT:
|
||||||
UNREACHABLE
|
UNREACHABLE
|
||||||
case EXPR_CT_ARG:
|
|
||||||
FALLTHROUGH;
|
|
||||||
case EXPR_BINARY:
|
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_BITACCESS:
|
||||||
case EXPR_BITASSIGN:
|
case EXPR_BITASSIGN:
|
||||||
case EXPR_COMPOUND_LITERAL:
|
case EXPR_COMPOUND_LITERAL:
|
||||||
@@ -9546,7 +9560,7 @@ static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr,
|
|||||||
case EXPR_CT_EVAL:
|
case EXPR_CT_EVAL:
|
||||||
return sema_expr_analyse_ct_eval(context, expr, check);
|
return sema_expr_analyse_ct_eval(context, expr, check);
|
||||||
case EXPR_BINARY:
|
case EXPR_BINARY:
|
||||||
return sema_expr_analyse_binary(context, expr);
|
return sema_expr_analyse_binary(context, expr, NULL);
|
||||||
case EXPR_TERNARY:
|
case EXPR_TERNARY:
|
||||||
return sema_expr_analyse_ternary(context, NULL, expr);
|
return sema_expr_analyse_ternary(context, NULL, expr);
|
||||||
case EXPR_UNARY:
|
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);
|
bool sema_bit_assignment_check(SemaContext *context, Expr *right, Decl *member);
|
||||||
CondResult sema_check_comp_time_bool(SemaContext *context, Expr *expr);
|
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);
|
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);
|
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);
|
ConstInitializer *sema_merge_bitstruct_const_initializers(ConstInitializer *lhs, ConstInitializer *rhs, BinaryOp op);
|
||||||
|
|||||||
@@ -9,12 +9,16 @@ fn void main()
|
|||||||
{
|
{
|
||||||
Foo* foo;
|
Foo* foo;
|
||||||
float[<4>] a @align(1) @noinit;
|
float[<4>] a @align(1) @noinit;
|
||||||
|
float[<4>] b @align(1) @noinit;
|
||||||
|
|
||||||
a = *(float[<4>]*)&foo.a;
|
a = *(float[<4>]*)&foo.a;
|
||||||
*(float[<4>]*)&foo.a = a;
|
*(float[<4>]*)&foo.a = a;
|
||||||
|
|
||||||
a = $$unaligned_load((float[<4>]*)&foo.a, 1);
|
a = $$unaligned_load((float[<4>]*)&foo.a, 1);
|
||||||
$$unaligned_store((float[<4>]*)&foo.a, 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
|
/* #expect: test.ll
|
||||||
@@ -23,6 +27,8 @@ define void @test.main() #0 {
|
|||||||
entry:
|
entry:
|
||||||
%foo = alloca ptr, align 8
|
%foo = alloca ptr, align 8
|
||||||
%a = alloca <4 x float>, align 1
|
%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
|
store ptr null, ptr %foo, align 8
|
||||||
%0 = load ptr, ptr %foo, align 8
|
%0 = load ptr, ptr %foo, align 8
|
||||||
%1 = load <4 x float>, ptr %0, align 16
|
%1 = load <4 x float>, ptr %0, align 16
|
||||||
@@ -36,5 +42,13 @@ entry:
|
|||||||
%6 = load ptr, ptr %foo, align 8
|
%6 = load ptr, ptr %foo, align 8
|
||||||
%7 = load <4 x float>, ptr %a, align 1
|
%7 = load <4 x float>, ptr %a, align 1
|
||||||
store <4 x float> %7, ptr %6, 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
|
ret void
|
||||||
}
|
}
|
||||||
@@ -31,42 +31,30 @@ define void @test.main() #0 !dbg !8 {
|
|||||||
entry:
|
entry:
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
%x = alloca i32, align 4
|
%x = alloca i32, align 4
|
||||||
%x1 = alloca ptr, align 8
|
|
||||||
%y = alloca i32, align 4
|
%y = alloca i32, align 4
|
||||||
%x2 = alloca ptr, align 8
|
|
||||||
%x3 = alloca ptr, align 8
|
|
||||||
%value = alloca i32, align 4
|
%value = alloca i32, align 4
|
||||||
%x4 = alloca ptr, align 8
|
%value2 = alloca i32, align 4
|
||||||
%value6 = alloca i32, align 4
|
|
||||||
%varargslots = alloca [1 x %any], align 16
|
%varargslots = alloca [1 x %any], align 16
|
||||||
%retparam = alloca i64, align 8
|
%retparam = alloca i64, align 8
|
||||||
store i32 111, ptr %a, align 4, !dbg !15
|
store i32 111, ptr %a, align 4, !dbg !15
|
||||||
store ptr %a, ptr %x1, align 8
|
%0 = load atomic i32, ptr %a seq_cst, align 4, !dbg !18
|
||||||
%0 = load ptr, ptr %x1, align 8, !dbg !18
|
store i32 %0, ptr %x, align 4, !dbg !18
|
||||||
%1 = load atomic i32, ptr %0 seq_cst, align 4, !dbg !18
|
%1 = load atomic volatile i32, ptr %a monotonic, align 4, !dbg !24
|
||||||
store i32 %1, ptr %x, align 4, !dbg !18
|
store i32 %1, ptr %y, align 4, !dbg !24
|
||||||
store ptr %a, ptr %x2, align 8
|
%2 = load i32, ptr %x, align 4, !dbg !27
|
||||||
%2 = load ptr, ptr %x2, align 8, !dbg !24
|
%add = add i32 123, %2, !dbg !28
|
||||||
%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
|
|
||||||
store i32 %add, ptr %value, align 4
|
store i32 %add, ptr %value, align 4
|
||||||
%5 = load ptr, ptr %x3, align 8, !dbg !29
|
%3 = load i32, ptr %value, align 4, !dbg !29
|
||||||
%6 = load i32, ptr %value, align 4, !dbg !29
|
store atomic i32 %3, ptr %a seq_cst, align 4, !dbg !29
|
||||||
store atomic i32 %6, ptr %5 seq_cst, align 4, !dbg !29
|
%4 = load i32, ptr %y, align 4, !dbg !32
|
||||||
store ptr %a, ptr %x4, align 8
|
%add1 = add i32 33, %4, !dbg !33
|
||||||
%7 = load i32, ptr %y, align 4, !dbg !32
|
store i32 %add1, ptr %value2, align 4
|
||||||
%add5 = add i32 33, %7, !dbg !33
|
%5 = load i32, ptr %value2, align 4, !dbg !34
|
||||||
store i32 %add5, ptr %value6, align 4
|
store atomic volatile i32 %5, ptr %a monotonic, align 4, !dbg !34
|
||||||
%8 = load ptr, ptr %x4, align 8, !dbg !34
|
%6 = insertvalue %any undef, ptr %a, 0, !dbg !37
|
||||||
%9 = load i32, ptr %value6, align 4, !dbg !34
|
%7 = insertvalue %any %6, i64 ptrtoint (ptr @"$ct.int" to i64), 1, !dbg !37
|
||||||
store atomic volatile i32 %9, ptr %8 monotonic, align 4, !dbg !34
|
store %any %7, ptr %varargslots, align 16, !dbg !37
|
||||||
%10 = insertvalue %any undef, ptr %a, 0, !dbg !37
|
%8 = call i64 @std.io.printfn(ptr %retparam, ptr @.str, i64 2, ptr %varargslots, i64 1), !dbg !38
|
||||||
%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
|
|
||||||
ret void, !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)
|
!22 = !DILocalVariable(name: "y", scope: !8, file: !7, line: 14, type: !13, align: 4)
|
||||||
!23 = !DILocation(line: 14, column: 6, scope: !8)
|
!23 = !DILocation(line: 14, column: 6, scope: !8)
|
||||||
!24 = !DILocation(
|
!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)
|
!26 = !DILocation(line: 14, column: 10, scope: !8)
|
||||||
!27 = !DILocation(line: 15, column: 25, scope: !8)
|
!27 = !DILocation(line: 15, column: 25, scope: !8)
|
||||||
!28 = !DILocation(line: 15, column: 19, scope: !8)
|
!28 = !DILocation(line: 15, column: 19, scope: !8)
|
||||||
!29 = !DILocation(
|
!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)
|
!31 = !DILocation(line: 15, column: 2, scope: !8)
|
||||||
!32 = !DILocation(line: 16, column: 24, scope: !8)
|
!32 = !DILocation(line: 16, column: 24, scope: !8)
|
||||||
!33 = !DILocation(line: 16, column: 19, scope: !8)
|
!33 = !DILocation(line: 16, column: 19, scope: !8)
|
||||||
!34 = !DILocation(
|
!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)
|
!36 = !DILocation(line: 16, column: 2, scope: !8)
|
||||||
!37 = !DILocation(line: 17, column: 20, scope: !8)
|
!37 = !DILocation(line: 17, column: 20, scope: !8)
|
||||||
!38 = !DILocation(line: 17, column: 2, 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)
|
!73 = !DILocalVariable(name: "name", arg: 3, scope: !66, file: !7, line: 33, type: !39)
|
||||||
!74 = !DILocation(line: 33, column: 63, scope: !66)
|
!74 = !DILocation(line: 33, column: 63, scope: !66)
|
||||||
!75 = !DILocation(line:
|
!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"
|
!77 = !DIFile(filename: "mem.c3"
|
||||||
!78 = !DILocation(line: 34, column: 10, scope: !66)
|
!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)
|
!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)
|
!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"
|
!153 = !DIFile(filename: "mem_allocator.c3"
|
||||||
!154 = !DILocation
|
!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
|
!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
|
!158 = !DILocation
|
||||||
!159 = !DILocation
|
!159 = !DILocation
|
||||||
!160 = !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 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'.
|
fn void foo9(int x, int x) {} // #error: Duplicate parameter name 'x'.
|
||||||
|
|
||||||
macro @foo($a, $b, $c, ...) {}
|
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()
|
fn void main()
|
||||||
{
|
{
|
||||||
@boba(;#hash_val, &foo, int $value, $Type)
|
@boba(;#hash_val, #foo, int $value, $Type)
|
||||||
{
|
{
|
||||||
io::printn("Now invoking hash");
|
io::printn("Now invoking hash");
|
||||||
#hash_val;
|
#hash_val;
|
||||||
#hash_val;
|
#hash_val;
|
||||||
*foo += $value;
|
#foo += $value;
|
||||||
io::printfn("The type was: %s", $Type.nameof);
|
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");
|
io::printn("Boba");
|
||||||
int a = 0;
|
int a = 0;
|
||||||
@@ -34,7 +34,6 @@ entry:
|
|||||||
%error_var8 = alloca i64, align 8
|
%error_var8 = alloca i64, align 8
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
%b = alloca i32, align 4
|
%b = alloca i32, align 4
|
||||||
%foo = alloca ptr, align 8
|
|
||||||
%len14 = alloca i64, align 8
|
%len14 = alloca i64, align 8
|
||||||
%error_var15 = alloca i64, align 8
|
%error_var15 = alloca i64, align 8
|
||||||
%retparam17 = alloca i64, align 8
|
%retparam17 = alloca i64, align 8
|
||||||
@@ -54,17 +53,13 @@ entry:
|
|||||||
%not_err = icmp eq i64 %1, 0
|
%not_err = icmp eq i64 %1, 0
|
||||||
%2 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
|
%2 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
|
||||||
br i1 %2, label %after_check, label %assign_optional
|
br i1 %2, label %after_check, label %assign_optional
|
||||||
|
|
||||||
assign_optional: ; preds = %entry
|
assign_optional: ; preds = %entry
|
||||||
store i64 %1, ptr %error_var, align 8
|
store i64 %1, ptr %error_var, align 8
|
||||||
br label %guard_block
|
br label %guard_block
|
||||||
|
|
||||||
after_check: ; preds = %entry
|
after_check: ; preds = %entry
|
||||||
br label %noerr_block
|
br label %noerr_block
|
||||||
|
|
||||||
guard_block: ; preds = %assign_optional
|
guard_block: ; preds = %assign_optional
|
||||||
br label %voiderr
|
br label %voiderr
|
||||||
|
|
||||||
noerr_block: ; preds = %after_check
|
noerr_block: ; preds = %after_check
|
||||||
%3 = load i64, ptr %retparam, align 8
|
%3 = load i64, ptr %retparam, align 8
|
||||||
store i64 %3, ptr %len, 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
|
%not_err3 = icmp eq i64 %4, 0
|
||||||
%5 = call i1 @llvm.expect.i1(i1 %not_err3, i1 true)
|
%5 = call i1 @llvm.expect.i1(i1 %not_err3, i1 true)
|
||||||
br i1 %5, label %after_check5, label %assign_optional4
|
br i1 %5, label %after_check5, label %assign_optional4
|
||||||
|
|
||||||
assign_optional4: ; preds = %noerr_block
|
assign_optional4: ; preds = %noerr_block
|
||||||
store i64 %4, ptr %error_var2, align 8
|
store i64 %4, ptr %error_var2, align 8
|
||||||
br label %guard_block6
|
br label %guard_block6
|
||||||
|
|
||||||
after_check5: ; preds = %noerr_block
|
after_check5: ; preds = %noerr_block
|
||||||
br label %noerr_block7
|
br label %noerr_block7
|
||||||
|
|
||||||
guard_block6: ; preds = %assign_optional4
|
guard_block6: ; preds = %assign_optional4
|
||||||
br label %voiderr
|
br label %voiderr
|
||||||
|
|
||||||
noerr_block7: ; preds = %after_check5
|
noerr_block7: ; preds = %after_check5
|
||||||
%6 = call i64 @std.io.File.flush(ptr %0)
|
%6 = call i64 @std.io.File.flush(ptr %0)
|
||||||
%not_err9 = icmp eq i64 %6, 0
|
%not_err9 = icmp eq i64 %6, 0
|
||||||
%7 = call i1 @llvm.expect.i1(i1 %not_err9, i1 true)
|
%7 = call i1 @llvm.expect.i1(i1 %not_err9, i1 true)
|
||||||
br i1 %7, label %after_check11, label %assign_optional10
|
br i1 %7, label %after_check11, label %assign_optional10
|
||||||
|
|
||||||
assign_optional10: ; preds = %noerr_block7
|
assign_optional10: ; preds = %noerr_block7
|
||||||
store i64 %6, ptr %error_var8, align 8
|
store i64 %6, ptr %error_var8, align 8
|
||||||
br label %guard_block12
|
br label %guard_block12
|
||||||
|
|
||||||
after_check11: ; preds = %noerr_block7
|
after_check11: ; preds = %noerr_block7
|
||||||
br label %noerr_block13
|
br label %noerr_block13
|
||||||
|
|
||||||
guard_block12: ; preds = %assign_optional10
|
guard_block12: ; preds = %assign_optional10
|
||||||
br label %voiderr
|
br label %voiderr
|
||||||
|
|
||||||
noerr_block13: ; preds = %after_check11
|
noerr_block13: ; preds = %after_check11
|
||||||
%8 = load i64, ptr %len, align 8
|
%8 = load i64, ptr %len, align 8
|
||||||
%add = add i64 %8, 1
|
%add = add i64 %8, 1
|
||||||
br label %voiderr
|
br label %voiderr
|
||||||
|
|
||||||
voiderr: ; preds = %noerr_block13, %guard_block12, %guard_block6, %guard_block
|
voiderr: ; preds = %noerr_block13, %guard_block12, %guard_block6, %guard_block
|
||||||
store i32 0, ptr %a, align 4
|
store i32 0, ptr %a, align 4
|
||||||
store i32 0, ptr %b, align 4
|
store i32 0, ptr %b, align 4
|
||||||
store ptr %b, ptr %foo, align 8
|
|
||||||
%9 = call ptr @std.io.stdout()
|
%9 = call ptr @std.io.stdout()
|
||||||
%10 = call i64 @std.io.File.write(ptr %retparam17, ptr %9, ptr @.str.1, i64 17)
|
%10 = call i64 @std.io.File.write(ptr %retparam17, ptr %9, ptr @.str.1, i64 17)
|
||||||
%not_err18 = icmp eq i64 %10, 0
|
%not_err18 = icmp eq i64 %10, 0
|
||||||
%11 = call i1 @llvm.expect.i1(i1 %not_err18, i1 true)
|
%11 = call i1 @llvm.expect.i1(i1 %not_err18, i1 true)
|
||||||
br i1 %11, label %after_check20, label %assign_optional19
|
br i1 %11, label %after_check20, label %assign_optional19
|
||||||
|
|
||||||
assign_optional19: ; preds = %voiderr
|
assign_optional19: ; preds = %voiderr
|
||||||
store i64 %10, ptr %error_var15, align 8
|
store i64 %10, ptr %error_var15, align 8
|
||||||
br label %guard_block21
|
br label %guard_block21
|
||||||
|
|
||||||
after_check20: ; preds = %voiderr
|
after_check20: ; preds = %voiderr
|
||||||
br label %noerr_block22
|
br label %noerr_block22
|
||||||
|
|
||||||
guard_block21: ; preds = %assign_optional19
|
guard_block21: ; preds = %assign_optional19
|
||||||
br label %voiderr36
|
br label %voiderr36
|
||||||
|
|
||||||
noerr_block22: ; preds = %after_check20
|
noerr_block22: ; preds = %after_check20
|
||||||
%12 = load i64, ptr %retparam17, align 8
|
%12 = load i64, ptr %retparam17, align 8
|
||||||
store i64 %12, ptr %len14, 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
|
%not_err24 = icmp eq i64 %13, 0
|
||||||
%14 = call i1 @llvm.expect.i1(i1 %not_err24, i1 true)
|
%14 = call i1 @llvm.expect.i1(i1 %not_err24, i1 true)
|
||||||
br i1 %14, label %after_check26, label %assign_optional25
|
br i1 %14, label %after_check26, label %assign_optional25
|
||||||
|
|
||||||
assign_optional25: ; preds = %noerr_block22
|
assign_optional25: ; preds = %noerr_block22
|
||||||
store i64 %13, ptr %error_var23, align 8
|
store i64 %13, ptr %error_var23, align 8
|
||||||
br label %guard_block27
|
br label %guard_block27
|
||||||
|
|
||||||
after_check26: ; preds = %noerr_block22
|
after_check26: ; preds = %noerr_block22
|
||||||
br label %noerr_block28
|
br label %noerr_block28
|
||||||
|
|
||||||
guard_block27: ; preds = %assign_optional25
|
guard_block27: ; preds = %assign_optional25
|
||||||
br label %voiderr36
|
br label %voiderr36
|
||||||
|
|
||||||
noerr_block28: ; preds = %after_check26
|
noerr_block28: ; preds = %after_check26
|
||||||
%15 = call i64 @std.io.File.flush(ptr %9)
|
%15 = call i64 @std.io.File.flush(ptr %9)
|
||||||
%not_err30 = icmp eq i64 %15, 0
|
%not_err30 = icmp eq i64 %15, 0
|
||||||
%16 = call i1 @llvm.expect.i1(i1 %not_err30, i1 true)
|
%16 = call i1 @llvm.expect.i1(i1 %not_err30, i1 true)
|
||||||
br i1 %16, label %after_check32, label %assign_optional31
|
br i1 %16, label %after_check32, label %assign_optional31
|
||||||
|
|
||||||
assign_optional31: ; preds = %noerr_block28
|
assign_optional31: ; preds = %noerr_block28
|
||||||
store i64 %15, ptr %error_var29, align 8
|
store i64 %15, ptr %error_var29, align 8
|
||||||
br label %guard_block33
|
br label %guard_block33
|
||||||
|
|
||||||
after_check32: ; preds = %noerr_block28
|
after_check32: ; preds = %noerr_block28
|
||||||
br label %noerr_block34
|
br label %noerr_block34
|
||||||
|
|
||||||
guard_block33: ; preds = %assign_optional31
|
guard_block33: ; preds = %assign_optional31
|
||||||
br label %voiderr36
|
br label %voiderr36
|
||||||
|
|
||||||
noerr_block34: ; preds = %after_check32
|
noerr_block34: ; preds = %after_check32
|
||||||
%17 = load i64, ptr %len14, align 8
|
%17 = load i64, ptr %len14, align 8
|
||||||
%add35 = add i64 %17, 1
|
%add35 = add i64 %17, 1
|
||||||
br label %voiderr36
|
br label %voiderr36
|
||||||
|
|
||||||
voiderr36: ; preds = %noerr_block34, %guard_block33, %guard_block27, %guard_block21
|
voiderr36: ; preds = %noerr_block34, %guard_block33, %guard_block27, %guard_block21
|
||||||
%18 = insertvalue %any undef, ptr %a, 0
|
%18 = insertvalue %any undef, ptr %a, 0
|
||||||
%19 = insertvalue %any %18, i64 ptrtoint (ptr @"$ct.int" to i64), 1
|
%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
|
%25 = load i32, ptr %a, align 4
|
||||||
%add45 = add i32 %25, 1
|
%add45 = add i32 %25, 1
|
||||||
store i32 %add45, ptr %a, align 4
|
store i32 %add45, ptr %a, align 4
|
||||||
%26 = load ptr, ptr %foo, align 8
|
%26 = load i32, ptr %b, align 4
|
||||||
%27 = load i32, ptr %26, align 4
|
%add46 = add i32 %26, 3
|
||||||
%add46 = add i32 %27, 3
|
store i32 %add46, ptr %b, align 4
|
||||||
store i32 %add46, ptr %26, align 4
|
|
||||||
store %"char[]" { ptr @.str.5, i64 3 }, ptr %taddr, align 8
|
store %"char[]" { ptr @.str.5, i64 3 }, ptr %taddr, align 8
|
||||||
%28 = insertvalue %any undef, ptr %taddr, 0
|
%27 = insertvalue %any undef, ptr %taddr, 0
|
||||||
%29 = insertvalue %any %28, i64 ptrtoint (ptr @"$ct.String" to i64), 1
|
%28 = insertvalue %any %27, i64 ptrtoint (ptr @"$ct.String" to i64), 1
|
||||||
store %any %29, ptr %varargslots47, align 16
|
store %any %28, ptr %varargslots47, align 16
|
||||||
%30 = call i64 @std.io.printfn(ptr %retparam48, ptr @.str.4, i64 16, ptr %varargslots47, i64 1)
|
%29 = call i64 @std.io.printfn(ptr %retparam48, ptr @.str.4, i64 16, ptr %varargslots47, i64 1)
|
||||||
%31 = insertvalue %any undef, ptr %b, 0
|
%30 = insertvalue %any undef, ptr %b, 0
|
||||||
%32 = insertvalue %any %31, i64 ptrtoint (ptr @"$ct.int" to i64), 1
|
%31 = insertvalue %any %30, i64 ptrtoint (ptr @"$ct.int" to i64), 1
|
||||||
store %any %32, ptr %varargslots51, align 16
|
store %any %31, ptr %varargslots51, align 16
|
||||||
%33 = call i64 @std.io.printfn(ptr %retparam52, ptr @.str.6, i64 2, ptr %varargslots51, i64 1)
|
%32 = call i64 @std.io.printfn(ptr %retparam52, ptr @.str.6, i64 2, ptr %varargslots51, i64 1)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,7 @@ macro foo(a, $b, $Type) {}
|
|||||||
|
|
||||||
macro @foo2(a, $b, $Type) {}
|
macro @foo2(a, $b, $Type) {}
|
||||||
|
|
||||||
macro bar(&x) // #error: Ref and expression parameters
|
macro baz(#y) {} // #error: are not allowed in function-like
|
||||||
{}
|
|
||||||
|
|
||||||
macro baz(#y) {} // #error: Ref and expression parameters
|
|
||||||
|
|
||||||
macro baz2(a; @body()) {} // #error: Names of macros
|
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;
|
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;
|
#x = foo.x;
|
||||||
@body(foo.mutate(), *x);
|
@body(foo.mutate(), #x);
|
||||||
}
|
}
|
||||||
|
|
||||||
macro @repeat(int times; @body(x))
|
macro @repeat(int times; @body(x))
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ fn int Foo.mutate(Foo *foo)
|
|||||||
return 10 * ++foo.x;
|
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;
|
#x = foo.x;
|
||||||
@body(foo.mutate(), x); // #error: 'int*' to 'int'
|
@body(foo.mutate(), &#x); // #error: 'int*' to 'int'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ fn int main() {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro @foo(&ref) {
|
macro @foo(#ref) {
|
||||||
*ref += 1;
|
#ref += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* #expect: test.ll
|
/* #expect: test.ll
|
||||||
@@ -21,20 +21,34 @@ define i32 @main() #0 {
|
|||||||
entry:
|
entry:
|
||||||
%vec = alloca <4 x i32>, align 16
|
%vec = alloca <4 x i32>, align 16
|
||||||
store <4 x i32> zeroinitializer, ptr %vec, align 16
|
store <4 x i32> zeroinitializer, ptr %vec, align 16
|
||||||
%0 = load i32, ptr %vec, align 4
|
%0 = load <4 x i32>, ptr %vec, align 16
|
||||||
%add = add i32 %0, 1
|
%elem = extractelement <4 x i32> %0, i64 0
|
||||||
store i32 %add, ptr %vec, align 4
|
%add = add i32 %elem, 1
|
||||||
%ptradd = getelementptr inbounds i8, ptr %vec, i64 8
|
%elemset = insertelement <4 x i32> %0, i32 %add, i64 0
|
||||||
%1 = load i32, ptr %ptradd, align 4
|
store <4 x i32> %elemset, ptr %vec, align 16
|
||||||
%add1 = add i32 %1, 1
|
%1 = load <4 x i32>, ptr %vec, align 16
|
||||||
store i32 %add1, ptr %ptradd, align 4
|
%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
|
%2 = load <4 x i32>, ptr %vec, align 16
|
||||||
%3 = extractelement <4 x i32> %2, i64 0
|
%3 = extractelement <4 x i32> %2, i64 0
|
||||||
%eq = icmp eq i32 %3, 1
|
%eq = icmp eq i32 %3, 1
|
||||||
call void @llvm.assume(i1 %eq)
|
call void @llvm.assume(i1 %eq)
|
||||||
%4 = load <4 x i32>, ptr %vec, align 16
|
%4 = load <4 x i32>, ptr %vec, align 16
|
||||||
%5 = extractelement <4 x i32> %4, i64 2
|
%5 = extractelement <4 x i32> %4, i64 2
|
||||||
%eq2 = icmp eq i32 %5, 1
|
%eq4 = icmp eq i32 %5, 1
|
||||||
call void @llvm.assume(i1 %eq2)
|
call void @llvm.assume(i1 %eq4)
|
||||||
ret i32 1
|
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;
|
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); }
|
macro test($Type = int) { io::printn($Type.nameof); }
|
||||||
|
|
||||||
@@ -31,9 +31,9 @@ import std;
|
|||||||
|
|
||||||
int[2] x;
|
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); }
|
macro test($Type = double) { io::printn($Type.nameof); }
|
||||||
|
|
||||||
|
|||||||
@@ -68,4 +68,4 @@ fn usz! TestReader.read(&self, char[] bytes) @dynamic
|
|||||||
return n;
|
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