1030 Commits

Author SHA1 Message Date
Stephen Heumann 84c47841a7 Add headers, tests, and documentation for strfromd/f/l (C23). 2026-04-05 20:27:36 -05:00
Stephen Heumann b46cbc4ae2 Add headers, tests, and documentation for strdup and strndup (C23). 2026-04-05 18:29:05 -05:00
Stephen Heumann c889254d52 Add headers, tests, and documentation for memalignment (C23). 2026-04-05 16:09:49 -05:00
Stephen Heumann 829d87d099 Define char8_t (C23).
We don't yet have the functions that operate on char8_t, but this can still be used in user code (e.g. to indicate what is a UTF-8 string).
2026-04-05 13:29:29 -05:00
Stephen Heumann 629bc3d3a8 Define _PRINTF_NAN_LEN_MAX (C23).
This is the maximum length of the printed representation for a NaN. In our case, it's for something like -NAN(123).

This is a new feature for C23, but since it was a reserved identifier under earlier standards, we just define it unconditionally.
2026-04-05 13:26:38 -05:00
Stephen Heumann 765ecca7e7 Generate better code for 32-bit assignments used as subexpressions.
This improves code for things like a=b=c=123. It also improves the setup code at the beginning of varargs functions.
2026-04-02 20:50:31 -05:00
Stephen Heumann c406011696 Allow varargs functions with no fixed parameters (C23). 2026-04-02 20:11:04 -05:00
Stephen Heumann 2ee05a2ff7 Update tests to avoid using trigraphs in C23 mode.
In C23 mode, C2.1.0.4.CC now tests that the former trigraph sequences are treated as regular characters (not trigraphs) in strings.
2026-04-02 18:04:38 -05:00
Stephen Heumann 99bc1d5534 Avoid defining true and false in <types.h> in C23 modes.
This prevents the macro definitions from overriding the C23 keywords, which would change the types of true and false.
2026-04-01 22:12:30 -05:00
Stephen Heumann d57f0567b3 Small edits to release notes. 2026-04-01 22:00:21 -05:00
Stephen Heumann 844ba0c01f Add tests for recent C23 library updates. 2026-03-31 19:01:04 -05:00
Stephen Heumann 16e8c983d2 Add docs and headers for new and updated <time.h> functions (C23). 2026-03-22 22:08:51 -05:00
Stephen Heumann 56e6029825 Add PRIb*, PRIB*, and SCNb* macros in <inttypes.h> (C23).
These correspond to the new binary conversions for printf and scanf.
2026-03-16 18:30:01 -05:00
Stephen Heumann b6960255ed Document strto* updates. 2026-03-15 21:29:25 -05:00
Stephen Heumann 58307280eb Document new printf/scanf features. 2026-03-15 16:02:59 -05:00
Stephen Heumann 5b0eca5e8a Handle wN/wfN length modifiers in printf/scanf format checker. 2026-03-15 16:00:42 -05:00
Stephen Heumann ca2c558cb6 Handle C23 'b' format for scanf.
As with printf, the format checker expects 'b' to have its traditional ORCA/C behavior in pre-C23 modes, or the C23 standard behavior in C23 modes.

Also as with printf, it can detect when 'b' is being used in the traditional way and automatically change it to 'p'. Specifically, this is done when 'b' is used with no length modifier and the corresponding argument is a pointer to a character type. This behavior is controlled by the same #pragma extensions bit as for printf, and it also only works when the scanf-family function is called directly and has a string literal for the format string.
2026-03-06 22:24:06 -06:00
Stephen Heumann ce41769d8c Add extension to auto-convert printf 'b' format to 'P' for pstrings.
This uses the printf format-checking mechanism to parse the format string and associate conversions in it with arguments. If the argument corresponding to 'b' is a pointer (and no length modifier is used), the 'b' is converted to 'P'. The effect is that most code that used 'b' in the old way will keep working, but code using 'b' with integers will get the new behavior (in C23 mode). Note that this only works if the format string is given by a string literal, and the printf-family function is called directly (not via a function pointer).

This is controlled bit a new #pragma extensions bit (bit 2), which is enabled by default when not in strict mode.
2026-03-05 21:02:28 -06:00
Stephen Heumann cfc95f68ab Adjust printf format checker to support 'B' and C23 version of 'b'.
It adjusts to use either the old or new version of 'b' depending on the language mode.
2026-03-04 19:52:58 -06:00
Stephen Heumann fe5a77addf Reference a label to indicate C23 mode to the library.
When compiling in C23 mode, ORCA/C now generates references to the label ~C23ORLATER, which is defined in the library. The presence of this label in the linked executable can be used by library functions to determine whether they should operate in C23 mode.
2026-03-04 19:47:25 -06:00
Stephen Heumann 3c8788e36c Allow K&R-style parameters without explicit decl in c23compat mode.
This applies to code like the following, which is allowed by C89 but not C99+:

int f(a) { /* code using a, implicitly declared as int */ }

