- add -f[no-]short-wchar
[cparser] / parser.c
index c7dd404..baa943a 100644 (file)
--- a/parser.c
+++ b/parser.c
 #include "adt/error.h"
 #include "adt/array.h"
 
+/** if wchar_t is equal to unsigned short. */
+bool opt_short_wchar_t =
+#ifdef _WIN32
+       true;
+#else
+       false;
+#endif
+
 //#define PRINT_TOKENS
 #define MAX_LOOKAHEAD 2
 
@@ -7001,25 +7009,24 @@ static bool check_pointer_arithmetic(const source_position_t *source_position,
        type_t *points_to = pointer_type->pointer.points_to;
        points_to = skip_typeref(points_to);
 
-       if (is_type_incomplete(points_to) &&
-                       !((c_mode & _GNUC)
-                        && is_type_atomic(points_to, ATOMIC_TYPE_VOID))) {
-               errorf(source_position,
-                      "arithmetic with pointer to incomplete type '%T' not allowed",
-                      orig_pointer_type);
-               return false;
-       } else if (!(c_mode & _GNUC) && is_type_function(points_to)) {
-               errorf(source_position,
-                      "arithmetic with pointer to function type '%T' not allowed",
-                      orig_pointer_type);
-               return false;
-       }
-       if (warning.pointer_arith) {
-               if (is_type_atomic(points_to, ATOMIC_TYPE_VOID)) {
+       if (is_type_incomplete(points_to)) {
+               if (!(c_mode & _GNUC) || !is_type_atomic(points_to, ATOMIC_TYPE_VOID)) {
+                       errorf(source_position,
+                              "arithmetic with pointer to incomplete type '%T' not allowed",
+                              orig_pointer_type);
+                       return false;
+               } else if (warning.pointer_arith) {
                        warningf(source_position,
                                 "pointer of type '%T' used in arithmetic",
                                 orig_pointer_type);
-               } else if (is_type_function(points_to)) {
+               }
+       } else if (is_type_function(points_to)) {
+               if (!(c_mode && _GNUC)) {
+                       errorf(source_position,
+                              "arithmetic with pointer to function type '%T' not allowed",
+                              orig_pointer_type);
+                       return false;
+               } else if (warning.pointer_arith) {
                        warningf(source_position,
                                 "pointer to a function '%T' used in arithmetic",
                                 orig_pointer_type);
@@ -8988,8 +8995,9 @@ static statement_t *parse_empty_statement(void)
        if (warning.empty_statement) {
                warningf(HERE, "statement is empty");
        }
+       statement_t *const statement = create_empty_statement();
        eat(';');
-       return create_empty_statement();
+       return statement;
 }
 
 /**
@@ -9166,7 +9174,7 @@ static void initialize_builtin_types(void)
        type_ptrdiff_t   = make_global_typedef("__PTRDIFF_TYPE__",  type_long);
        type_uintmax_t   = make_global_typedef("__uintmax_t__",     type_unsigned_long_long);
        type_uptrdiff_t  = make_global_typedef("__UPTRDIFF_TYPE__", type_unsigned_long);
-       type_wchar_t     = make_global_typedef("__WCHAR_TYPE__",    type_int);
+       type_wchar_t     = make_global_typedef("__WCHAR_TYPE__",    opt_short_wchar_t ? type_unsigned_short : type_int);
        type_wint_t      = make_global_typedef("__WINT_TYPE__",     type_int);
 
        type_intmax_t_ptr  = make_pointer_type(type_intmax_t,  TYPE_QUALIFIER_NONE);