From ad608238a7a1815a4a058e092e4718623273bf00 Mon Sep 17 00:00:00 2001 From: Evan Haas Date: Wed, 17 Apr 2024 17:35:08 -0700 Subject: [PATCH 1/3] Attribute: check for non-string instead of asserting --- src/aro/Attribute.zig | 3 +-- test/cases/non string attribute.c | 7 +++++++ 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 test/cases/non string attribute.c diff --git a/src/aro/Attribute.zig b/src/aro/Attribute.zig index f3961451..a09bf3b0 100644 --- a/src/aro/Attribute.zig +++ b/src/aro/Attribute.zig @@ -251,8 +251,7 @@ fn diagnoseField( }, .bytes => |bytes| { if (Wanted == Value) { - std.debug.assert(node.tag == .string_literal_expr); - if (!node.ty.elemType().is(.char) and !node.ty.elemType().is(.uchar)) { + if (node.tag != .string_literal_expr or (!node.ty.elemType().is(.char) and !node.ty.elemType().is(.uchar))) { return .{ .tag = .attribute_requires_string, .extra = .{ .str = decl.name }, diff --git a/test/cases/non string attribute.c b/test/cases/non string attribute.c new file mode 100644 index 00000000..20f146c2 --- /dev/null +++ b/test/cases/non string attribute.c @@ -0,0 +1,7 @@ +enum E { + is_deprecated_with_msg __attribute__((deprecated("I am deprecated" = 5 ))), +}; + +#define EXPECTED_ERRORS "non string attribute.c:2:71: error: expression is not assignable" \ + "non string attribute.c:2:53: error: attribute 'deprecated' requires an ordinary string" \ + From 8a9b5317eba370e7047bf587b3d1c48f35a09367 Mon Sep 17 00:00:00 2001 From: Evan Haas Date: Wed, 17 Apr 2024 17:43:39 -0700 Subject: [PATCH 2/3] Preprocessor: error instead of assert if include directive has no tokens --- src/aro/Preprocessor.zig | 9 ++++++++- test/cases/include pragma.c | 4 ++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 test/cases/include pragma.c diff --git a/src/aro/Preprocessor.zig b/src/aro/Preprocessor.zig index 5cac807a..0266051d 100644 --- a/src/aro/Preprocessor.zig +++ b/src/aro/Preprocessor.zig @@ -1356,7 +1356,14 @@ fn stringify(pp: *Preprocessor, tokens: []const TokenWithExpansionLocs) !void { } fn reconstructIncludeString(pp: *Preprocessor, param_toks: []const TokenWithExpansionLocs, embed_args: ?*[]const TokenWithExpansionLocs, first: TokenWithExpansionLocs) !?[]const u8 { - assert(param_toks.len != 0); + if (param_toks.len == 0) { + try pp.comp.addDiagnostic(.{ + .tag = .expected_filename, + .loc = first.loc, + }, first.expansionSlice()); + return null; + } + const char_top = pp.char_buf.items.len; defer pp.char_buf.items.len = char_top; diff --git a/test/cases/include pragma.c b/test/cases/include pragma.c new file mode 100644 index 00000000..80a7098a --- /dev/null +++ b/test/cases/include pragma.c @@ -0,0 +1,4 @@ +#include _Pragma("once") + +#define EXPECTED_ERRORS "include pragma.c:1:10: error: expected \"FILENAME\" or " \ + From b75d695da29f6acf1e4ba1a856bc89bcee0a2146 Mon Sep 17 00:00:00 2001 From: Evan Haas Date: Thu, 18 Apr 2024 16:30:24 -0700 Subject: [PATCH 3/3] Parser: boolCast boolean results even if not evaluated Even if the expression is not evaluated, we need the result to be an integral type Fixes #686 --- src/aro/Parser.zig | 6 ++++++ test/cases/binary expressions.c | 3 +++ 2 files changed, 9 insertions(+) diff --git a/src/aro/Parser.zig b/src/aro/Parser.zig index ef39f075..9a956b0e 100644 --- a/src/aro/Parser.zig +++ b/src/aro/Parser.zig @@ -6447,6 +6447,8 @@ fn landExpr(p: *Parser) Error!Result { if (try lhs.adjustTypes(tok, &rhs, p, .boolean_logic)) { const res = lhs.val.toBool(p.comp) and rhs.val.toBool(p.comp); lhs.val = Value.fromBool(res); + } else { + lhs.val.boolCast(p.comp); } try lhs.boolRes(p, .bool_and_expr, rhs); } @@ -6516,6 +6518,8 @@ fn eqExpr(p: *Parser) Error!Result { const op: std.math.CompareOperator = if (tag == .equal_expr) .eq else .neq; const res = lhs.val.compare(op, rhs.val, p.comp); lhs.val = Value.fromBool(res); + } else { + lhs.val.boolCast(p.comp); } try lhs.boolRes(p, tag, rhs); } @@ -6545,6 +6549,8 @@ fn compExpr(p: *Parser) Error!Result { }; const res = lhs.val.compare(op, rhs.val, p.comp); lhs.val = Value.fromBool(res); + } else { + lhs.val.boolCast(p.comp); } try lhs.boolRes(p, tag, rhs); } diff --git a/test/cases/binary expressions.c b/test/cases/binary expressions.c index c628c61a..2b008d3f 100644 --- a/test/cases/binary expressions.c +++ b/test/cases/binary expressions.c @@ -83,6 +83,9 @@ _Static_assert((-1 ^ 0) == -1, ""); _Static_assert((-1 ^ -1) == 0, ""); _Static_assert((-2 ^ 2) == -4, ""); +_Static_assert(2.0||(2.0 == 2.0), ""); +_Static_assert(2.0||(3.0 > 2.0), ""); +_Static_assert(2.0||(2.0 && 2.0), ""); #define EXPECTED_ERRORS "binary expressions.c:3:7: error: invalid operands to binary expression ('long' and 'float')" \ "binary expressions.c:6:13: error: invalid operands to binary expression ('char' and 'int *')" \