Such code was inadvertently broken in c23compat mode due to changes to handle C23 rules, but it should be allowed in that mode for compatibility with old code. It is still disallowed by strict mode, or by appropriate lint checks.
2026-03-02 19:46:32 -06:00
Stephen Heumann 76433a64cd Remove some nil/garbage pointer dereferences.
These are similar to the ones from the last commit, in that there are earlier checks for the pointer being nil, but the nil dereferences can still occur because short-circuit evaluation is not used. These ones have somewhat more complicated control flow, and also the added aspect that a value read through the nil pointer is itself treated as a pointer and dereferenced. This still doesn't cause problems most of the time, but dereferencing that garbage value may possibly hit a soft switch or IO location. Apart from fixing that potential issue, there should be no functional changes.
2026-03-02 19:37:37 -06:00
Stephen Heumann b35bd91077 Remove several possible nil pointer dereferences.
These were in code like "if (ptr <> nil) and (ptr^.field = XYZ) then ..." or similar. ORCA/Pascal does not use short-circuit evaluation for boolean operators, so the code that would dereference the pointer would get evaluated even if it was nil. In the situations here, this was basically harmless, since the IIGS does not have memory protection and the value read from the nil pointer would not affect the program's behavior. However, it is still cleaner to avoid the nil pointer dereferences.

(Some similar code with more complex control flow is still present.)
2026-03-02 18:30:32 -06:00
Stephen Heumann 12276d456c Implement C23 enum enhancements.
This implements the enhancements to enum types in C23. There are three major elements to these enhancements, which are all implemented here:

-Enumeration constants can have values outside the range of int; enum types using the traditional syntax are automatically assigned an underlying type that is able to hold their constant values (WG14 N3029)
-The underlying type for an enumeration can be explicitly specified using a new syntax (WG14 N3030)
-Enumeration types and their constants can be declared multiple times within the same scope (parts of WG14 N3037)
2026-02-26 22:04:44 -06:00
Stephen Heumann 794ca70beb Prevent casts to void in integer constant expressions.
This gives an error when an expression cast to void is used somewhere that an integer constant expression is required, e.g.:

int main(int argc, char *argv[]) {
        switch (argc) {
                case (void)0: 1;
        }
}
2026-02-24 22:26:19 -06:00
Stephen Heumann ac23d1de4f Comment out code to handle enum types in debug info.
This was dead code, because types with kind=enumType are not used as variable types.
2026-02-24 20:01:35 -06:00
Stephen Heumann df3f364931 Make the type of comma expressions be exactly that of the right operand.
This is what the standards specify. Previously, ORCA/C was applying the usual unary conversions (aka integer promotions), which could change the type.
2026-02-21 22:17:40 -06:00
Stephen Heumann 713aacb70f Comment out code generation for enumConst.
This was dead code, because enumConst tokens get converted to intconst as part of ExpressionTree (in DoOperand).
2026-02-17 20:23:08 -06:00
Stephen Heumann 3003f89ee4 Fix bugs when enum constant names shadow something from an outer scope.
One bug is that the scope of the enum constant only begins at the end of the enumerator, so a definition of the same name from an outer scope should be visible and usable within the expression giving the enum constant value. The other bug is that spurious errors would be reported if the enum constant matched the name of a typedef from an outer scope.
2026-02-13 19:26:57 -06:00
Stephen Heumann bdc081e787 Comment out code for enum-typed expressions, variables, or return types.
In ORCA/C, types with kind = enumType are only used for enum type tags. They do not appear in other places, because an enum type specifier is treated as yielding the type int. Thus, there can never be an expression or variable with an enum type. This has been the case in ORCA/C at least back to 2.1.0 (and likely farther). This is technically not quite standard-conformant, but it makes very little difference in practice, because ORCA/C currently makes all enum types compatible with int.

There was code in some places to handle enum-typed expressions, variables, or function return types, but this is dead code. Most of this code looks reasonable as far as I can tell, but it has not actually been used for a long time (if ever), and it is likely incomplete relative to what would actually be needed to support enum-typed expressions and variables.

This patch comments out that dead code and replaces it with calls to produce an error if those code paths are ever triggered, which effectively act as assertions that they are not used. If ORCA/C was ever changed to use enum types more widely, the code for handling them could be uncommented at that time, but it would need to audited and updated as appropriate.
2026-02-11 17:30:37 -06:00
Stephen Heumann 8a3830645d Implement nullptr and nullptr_t (C23). 2026-02-10 20:38:01 -06:00
Stephen Heumann 583feaf300 Remove an unneeded variable. 2026-02-09 17:55:24 -06:00
Stephen Heumann ca5a93e974 Disallow mistyped expressions for the function in function calls.
Previously, the code would remove any number of "pointer to" and "array of" elements in the type, and accept it if this ultimately yielded a function type. Thus, the expressions denoting the function to be called could be, e.g., a pointer to a function pointer or an array of function pointers. The code generated in these cases would not work properly, but no error was reported.

Now only function pointers or expressions of function type are accepted, as they should be.
2026-02-08 18:17:35 -06:00
Stephen Heumann 9fffb51b96 Allow use of function-typed expressions as boolean values.
This includes conversion to bool, use as the condition for "if", etc.
2026-02-08 18:08:48 -06:00
Stephen Heumann 68786e4ac8 Allow casts from function-typed expressions to pointer or scalar types. 2026-02-07 22:23:05 -06:00
Stephen Heumann e057df4db3 Allow assignment of function-typed expressions to function pointers.
This affects code like function_ptr1 = *function_ptr2. This should be allowed (if the function types are compatible), since the function type is converted to a function pointer type in this context.
2026-02-07 21:53:54 -06:00
Stephen Heumann 42feb8b01e Report an error for ++/-- on expressions of function type.
This affects things like (*function_pointer)++.
2026-02-07 15:48:40 -06:00
Stephen Heumann b0e10d2e80 Allow comparison of expressions of function type with function pointers.
This affects equality comparisons where one side has function type (e.g. *function_pointer) and the other side has function pointer type (pointing to a compatible function type) or is a null pointer constant. These should be permitted, because the function type is converted to a function pointer type in this context. ORCA/C could report a spurious error for such comparisons, because it was not always performing those conversions.

(ORCA/C would treat function names as having function pointer type for these purposes, since for those the type conversion is performed elsewhere.)

Here is an example showing several expressions that gave spurious errors:

void f(void) {}
void (*fp)(void);
int main(void) {
        *fp == f;
        *fp == 0;
        *fp == (void *)0;
}
2026-02-06 23:10:21 -06:00
Stephen Heumann bdb8f3cf2b Allow empty initializers for single-valued types (C23).
An empty initializer {} is now allowed for numeric or pointer types, and is equivalent to {0}. ORCA/C already allowed empty initializers for structs/unions/arrays.
2026-02-03 22:07:30 -06:00
Stephen Heumann b9daf5159c Make bsearch and string search functions into generic functions (C23).
This means that if the parameter giving the array to search is a pointer to a const-qualified type, the return type will be modified so that its pointed-to type is also const-qualified. This functionality is implemented using macros, so the underlying functions still have the same types as before. In addition to the functions specified as generic in C23, this change is also applied to the non-standard strrpbrk function, since it is analogous to strpbrk and has the same issue of potentially discarding const qualifiers.

Note that under ORCA/C's default loose type checking rules, assignments that discard qualifiers are permitted, so these changes have a somewhat limited safety benefit (but also should very rarely require code changes). If using strict type checking, the type rules for assignments will be enforced as per the standard, so assignments that discard qualifiers will produce an error.
2026-02-02 21:27:13 -06:00
Stephen Heumann 3aa96f8a10 Update definition of assert to pass a 32-bit line number.
This requires a new call in ORCALib (__assert3), which is equivalent to the previous __assert2 except for the type of the line number.
2025-11-25 22:20:16 -06:00
Stephen Heumann 719453e2a2 Define assert using ... so that the argument can contain a comma (C23).
This affects cases where the argument expression to assert contains an un-parenthesized comma, which can occur when using compound literals.

When NDEBUG is not defined, this still requires the argument to be something that would count as one argument to a function (i.e. it cannot use an un-parenthesized comma operator). We do this by including an unevaluated call to a fake function using that argument as part of the expansion of the assert macro. (This behavior is specified by a note in the standard, and it's not entirely clear to me that it follows from the normative text, but I've implemented it that way since that's apparently the intent.)
2025-11-25 22:17:46 -06:00
Stephen Heumann d631326efc Add headers, tests, and documentation for free_sized and free_aligned_sized. 2025-11-13 20:46:32 -06:00
Stephen Heumann dcd530c09d Add headers, tests, and documentation for memccpy. 2025-11-12 20:03:29 -06:00
Stephen Heumann 1efbedb362 Add headers, tests, and documentation for memset_explicit. 2025-09-21 17:52:54 -05:00
Stephen Heumann ec1f49d12c Add headers, tests, and documentation for call_once. 2025-09-21 16:29:27 -05:00
Stephen Heumann b29517c7b9 Add BOOL_MAX macro (C23). 2025-09-17 20:54:31 -05:00
Stephen Heumann ee8be78a8b Allow initialization of static/global bool variables from addresses.
This permits code like the following, which the standards seem to allow:

int x;
_Bool b = &x;

(The bool variable is always initialized to one in cases like this. If would be undefined behavior if the address evaluated to 0, so we can assume it doesn't.)
2025-09-06 20:33:05 -05:00
Stephen Heumann be97e598d2 Implement pointer subtraction for pointers to VLA types. 2025-09-03 22:18:20 -05:00
Stephen Heumann 174028dc0e Check that right operand in ptr subtraction points to a complete type.
This check is currently only enabled under strict type checking, since ORCA/C traditionally did not require it but the C11 and later standards do. (The left operand has always been required to point to a complete type, and the two types have been required to be compatible, but the traditional ORCA/C rules could allow the right operand to point to an incomplete array type.)
2025-09-03 22:17:28 -05:00